mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
Bug 1899949 - Add the ability to have a custom parse function to derived variants. r=jwatt
Differential Revision: https://phabricator.services.mozilla.com/D212448
This commit is contained in:
parent
6045fc076c
commit
a572c0d70b
@ -178,6 +178,9 @@ impl<'a> ParserContext<'a> {
|
|||||||
/// * `#[parse(condition = "function")]` can be used to make the parsing of the
|
/// * `#[parse(condition = "function")]` can be used to make the parsing of the
|
||||||
/// value conditional on `function`, which needs to fulfill
|
/// value conditional on `function`, which needs to fulfill
|
||||||
/// `fn(&ParserContext) -> bool`.
|
/// `fn(&ParserContext) -> bool`.
|
||||||
|
///
|
||||||
|
/// * `#[parse(parse_fn = "function")]` can be used to specify a function other than Parser::parse
|
||||||
|
/// for a particular variant.
|
||||||
pub trait Parse: Sized {
|
pub trait Parse: Sized {
|
||||||
/// Parse a value of this type.
|
/// Parse a value of this type.
|
||||||
///
|
///
|
||||||
|
@ -14,6 +14,7 @@ use synstructure::{Structure, VariantInfo};
|
|||||||
pub struct ParseVariantAttrs {
|
pub struct ParseVariantAttrs {
|
||||||
pub aliases: Option<String>,
|
pub aliases: Option<String>,
|
||||||
pub condition: Option<Path>,
|
pub condition: Option<Path>,
|
||||||
|
pub parse_fn: Option<Path>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, FromField)]
|
#[derive(Default, FromField)]
|
||||||
@ -109,6 +110,7 @@ fn parse_non_keyword_variant(
|
|||||||
|
|
||||||
if let Some(ref bitflags) = variant_attrs.bitflags {
|
if let Some(ref bitflags) = variant_attrs.bitflags {
|
||||||
assert!(skip_try, "Should be the only variant");
|
assert!(skip_try, "Should be the only variant");
|
||||||
|
assert!(parse_attrs.parse_fn.is_none(), "should not be needed");
|
||||||
assert!(
|
assert!(
|
||||||
parse_attrs.condition.is_none(),
|
parse_attrs.condition.is_none(),
|
||||||
"Should be the only variant"
|
"Should be the only variant"
|
||||||
@ -118,18 +120,25 @@ fn parse_non_keyword_variant(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let field_attrs = cg::parse_field_attrs::<ParseFieldAttrs>(binding_ast);
|
let field_attrs = cg::parse_field_attrs::<ParseFieldAttrs>(binding_ast);
|
||||||
|
|
||||||
if field_attrs.field_bound {
|
if field_attrs.field_bound {
|
||||||
cg::add_predicate(where_clause, parse_quote!(#ty: crate::parser::Parse));
|
cg::add_predicate(where_clause, parse_quote!(#ty: crate::parser::Parse));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut parse = if skip_try {
|
let mut parse = if let Some(ref parse_fn) = parse_attrs.parse_fn {
|
||||||
|
quote! { #parse_fn(context, input) }
|
||||||
|
} else {
|
||||||
|
quote! { <#ty as crate::parser::Parse>::parse(context, input) }
|
||||||
|
};
|
||||||
|
|
||||||
|
parse = if skip_try {
|
||||||
quote! {
|
quote! {
|
||||||
let v = <#ty as crate::parser::Parse>::parse(context, input)?;
|
let v = #parse?;
|
||||||
return Ok(#name::#variant_name(v));
|
return Ok(#name::#variant_name(v));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
quote! {
|
quote! {
|
||||||
if let Ok(v) = input.try(|i| <#ty as crate::parser::Parse>::parse(context, i)) {
|
if let Ok(v) = input.try(|input| #parse) {
|
||||||
return Ok(#name::#variant_name(v));
|
return Ok(#name::#variant_name(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -188,6 +197,8 @@ pub fn derive(mut input: DeriveInput) -> TokenStream {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert!(parse_attrs.parse_fn.is_none());
|
||||||
|
|
||||||
let identifier = cg::to_css_identifier(
|
let identifier = cg::to_css_identifier(
|
||||||
&css_variant_attrs
|
&css_variant_attrs
|
||||||
.keyword
|
.keyword
|
||||||
|
Loading…
Reference in New Issue
Block a user