zyn_core/extract/
fields.rs1use crate::mark;
2use crate::types::Input;
3
4use super::FromInput;
5
6pub trait FromFields: Sized {
11 fn from_fields(fields: syn::Fields) -> crate::Result<Self>;
12}
13
14impl FromFields for syn::Fields {
15 fn from_fields(fields: syn::Fields) -> crate::Result<Self> {
16 Ok(fields)
17 }
18}
19
20impl FromFields for syn::FieldsNamed {
21 fn from_fields(fields: syn::Fields) -> crate::Result<Self> {
22 match fields {
23 syn::Fields::Named(f) => Ok(f),
24 syn::Fields::Unnamed(f) => Err(mark::error("expected named fields")
25 .span(f.paren_token.span.join())
26 .build()),
27 syn::Fields::Unit => Err(mark::error("expected named fields").build()),
28 }
29 }
30}
31
32impl FromFields for syn::FieldsUnnamed {
33 fn from_fields(fields: syn::Fields) -> crate::Result<Self> {
34 match fields {
35 syn::Fields::Unnamed(f) => Ok(f),
36 syn::Fields::Named(f) => Err(mark::error("expected unnamed fields")
37 .span(f.brace_token.span.join())
38 .build()),
39 syn::Fields::Unit => Err(mark::error("expected unnamed fields").build()),
40 }
41 }
42}
43
44pub struct Fields<T: FromFields = syn::Fields>(T);
57
58impl<T: FromFields> Fields<T> {
59 pub fn inner(self) -> T {
61 self.0
62 }
63}
64
65impl<T: FromFields> std::ops::Deref for Fields<T> {
66 type Target = T;
67
68 fn deref(&self) -> &Self::Target {
69 &self.0
70 }
71}
72
73impl<T: FromFields> std::ops::DerefMut for Fields<T> {
74 fn deref_mut(&mut self) -> &mut Self::Target {
75 &mut self.0
76 }
77}
78
79impl<T: FromFields> FromInput for Fields<T> {
80 fn from_input(input: &Input) -> crate::Result<Self> {
81 let raw = match input {
82 Input::Derive(d) => match &d.data {
83 syn::Data::Struct(s) => s.fields.clone(),
84 _ => {
85 return Err(mark::error("expected struct input for Fields extractor")
86 .span(d.ident.span())
87 .build());
88 }
89 },
90 Input::Item(syn::Item::Struct(s)) => s.fields.clone(),
91 _ => {
92 return Err(mark::error("expected struct input for Fields extractor")
93 .span(input.span())
94 .build());
95 }
96 };
97
98 T::from_fields(raw).map(Fields)
99 }
100}