summaryrefslogtreecommitdiffstats
path: root/third_party/rust/weedle2/src/common.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/weedle2/src/common.rs
parentInitial commit. (diff)
downloadfirefox-esr-upstream.tar.xz
firefox-esr-upstream.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
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.rs214
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";
+ });
+}