derivit_core/
parser.rs

1pub struct Parser;
2
3impl Parser {
4  pub fn parse_fields<T: syn::spanned::Spanned>(
5    span: &T,
6    raw: &str,
7  ) -> syn::Result<(bool, syn::Fields)> {
8    let Some(start) = raw.find('{') else {
9            return Err(
10                darling::Error::custom("expected left curly brace")
11                    .with_span(span),
12            )?;
13        };
14    let Some(end) = raw.rfind('}') else {
15            return Err(
16                darling::Error::custom("expected right curly brace")
17                    .with_span(span),
18            )?;
19        };
20    syn::parse_str::<syn::FieldsNamed>(&raw[start..end + 1])
21      .map(|v| (true, syn::Fields::Named(v)))
22      .or_else(|_| {
23        syn::parse_str::<syn::FieldsUnnamed>(&raw[start..end + 1])
24          .map(|v| (false, syn::Fields::Unnamed(v)))
25          .map_err(|_| syn::Error::new(span.span(), "fail to parse extra fields"))
26      })
27  }
28
29  pub fn parse<T>(
30    name: &str,
31    inner: &syn::Meta,
32    target: &mut (bool, Option<T>),
33  ) -> darling::Result<()>
34  where
35    T: darling::FromMeta,
36  {
37    if !target.0 {
38      *target = (
39        true,
40        Some(darling::FromMeta::from_meta(inner).map_err(|e| e.with_span(&inner).at(name))?),
41      );
42      Ok(())
43    } else {
44      Err(darling::Error::duplicate_field(name).with_span(&inner))
45    }
46  }
47}