diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/weedle2/src/common.rs | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/weedle2/src/common.rs')
-rw-r--r-- | third_party/rust/weedle2/src/common.rs | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/third_party/rust/weedle2/src/common.rs b/third_party/rust/weedle2/src/common.rs new file mode 100644 index 0000000000..fadf89ba8b --- /dev/null +++ b/third_party/rust/weedle2/src/common.rs @@ -0,0 +1,214 @@ +use crate::literal::DefaultValue; +use crate::{term, IResult, Parse}; + +pub(crate) fn is_alphanum_underscore_dash(token: char) -> bool { + nom::AsChar::is_alphanum(token) || matches!(token, '_' | '-') +} + +fn marker<S>(i: &str) -> IResult<&str, S> +where + S: ::std::default::Default, +{ + Ok((i, S::default())) +} + +impl<'a, T: Parse<'a>> Parse<'a> for Option<T> { + parser!(nom::combinator::opt(weedle!(T))); +} + +impl<'a, T: Parse<'a>> Parse<'a> for Box<T> { + parser!(nom::combinator::map(weedle!(T), Box::new)); +} + +/// Parses `item1 item2 item3...` +impl<'a, T: Parse<'a>> Parse<'a> for Vec<T> { + parser!(nom::multi::many0(T::parse)); +} + +impl<'a, T: Parse<'a>, U: Parse<'a>> Parse<'a> for (T, U) { + parser!(nom::sequence::tuple((T::parse, U::parse))); +} + +impl<'a, T: Parse<'a>, U: Parse<'a>, V: Parse<'a>> Parse<'a> for (T, U, V) { + parser!(nom::sequence::tuple((T::parse, U::parse, V::parse))); +} + +ast_types! { + /// Parses `( body )` + #[derive(Copy, Default)] + struct Parenthesized<T> where [T: Parse<'a>] { + open_paren: term::OpenParen, + body: T, + close_paren: term::CloseParen, + } + + /// Parses `[ body ]` + #[derive(Copy, Default)] + struct Bracketed<T> where [T: Parse<'a>] { + open_bracket: term::OpenBracket, + body: T, + close_bracket: term::CloseBracket, + } + + /// Parses `{ body }` + #[derive(Copy, Default)] + struct Braced<T> where [T: Parse<'a>] { + open_brace: term::OpenBrace, + body: T, + close_brace: term::CloseBrace, + } + + /// Parses `< body >` + #[derive(Copy, Default)] + struct Generics<T> where [T: Parse<'a>] { + open_angle: term::LessThan, + body: T, + close_angle: term::GreaterThan, + } + + /// Parses `(item1, item2, item3,...)?` + struct Punctuated<T, S> where [T: Parse<'a>, S: Parse<'a> + ::std::default::Default] { + list: Vec<T> = nom::multi::separated_list0(weedle!(S), weedle!(T)), + separator: S = marker, + } + + /// Parses `item1, item2, item3, ...` + struct PunctuatedNonEmpty<T, S> where [T: Parse<'a>, S: Parse<'a> + ::std::default::Default] { + list: Vec<T> = nom::sequence::terminated( + nom::multi::separated_list1(weedle!(S), weedle!(T)), + nom::combinator::opt(weedle!(S)) + ), + separator: S = marker, + } + + /// Represents an identifier + /// + /// Follows `/_?[A-Za-z][0-9A-Z_a-z-]*/` + #[derive(Copy)] + struct Identifier<'a>( + // See https://heycam.github.io/webidl/#idl-names for why the leading + // underscore is trimmed + &'a str = crate::whitespace::ws(nom::sequence::preceded( + nom::combinator::opt(nom::character::complete::char('_')), + nom::combinator::recognize(nom::sequence::tuple(( + nom::bytes::complete::take_while1(nom::AsChar::is_alphanum), + nom::bytes::complete::take_while(is_alphanum_underscore_dash), + ))) + )), + ) + + /// Parses rhs of an assignment expression. Ex: `= 45` + #[derive(Copy)] + struct Default<'a> { + assign: term!(=), + value: DefaultValue<'a>, + } +} + +#[cfg(test)] +mod test { + use super::*; + + test!(should_parse_optional_present { "one" => + ""; + Option<Identifier>; + is_some(); + }); + + test!(should_parse_optional_not_present { "" => + ""; + Option<Identifier>; + is_none(); + }); + + test!(should_parse_boxed { "one" => + ""; + Box<Identifier>; + }); + + test!(should_parse_vec { "one two three" => + ""; + Vec<Identifier>; + len() == 3; + }); + + test!(should_parse_parenthesized { "( one )" => + ""; + Parenthesized<Identifier>; + body.0 == "one"; + }); + + test!(should_parse_bracketed { "[ one ]" => + ""; + Bracketed<Identifier>; + body.0 == "one"; + }); + + test!(should_parse_braced { "{ one }" => + ""; + Braced<Identifier>; + body.0 == "one"; + }); + + test!(should_parse_generics { "<one>" => + ""; + Generics<Identifier>; + body.0 == "one"; + }); + + test!(should_parse_generics_two { "<one, two>" => + ""; + Generics<(Identifier, term!(,), Identifier)> => + Generics { + open_angle: term!(<), + body: (Identifier("one"), term!(,), Identifier("two")), + close_angle: term!(>), + } + }); + + test!(should_parse_comma_separated_values { "one, two, three" => + ""; + Punctuated<Identifier, term!(,)>; + list.len() == 3; + }); + + test!(err should_not_parse_comma_separated_values_empty { "" => + PunctuatedNonEmpty<Identifier, term!(,)> + }); + + test!(should_parse_identifier { "hello" => + ""; + Identifier; + 0 == "hello"; + }); + + test!(should_parse_numbered_identifier { "hello5" => + ""; + Identifier; + 0 == "hello5"; + }); + + test!(should_parse_underscored_identifier { "_hello_" => + ""; + Identifier; + 0 == "hello_"; + }); + + test!(should_parse_identifier_surrounding_with_spaces { " hello " => + ""; + Identifier; + 0 == "hello"; + }); + + test!(should_parse_identifier_preceding_others { "hello note" => + "note"; + Identifier; + 0 == "hello"; + }); + + test!(should_parse_identifier_attached_to_symbol { "hello=" => + "="; + Identifier; + 0 == "hello"; + }); +} |