mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-11-22 19:41:00 +00:00
closedcaption: Port to combine 4
This commit is contained in:
parent
660e325bbc
commit
8370fb8a11
5 changed files with 135 additions and 120 deletions
|
@ -9,7 +9,7 @@ repository = "https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs"
|
|||
|
||||
[dependencies]
|
||||
glib = { git = "https://github.com/gtk-rs/glib" }
|
||||
combine = "3.6"
|
||||
combine = "4.0"
|
||||
either = "1"
|
||||
uuid = { version = "0.8", features = ["v4"] }
|
||||
chrono = "0.4"
|
||||
|
|
|
@ -94,7 +94,7 @@ struct State {
|
|||
need_flush_stop: bool,
|
||||
}
|
||||
|
||||
type CombineError<'a> = combine::easy::Errors<u8, &'a [u8], combine::stream::PointerOffset>;
|
||||
type CombineError<'a> = combine::easy::ParseError<&'a [u8]>;
|
||||
|
||||
impl Default for State {
|
||||
fn default() -> Self {
|
||||
|
|
|
@ -21,6 +21,7 @@ use combine;
|
|||
use combine::parser::byte::hex_digit;
|
||||
use combine::parser::range::{range, take_while1};
|
||||
use combine::parser::repeat::skip_many;
|
||||
use combine::parser::EasyParser;
|
||||
use combine::{any, choice, eof, from_str, many1, one_of, optional, token, unexpected_any, value};
|
||||
use combine::{ParseError, Parser, RangeStream};
|
||||
|
||||
|
@ -59,22 +60,20 @@ pub struct MccParser {
|
|||
}
|
||||
|
||||
/// Parser for parsing a run of ASCII, decimal digits and converting them into a `u32`
|
||||
fn digits<'a, I: 'a>() -> impl Parser<Input = I, Output = u32>
|
||||
fn digits<'a, I: 'a>() -> impl Parser<I, Output = u32>
|
||||
where
|
||||
I: RangeStream<Item = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>,
|
||||
I: RangeStream<Token = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Token, I::Range, I::Position>,
|
||||
{
|
||||
from_str(take_while1(|c: u8| c >= b'0' && c <= b'9').message("while parsing digits"))
|
||||
}
|
||||
|
||||
/// Parser for a run of decimal digits, that converts them into a `u32` and checks if the result is
|
||||
/// in the allowed range.
|
||||
fn digits_range<'a, I: 'a, R: std::ops::RangeBounds<u32>>(
|
||||
range: R,
|
||||
) -> impl Parser<Input = I, Output = u32>
|
||||
fn digits_range<'a, I: 'a, R: std::ops::RangeBounds<u32>>(range: R) -> impl Parser<I, Output = u32>
|
||||
where
|
||||
I: RangeStream<Item = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>,
|
||||
I: RangeStream<Token = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Token, I::Range, I::Position>,
|
||||
{
|
||||
digits().then(move |v| {
|
||||
if range.contains(&v) {
|
||||
|
@ -86,10 +85,10 @@ where
|
|||
}
|
||||
|
||||
/// Parser for a timecode in the form `hh:mm:ss:fs`
|
||||
fn timecode<'a, I: 'a>() -> impl Parser<Input = I, Output = TimeCode>
|
||||
fn timecode<'a, I: 'a>() -> impl Parser<I, Output = TimeCode>
|
||||
where
|
||||
I: RangeStream<Item = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>,
|
||||
I: RangeStream<Token = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Token, I::Range, I::Position>,
|
||||
{
|
||||
(
|
||||
digits(),
|
||||
|
@ -111,10 +110,10 @@ where
|
|||
}
|
||||
|
||||
/// Parser that checks for EOF and optionally `\n` or `\r\n` before EOF
|
||||
fn end_of_line<'a, I: 'a>() -> impl Parser<Input = I, Output = ()> + 'a
|
||||
fn end_of_line<'a, I: 'a>() -> impl Parser<I, Output = ()> + 'a
|
||||
where
|
||||
I: RangeStream<Item = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>,
|
||||
I: RangeStream<Token = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Token, I::Range, I::Position>,
|
||||
{
|
||||
(
|
||||
optional(choice((range(b"\n".as_ref()), range(b"\r\n".as_ref())))),
|
||||
|
@ -125,10 +124,10 @@ where
|
|||
}
|
||||
|
||||
/// Parser for the MCC header
|
||||
fn header<'a, I: 'a>() -> impl Parser<Input = I, Output = MccLine<'a>>
|
||||
fn header<'a, I: 'a>() -> impl Parser<I, Output = MccLine<'a>>
|
||||
where
|
||||
I: RangeStream<Item = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>,
|
||||
I: RangeStream<Token = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Token, I::Range, I::Position>,
|
||||
{
|
||||
(
|
||||
range(b"File Format=MacCaption_MCC V".as_ref()),
|
||||
|
@ -140,10 +139,10 @@ where
|
|||
}
|
||||
|
||||
/// Parser that accepts only an empty line
|
||||
fn empty_line<'a, I: 'a>() -> impl Parser<Input = I, Output = MccLine<'a>>
|
||||
fn empty_line<'a, I: 'a>() -> impl Parser<I, Output = MccLine<'a>>
|
||||
where
|
||||
I: RangeStream<Item = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>,
|
||||
I: RangeStream<Token = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Token, I::Range, I::Position>,
|
||||
{
|
||||
end_of_line()
|
||||
.map(|_| MccLine::Empty)
|
||||
|
@ -152,10 +151,10 @@ where
|
|||
|
||||
/// Parser for an MCC comment, i.e. a line starting with `//`. We don't return the actual comment
|
||||
/// text as it's irrelevant for us.
|
||||
fn comment<'a, I: 'a>() -> impl Parser<Input = I, Output = MccLine<'a>>
|
||||
fn comment<'a, I: 'a>() -> impl Parser<I, Output = MccLine<'a>>
|
||||
where
|
||||
I: RangeStream<Item = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>,
|
||||
I: RangeStream<Token = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Token, I::Range, I::Position>,
|
||||
{
|
||||
(token(b'/'), token(b'/'), skip_many(any()))
|
||||
.map(|_| MccLine::Comment)
|
||||
|
@ -163,10 +162,10 @@ where
|
|||
}
|
||||
|
||||
/// Parser for the MCC UUID line.
|
||||
fn uuid<'a, I: 'a>() -> impl Parser<Input = I, Output = MccLine<'a>>
|
||||
fn uuid<'a, I: 'a>() -> impl Parser<I, Output = MccLine<'a>>
|
||||
where
|
||||
I: RangeStream<Item = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>,
|
||||
I: RangeStream<Token = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Token, I::Range, I::Position>,
|
||||
{
|
||||
(
|
||||
range(b"UUID=".as_ref()),
|
||||
|
@ -178,10 +177,10 @@ where
|
|||
}
|
||||
|
||||
/// Parser for the MCC Time Code Rate line.
|
||||
fn time_code_rate<'a, I: 'a>() -> impl Parser<Input = I, Output = MccLine<'a>>
|
||||
fn time_code_rate<'a, I: 'a>() -> impl Parser<I, Output = MccLine<'a>>
|
||||
where
|
||||
I: RangeStream<Item = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>,
|
||||
I: RangeStream<Token = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Token, I::Range, I::Position>,
|
||||
{
|
||||
(
|
||||
range(b"Time Code Rate=".as_ref()),
|
||||
|
@ -195,10 +194,10 @@ where
|
|||
}
|
||||
|
||||
/// Parser for generic MCC metadata lines in the form `key=value`.
|
||||
fn metadata<'a, I: 'a>() -> impl Parser<Input = I, Output = MccLine<'a>>
|
||||
fn metadata<'a, I: 'a>() -> impl Parser<I, Output = MccLine<'a>>
|
||||
where
|
||||
I: RangeStream<Item = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>,
|
||||
I: RangeStream<Token = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Token, I::Range, I::Position>,
|
||||
{
|
||||
(
|
||||
take_while1(|b| b != b'='),
|
||||
|
@ -215,55 +214,73 @@ where
|
|||
///
|
||||
/// It returns an `Either` of the single hex encoded byte or the short-cut byte sequence as a
|
||||
/// static byte slice.
|
||||
fn mcc_payload_item<'a, I: 'a>() -> impl Parser<Input = I, Output = Either<u8, &'static [u8]>>
|
||||
fn mcc_payload_item<'a, I: 'a>() -> impl Parser<I, Output = Either<u8, &'static [u8]>>
|
||||
where
|
||||
I: RangeStream<Item = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>,
|
||||
I: RangeStream<Token = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Token, I::Range, I::Position>,
|
||||
{
|
||||
choice!(
|
||||
// FIXME: Switch back to the choice! macro once https://github.com/rust-lang/rust/issues/68666
|
||||
// is fixed and we depend on a new enough Rust version.
|
||||
choice((
|
||||
token(b'G').map(|_| Either::Right([0xfau8, 0x00, 0x00].as_ref())),
|
||||
token(b'H').map(|_| Either::Right([0xfau8, 0x00, 0x00, 0xfa, 0x00, 0x00].as_ref())),
|
||||
token(b'I').map(|_| Either::Right(
|
||||
[0xfau8, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00].as_ref()
|
||||
)),
|
||||
token(b'J').map(|_| Either::Right(
|
||||
[0xfau8, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00].as_ref()
|
||||
)),
|
||||
token(b'K').map(|_| Either::Right(
|
||||
[
|
||||
0xfau8, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
|
||||
0x00, 0x00
|
||||
]
|
||||
.as_ref()
|
||||
)),
|
||||
token(b'L').map(|_| Either::Right(
|
||||
[
|
||||
0xfau8, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
|
||||
0x00, 0x00, 0xfa, 0x00, 0x00
|
||||
]
|
||||
.as_ref()
|
||||
)),
|
||||
token(b'M').map(|_| Either::Right(
|
||||
[
|
||||
0xfau8, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
|
||||
0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00
|
||||
]
|
||||
.as_ref()
|
||||
)),
|
||||
token(b'N').map(|_| Either::Right(
|
||||
[
|
||||
0xfau8, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
|
||||
0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00
|
||||
]
|
||||
.as_ref()
|
||||
)),
|
||||
token(b'O').map(|_| Either::Right(
|
||||
[
|
||||
0xfau8, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
|
||||
0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00
|
||||
]
|
||||
.as_ref()
|
||||
)),
|
||||
token(b'I').map(|_| {
|
||||
Either::Right([0xfau8, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00].as_ref())
|
||||
}),
|
||||
token(b'J').map(|_| {
|
||||
Either::Right(
|
||||
[
|
||||
0xfau8, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
|
||||
]
|
||||
.as_ref(),
|
||||
)
|
||||
}),
|
||||
token(b'K').map(|_| {
|
||||
Either::Right(
|
||||
[
|
||||
0xfau8, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
|
||||
0x00, 0x00,
|
||||
]
|
||||
.as_ref(),
|
||||
)
|
||||
}),
|
||||
token(b'L').map(|_| {
|
||||
Either::Right(
|
||||
[
|
||||
0xfau8, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
|
||||
0x00, 0x00, 0xfa, 0x00, 0x00,
|
||||
]
|
||||
.as_ref(),
|
||||
)
|
||||
}),
|
||||
token(b'M').map(|_| {
|
||||
Either::Right(
|
||||
[
|
||||
0xfau8, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
|
||||
0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
|
||||
]
|
||||
.as_ref(),
|
||||
)
|
||||
}),
|
||||
token(b'N').map(|_| {
|
||||
Either::Right(
|
||||
[
|
||||
0xfau8, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
|
||||
0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00,
|
||||
]
|
||||
.as_ref(),
|
||||
)
|
||||
}),
|
||||
token(b'O').map(|_| {
|
||||
Either::Right(
|
||||
[
|
||||
0xfau8, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa,
|
||||
0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00, 0x00, 0xfa, 0x00,
|
||||
0x00,
|
||||
]
|
||||
.as_ref(),
|
||||
)
|
||||
}),
|
||||
token(b'P').map(|_| Either::Right([0xfbu8, 0x80, 0x80].as_ref())),
|
||||
token(b'Q').map(|_| Either::Right([0xfcu8, 0x80, 0x80].as_ref())),
|
||||
token(b'R').map(|_| Either::Right([0xfdu8, 0x80, 0x80].as_ref())),
|
||||
|
@ -280,8 +297,8 @@ where
|
|||
};
|
||||
let val = (hex_to_u8(u) << 4) | hex_to_u8(l);
|
||||
Either::Left(val)
|
||||
})
|
||||
)
|
||||
}),
|
||||
))
|
||||
.message("while parsing MCC payload")
|
||||
}
|
||||
|
||||
|
@ -311,10 +328,10 @@ impl<'a> Extend<Either<u8, &'a [u8]>> for VecExtend {
|
|||
}
|
||||
|
||||
/// Parser for the whole MCC payload with conversion to the underlying byte values.
|
||||
fn mcc_payload<'a, I: 'a>() -> impl Parser<Input = I, Output = Vec<u8>>
|
||||
fn mcc_payload<'a, I: 'a>() -> impl Parser<I, Output = Vec<u8>>
|
||||
where
|
||||
I: RangeStream<Item = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>,
|
||||
I: RangeStream<Token = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Token, I::Range, I::Position>,
|
||||
{
|
||||
many1(mcc_payload_item())
|
||||
.map(|v: VecExtend| v.0)
|
||||
|
@ -322,10 +339,10 @@ where
|
|||
}
|
||||
|
||||
/// Parser for a MCC caption line in the form `timecode\tpayload`.
|
||||
fn caption<'a, I: 'a>(parse_payload: bool) -> impl Parser<Input = I, Output = MccLine<'a>>
|
||||
fn caption<'a, I: 'a>(parse_payload: bool) -> impl Parser<I, Output = MccLine<'a>>
|
||||
where
|
||||
I: RangeStream<Item = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>,
|
||||
I: RangeStream<Token = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Token, I::Range, I::Position>,
|
||||
{
|
||||
(
|
||||
timecode(),
|
||||
|
@ -368,8 +385,7 @@ impl MccParser {
|
|||
&mut self,
|
||||
line: &'a [u8],
|
||||
parse_payload: bool,
|
||||
) -> Result<MccLine<'a>, combine::easy::Errors<u8, &'a [u8], combine::stream::PointerOffset>>
|
||||
{
|
||||
) -> Result<MccLine<'a>, combine::easy::ParseError<&'a [u8]>> {
|
||||
match self.state {
|
||||
State::Header => header()
|
||||
.message("while in Header state")
|
||||
|
|
|
@ -51,7 +51,7 @@ struct State {
|
|||
last_timecode: Option<gst_video::ValidVideoTimeCode>,
|
||||
}
|
||||
|
||||
type CombineError<'a> = combine::easy::Errors<u8, &'a [u8], combine::stream::PointerOffset>;
|
||||
type CombineError<'a> = combine::easy::ParseError<&'a [u8]>;
|
||||
|
||||
impl Default for State {
|
||||
fn default() -> Self {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
use combine;
|
||||
use combine::parser::byte::hex_digit;
|
||||
use combine::parser::range::{range, take_while1};
|
||||
use combine::parser::EasyParser;
|
||||
use combine::{choice, eof, from_str, many1, one_of, optional, token, unexpected_any, value};
|
||||
use combine::{ParseError, Parser, RangeStream};
|
||||
|
||||
|
@ -51,22 +52,20 @@ pub struct SccParser {
|
|||
}
|
||||
|
||||
/// Parser for parsing a run of ASCII, decimal digits and converting them into a `u32`
|
||||
fn digits<'a, I: 'a>() -> impl Parser<Input = I, Output = u32>
|
||||
fn digits<'a, I: 'a>() -> impl Parser<I, Output = u32>
|
||||
where
|
||||
I: RangeStream<Item = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>,
|
||||
I: RangeStream<Token = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Token, I::Range, I::Position>,
|
||||
{
|
||||
from_str(take_while1(|c: u8| c >= b'0' && c <= b'9').message("while parsing digits"))
|
||||
}
|
||||
|
||||
/// Parser for a run of decimal digits, that converts them into a `u32` and checks if the result is
|
||||
/// in the allowed range.
|
||||
fn digits_range<'a, I: 'a, R: std::ops::RangeBounds<u32>>(
|
||||
range: R,
|
||||
) -> impl Parser<Input = I, Output = u32>
|
||||
fn digits_range<'a, I: 'a, R: std::ops::RangeBounds<u32>>(range: R) -> impl Parser<I, Output = u32>
|
||||
where
|
||||
I: RangeStream<Item = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>,
|
||||
I: RangeStream<Token = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Token, I::Range, I::Position>,
|
||||
{
|
||||
digits().then(move |v| {
|
||||
if range.contains(&v) {
|
||||
|
@ -78,10 +77,10 @@ where
|
|||
}
|
||||
|
||||
/// Parser for a timecode in the form `hh:mm:ss:fs`
|
||||
fn timecode<'a, I: 'a>() -> impl Parser<Input = I, Output = TimeCode>
|
||||
fn timecode<'a, I: 'a>() -> impl Parser<I, Output = TimeCode>
|
||||
where
|
||||
I: RangeStream<Item = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>,
|
||||
I: RangeStream<Token = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Token, I::Range, I::Position>,
|
||||
{
|
||||
(
|
||||
digits(),
|
||||
|
@ -103,10 +102,10 @@ where
|
|||
}
|
||||
|
||||
/// Parser that checks for EOF and optionally `\n` or `\r\n` before EOF
|
||||
fn end_of_line<'a, I: 'a>() -> impl Parser<Input = I, Output = ()> + 'a
|
||||
fn end_of_line<'a, I: 'a>() -> impl Parser<I, Output = ()> + 'a
|
||||
where
|
||||
I: RangeStream<Item = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>,
|
||||
I: RangeStream<Token = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Token, I::Range, I::Position>,
|
||||
{
|
||||
(
|
||||
optional(choice((range(b"\n".as_ref()), range(b"\r\n".as_ref())))),
|
||||
|
@ -117,10 +116,10 @@ where
|
|||
}
|
||||
|
||||
/// Parser for the SCC header
|
||||
fn header<'a, I: 'a>() -> impl Parser<Input = I, Output = SccLine> + 'a
|
||||
fn header<'a, I: 'a>() -> impl Parser<I, Output = SccLine> + 'a
|
||||
where
|
||||
I: RangeStream<Item = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>,
|
||||
I: RangeStream<Token = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Token, I::Range, I::Position>,
|
||||
{
|
||||
(range(b"Scenarist_SCC V1.0".as_ref()), end_of_line())
|
||||
.map(|_| SccLine::Header)
|
||||
|
@ -128,10 +127,10 @@ where
|
|||
}
|
||||
|
||||
/// Parser that accepts only an empty line
|
||||
fn empty_line<'a, I: 'a>() -> impl Parser<Input = I, Output = SccLine> + 'a
|
||||
fn empty_line<'a, I: 'a>() -> impl Parser<I, Output = SccLine> + 'a
|
||||
where
|
||||
I: RangeStream<Item = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>,
|
||||
I: RangeStream<Token = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Token, I::Range, I::Position>,
|
||||
{
|
||||
end_of_line()
|
||||
.map(|_| SccLine::Empty)
|
||||
|
@ -140,10 +139,10 @@ where
|
|||
|
||||
/// A single SCC payload item. This is ASCII hex encoded bytes.
|
||||
/// It returns an tuple of `(u8, u8)` of the hex encoded bytes.
|
||||
fn scc_payload_item<'a, I: 'a>() -> impl Parser<Input = I, Output = (u8, u8)>
|
||||
fn scc_payload_item<'a, I: 'a>() -> impl Parser<I, Output = (u8, u8)>
|
||||
where
|
||||
I: RangeStream<Item = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>,
|
||||
I: RangeStream<Token = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Token, I::Range, I::Position>,
|
||||
{
|
||||
((hex_digit(), hex_digit(), hex_digit(), hex_digit()).map(|(u, l, m, n)| {
|
||||
let hex_to_u8 = |v: u8| match v {
|
||||
|
@ -182,10 +181,10 @@ impl Extend<(u8, u8)> for VecExtend {
|
|||
}
|
||||
|
||||
/// Parser for the whole SCC payload with conversion to the underlying byte values.
|
||||
fn scc_payload<'a, I: 'a>() -> impl Parser<Input = I, Output = Vec<u8>> + 'a
|
||||
fn scc_payload<'a, I: 'a>() -> impl Parser<I, Output = Vec<u8>> + 'a
|
||||
where
|
||||
I: RangeStream<Item = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>,
|
||||
I: RangeStream<Token = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Token, I::Range, I::Position>,
|
||||
{
|
||||
many1(
|
||||
(
|
||||
|
@ -199,10 +198,10 @@ where
|
|||
}
|
||||
|
||||
/// Parser for a SCC caption line in the form `timecode\tpayload`.
|
||||
fn caption<'a, I: 'a>() -> impl Parser<Input = I, Output = SccLine> + 'a
|
||||
fn caption<'a, I: 'a>() -> impl Parser<I, Output = SccLine> + 'a
|
||||
where
|
||||
I: RangeStream<Item = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Item, I::Range, I::Position>,
|
||||
I: RangeStream<Token = u8, Range = &'a [u8]>,
|
||||
I::Error: ParseError<I::Token, I::Range, I::Position>,
|
||||
{
|
||||
(timecode(), token(b'\t'), scc_payload(), end_of_line())
|
||||
.map(|(tc, _, value, _)| SccLine::Caption(tc, value))
|
||||
|
@ -224,7 +223,7 @@ impl SccParser {
|
|||
pub fn parse_line<'a>(
|
||||
&mut self,
|
||||
line: &'a [u8],
|
||||
) -> Result<SccLine, combine::easy::Errors<u8, &'a [u8], combine::stream::PointerOffset>> {
|
||||
) -> Result<SccLine, combine::easy::ParseError<&'a [u8]>> {
|
||||
match self.state {
|
||||
State::Header => header()
|
||||
.message("while in Header state")
|
||||
|
|
Loading…
Reference in a new issue