//! Types for "shape" validation. This allows types deriving `FromDeriveInput` etc. to declare //! that they only work on - for example - structs with named fields, or newtype enum variants.
use proc_macro2::TokenStream; use quote::{quote, ToTokens, TokenStreamExt}; use syn::{parse_quote, Meta};
/// Receiver struct for shape validation. Shape validation allows a deriving type /// to declare that it only accepts - for example - named structs, or newtype enum /// variants. /// /// ```rust,ignore /// #[ignore(any, struct_named, enum_newtype)] /// ``` #[derive(Debug, Clone)] pubstruct DeriveInputShapeSet {
enum_values: DataShape,
struct_values: DataShape,
any: bool,
}
impl FromMeta for DeriveInputShapeSet { fn from_list(items: &[NestedMeta]) -> Result<Self> { letmut new = DeriveInputShapeSet::default(); for item in items { iflet NestedMeta::Meta(Meta::Path(ref path)) = *item { let ident = &path.segments.first().unwrap().ident; let word = ident.to_string(); if word == "any" {
new.any = true;
} elseif word.starts_with("enum_") {
new.enum_values
.set_word(&word)
.map_err(|e| e.with_span(&ident))?;
} elseif word.starts_with("struct_") {
new.struct_values
.set_word(&word)
.map_err(|e| e.with_span(&ident))?;
} else { return Err(Error::unknown_value(&word).with_span(&ident));
}
} else { return Err(Error::unsupported_format("non-word").with_span(item));
}
}
Ok(new)
}
}
impl ToTokens for DeriveInputShapeSet { fn to_tokens(&self, tokens: &mut TokenStream) { let fn_body = ifself.any {
quote!(::darling::export::Ok(()))
} else { let en = &self.enum_values; let st = &self.struct_values;
quote! {
{ let struct_check = #st; let enum_check = #en;
match *__body {
::darling::export::syn::Data::Enum(ref data) => { if enum_check.is_empty() { return ::darling::export::Err(
::darling::Error::unsupported_shape_with_expected("enum", &format!(>"struct with {}", struct_check))
);
}
letmut variant_errors = ::darling::Error::accumulator(); for variant in &data.variants {
variant_errors.handle(enum_check.check(variant));
}
variant_errors.finish()
}
::darling::export::syn::Data::Struct(ref struct_data) => { if struct_check.is_empty() { return ::darling::export::Err(
::darling::Error::unsupported_shape_with_expected("struct", &format!("enum with {}", enum_check))
);
}
/// Receiver for shape information within a struct or enum context. See `Shape` for more information /// on valid uses of shape validation. #[derive(Debug, Clone, Default, PartialEq, Eq)] pubstruct DataShape { /// The kind of shape being described. This can be `struct_` or `enum_`.
prefix: &'static str,
newtype: bool,
named: bool,
tuple: bool,
unit: bool,
any: bool,
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.