1pub mod invoke;
2pub mod marshal;
3
4use marshal::MarshalAttr;
5
6#[derive(Debug)]
7pub struct Mapping {
8 pub output_type: syn::Type,
9 pub marshaler: Option<MarshalAttr>,
10}
11
12impl Mapping {
13 pub fn self_type(receiver: &syn::Receiver, parent: &syn::Type) -> Result<Mapping, syn::Error> {
14 let syn::Receiver {
15 reference,
16 mutability,
17 ..
18 } = receiver.clone();
19
20 let path = match parent {
21 syn::Type::Path(path) => path,
22 e => return Err(syn::Error::new_spanned(&e, "not a valid self type path")),
23 };
24
25 let output_type = match (reference, mutability) {
26 (None, _) => syn::Type::Path(path.clone()),
27 (Some((and_token, lifetime)), mutability) => syn::Type::Reference(syn::TypeReference {
28 and_token,
29 lifetime,
30 mutability,
31 elem: Box::new(syn::Type::Path(path.clone())),
32 }),
33 };
34
35 Ok(Mapping {
36 output_type,
37 marshaler: MarshalAttr::self_type(),
38 })
39 }
40}
41
42pub(crate) trait AttrExt {
43 fn drain_marshal_attrs(&mut self) -> Result<Option<MarshalAttr>, syn::Error>;
44}
45
46#[inline]
47fn drain_marshal_attrs(attrs: &mut Vec<syn::Attribute>) -> Result<Option<MarshalAttr>, syn::Error> {
48 let mut unhandled_attrs = vec![];
49 std::mem::swap(attrs, &mut unhandled_attrs);
50
51 let idents = unhandled_attrs
52 .into_iter()
53 .filter_map(|item| match MarshalAttr::from_attribute(item.clone()) {
54 Ok(None) => {
55 attrs.push(item);
56 return None;
57 }
58 Ok(Some(v)) => Some(Ok(v)),
59 Err(e) => return Some(Err(e)),
60 })
61 .collect::<Result<Vec<_>, _>>();
62
63 let mut idents = match idents {
64 Ok(v) => v,
65 Err(e) => return Err(e),
66 };
67
68 Ok(idents.pop())
69}
70
71impl AttrExt for syn::PatType {
72 fn drain_marshal_attrs(&mut self) -> Result<Option<MarshalAttr>, syn::Error> {
73 drain_marshal_attrs(&mut self.attrs)
74 }
75}
76
77impl AttrExt for syn::FnArg {
78 fn drain_marshal_attrs(&mut self) -> Result<Option<MarshalAttr>, syn::Error> {
79 match self {
80 syn::FnArg::Receiver(receiver) => drain_marshal_attrs(&mut receiver.attrs),
81 syn::FnArg::Typed(typed) => drain_marshal_attrs(&mut typed.attrs),
82 }
83 }
84}
85
86pub(crate) trait SignatureExt {
87 fn drain_mappings(
88 &mut self,
89 parent_type: Option<&syn::Type>,
90 ) -> Result<Vec<Mapping>, syn::Error>;
91}
92
93impl SignatureExt for syn::Signature {
94 fn drain_mappings(
95 &mut self,
96 parent_type: Option<&syn::Type>,
97 ) -> Result<Vec<Mapping>, syn::Error> {
98 self.inputs
99 .iter_mut()
100 .filter_map(|mut input| {
101 let input = match &mut input {
104 syn::FnArg::Receiver(receiver) => {
105 if let Some(parent_type) = parent_type {
106 return Some(Mapping::self_type(receiver, parent_type));
107 } else {
108 return Some(Err(syn::Error::new_spanned(
109 &receiver,
110 "no self type found; using invoke wrong?",
111 )));
112 }
113 }
114 syn::FnArg::Typed(t) => t,
115 };
116
117 let marshaler = match input.drain_marshal_attrs() {
118 Ok(v) => v.or_else(|| MarshalAttr::from_defaults_by_type(&input.ty)),
119 Err(e) => return Some(Err(e)),
120 };
121
122 Some(Ok(Mapping {
123 output_type: *input.ty.clone(),
124 marshaler,
125 }))
126 })
127 .collect::<Result<Vec<_>, _>>()
128 }
129}