intercom_common/
ast_converters.rs1use crate::prelude::*;
2use syn::{Attribute, FnArg, GenericArgument, Ident, Item, Pat, Path, Type};
3
4pub trait GetType
6{
7 fn get_ty(&self) -> Result<Type, String>;
9}
10
11impl GetType for FnArg
12{
13 fn get_ty(&self) -> Result<Type, String>
14 {
15 Ok(match *self {
16 FnArg::Receiver(_) => self_ty(),
17 FnArg::Typed(ref pat_type) => pat_type.ty.as_ref().to_owned(),
18 })
19 }
20}
21
22impl GetType for GenericArgument
23{
24 fn get_ty(&self) -> Result<Type, String>
25 {
26 match *self {
27 GenericArgument::Type(ref ty) => Ok(ty.clone()),
28 _ => Err("Expected type parameter".to_string()),
29 }
30 }
31}
32
33pub trait GetIdent
34{
35 fn get_ident(&self) -> Result<Ident, String>;
37}
38
39impl GetIdent for FnArg
40{
41 fn get_ident(&self) -> Result<Ident, String>
42 {
43 Ok(match *self {
44 FnArg::Receiver(_) => Ident::new("self", Span::call_site()),
45 FnArg::Typed(ref pat_type) => match *pat_type.pat {
46 Pat::Ident(ref pat_ident) => pat_ident.ident.clone(),
47 _ => return Err(format!("Unsupported argument: {:?}", self)),
48 },
49 })
50 }
51}
52
53impl GetIdent for Path
54{
55 fn get_ident(&self) -> Result<Ident, String>
56 {
57 self.segments
58 .last()
59 .map(|l| l.ident.clone())
60 .ok_or_else(|| "Empty path".to_owned())
61 }
62}
63
64impl GetIdent for Type
65{
66 fn get_ident(&self) -> Result<Ident, String>
67 {
68 match *self {
69 Type::Path(ref p) => p
70 .path
71 .get_ident()
72 .cloned()
73 .ok_or_else(|| format!("No Ident for {:?}", self)),
74 _ => Err(format!("Cannot get Ident for {:?}", self)),
75 }
76 }
77}
78
79impl GetIdent for Item
80{
81 fn get_ident(&self) -> Result<Ident, String>
82 {
83 Ok(match *self {
84 Item::ExternCrate(ref i) => i.ident.clone(),
85 Item::Static(ref i) => i.ident.clone(),
86 Item::Const(ref i) => i.ident.clone(),
87 Item::Fn(ref i) => i.sig.ident.clone(),
88 Item::Mod(ref i) => i.ident.clone(),
89 Item::Type(ref i) => i.ident.clone(),
90 Item::Struct(ref i) => i.ident.clone(),
91 Item::Enum(ref i) => i.ident.clone(),
92 Item::Union(ref i) => i.ident.clone(),
93 Item::Trait(ref i) => i.ident.clone(),
94 Item::Impl(ref i) => i.self_ty.get_ident()?,
95 Item::Macro(ref m) => m
96 .mac
97 .path
98 .get_ident()
99 .cloned()
100 .ok_or_else(|| format!("No ident on {:?}", self))?,
101 Item::Macro2(ref i) => i.ident.clone(),
102 Item::TraitAlias(ref i) => i.ident.clone(),
103
104 Item::Use(..) | Item::ForeignMod(..) | Item::Verbatim(..) => {
105 return Err("Item type not supported for Ident".to_string())
106 }
107 _ => panic!(),
108 })
109 }
110}
111
112pub trait GetAttributes
113{
114 fn get_attributes(&self) -> Result<Vec<Attribute>, String>;
116}
117
118impl GetAttributes for Item
119{
120 fn get_attributes(&self) -> Result<Vec<Attribute>, String>
121 {
122 Ok(match *self {
123 Item::ExternCrate(ref i) => i.attrs.clone(),
124 Item::Static(ref i) => i.attrs.clone(),
125 Item::Const(ref i) => i.attrs.clone(),
126 Item::Fn(ref i) => i.attrs.clone(),
127 Item::Mod(ref i) => i.attrs.clone(),
128 Item::Type(ref i) => i.attrs.clone(),
129 Item::Struct(ref i) => i.attrs.clone(),
130 Item::Enum(ref i) => i.attrs.clone(),
131 Item::Union(ref i) => i.attrs.clone(),
132 Item::Trait(ref i) => i.attrs.clone(),
133 Item::Impl(ref i) => i.attrs.clone(),
134 Item::Macro(ref i) => i.attrs.clone(),
135 Item::Macro2(ref i) => i.attrs.clone(),
136 Item::Use(ref i) => i.attrs.clone(),
137 Item::ForeignMod(ref i) => i.attrs.clone(),
138 Item::TraitAlias(ref i) => i.attrs.clone(),
139 Item::Verbatim(..) => vec![],
140 _ => panic!(),
141 })
142 }
143}
144
145pub trait ReplaceIdent: Sized
146{
147 fn map_ident(&self, f: impl FnOnce(&Ident) -> String) -> Result<Self, String>;
148}
149
150impl ReplaceIdent for syn::Path
151{
152 fn map_ident(&self, f: impl FnOnce(&Ident) -> String) -> Result<Self, String>
153 {
154 let mut result = self.clone();
155 let mut last = result
156 .segments
157 .last_mut()
158 .ok_or_else(|| format!("Path {:?} is empty", self))?;
159 last.ident = Ident::new(&f(&last.ident), Span::call_site());
160 Ok(result)
161 }
162}
163
164fn self_ty() -> Type
165{
166 parse_quote!(Self)
167}