wasm_wrapper_gen_shared/
types.rs1use std::fmt;
2
3use quote::{ToTokens, Tokens};
4
5use syn;
6
7use MacroError;
8
9#[derive(Debug, Copy, Clone, PartialEq, Eq)]
10pub enum SupportedCopyTy {
11 U8,
12 U16,
13 U32,
14 USize,
15 I8,
16 I16,
17 I32,
18 ISize,
19 F32,
20 F64,
21 Bool,
22}
23
24impl SupportedCopyTy {
25 pub fn new<T: AsRef<str>>(ident: &T) -> Option<Self> {
26 use self::SupportedCopyTy::*;
27 match ident.as_ref() {
28 "u8" => Some(U8),
29 "u16" => Some(U16),
30 "u32" => Some(U32),
31 "usize" => Some(USize),
32 "i8" => Some(I8),
33 "i16" => Some(I16),
34 "i32" => Some(I32),
35 "isize" => Some(ISize),
36 "f32" => Some(F32),
37 "f64" => Some(F64),
38 "bool" => Some(Bool),
39 _ => None,
40 }
41 }
42
43 pub fn size_in_bytes(&self) -> usize {
44 use self::SupportedCopyTy::*;
45 match *self {
47 Bool | U8 => 1,
48 U16 => 2,
49 USize | U32 => 4,
50 I8 => 1,
51 I16 => 2,
52 ISize | I32 => 4,
53 F32 => 4,
54 F64 => 8,
55 }
56 }
57}
58
59impl AsRef<str> for SupportedCopyTy {
60 fn as_ref(&self) -> &str {
61 use self::SupportedCopyTy::*;
62 match *self {
63 U8 => "u8",
64 U16 => "u16",
65 U32 => "u32",
66 USize => "usize",
67 I8 => "i8",
68 I16 => "i16",
69 I32 => "i32",
70 ISize => "isize",
71 F32 => "f32",
72 F64 => "f64",
73 Bool => "bool",
74 }
75 }
76}
77
78impl fmt::Display for SupportedCopyTy {
79 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
80 f.write_str(self.as_ref())
81 }
82}
83
84impl ToTokens for SupportedCopyTy {
85 fn to_tokens(&self, tokens: &mut Tokens) {
86 tokens.append(self.as_ref());
87 }
88}
89
90#[derive(Debug, Copy, Clone, PartialEq, Eq)]
91pub enum SupportedArgumentType {
92 IntegerSliceRef(SupportedCopyTy),
94 IntegerSliceMutRef(SupportedCopyTy),
96 IntegerVec(SupportedCopyTy),
98 Integer(SupportedCopyTy),
100 }
102
103fn resolve_parens(mut ty: &syn::Ty) -> &syn::Ty {
104 while let syn::Ty::Paren(ref temp) = *ty {
105 ty = temp;
106 }
107 ty
108}
109
110fn is_u8(ty: &syn::Ty) -> bool {
111 let ty = resolve_parens(ty);
112 if let syn::Ty::Path(None, ref path) = *ty {
113 if path.segments.len() <= 1 {
114 if let Some(segment) = path.segments.first() {
115 if segment.ident == "u8" && segment.parameters == syn::PathParameters::none() {
116 return true;
117 }
118 }
119 }
120 }
121 false
122}
123
124fn as_simple_integer(ty: &syn::Ty) -> Option<SupportedCopyTy> {
125 let ty = resolve_parens(ty);
126 if let syn::Ty::Path(None, ref path) = *ty {
127 if path.segments.len() <= 1 {
128 if let Some(segment) = path.segments.first() {
129 if segment.parameters == syn::PathParameters::none() {
130 return SupportedCopyTy::new(&segment.ident);
131 }
132 }
133 }
134 }
135 None
136}
137
138fn as_vec_simple_integer_type(ty: &syn::Ty) -> Option<SupportedCopyTy> {
139 let ty = resolve_parens(ty);
140 if let syn::Ty::Path(None, ref path) = *ty {
141 if path.segments.len() <= 1 {
142 if let Some(segment) = path.segments.first() {
143 if segment.ident == "Vec" {
144 if let syn::PathParameters::AngleBracketed(ref params) = segment.parameters {
145 if params.lifetimes.is_empty() && params.bindings.is_empty()
146 && params.types.len() == 1
147 {
148 if let Some(single_param_type) = params.types.first() {
149 return as_simple_integer(single_param_type);
150 }
151 }
152 }
153 }
154 }
155 }
156 }
157 None
158}
159
160impl SupportedArgumentType {
161 pub fn new(ty: &syn::Ty) -> Result<Self, MacroError> {
162 let ty = resolve_parens(ty);
163 if let syn::Ty::Rptr(_, ref slice_ty_mut) = *ty {
164 let slice_ty = resolve_parens(&slice_ty_mut.ty);
165 if let syn::Ty::Slice(ref byte_ty) = *slice_ty {
166 if let Some(inner_ty) = as_simple_integer(byte_ty) {
167 return Ok(match slice_ty_mut.mutability {
168 syn::Mutability::Immutable => {
169 SupportedArgumentType::IntegerSliceRef(inner_ty)
170 }
171 syn::Mutability::Mutable => {
172 SupportedArgumentType::IntegerSliceMutRef(inner_ty)
173 }
174 });
175 }
176 if is_u8(byte_ty) {}
177 }
178 }
179 if let Some(int_ty) = as_simple_integer(ty) {
180 return Ok(SupportedArgumentType::Integer(int_ty));
181 }
182 if let Some(item_ty) = as_vec_simple_integer_type(ty) {
183 return Ok(SupportedArgumentType::IntegerVec(item_ty));
184 }
185 Err(MacroError::UnhandledArgumentType { ty: ty.clone() })?
186 }
187}
188
189pub enum SupportedRetType {
190 IntegerVec(SupportedCopyTy),
192 Integer(SupportedCopyTy),
194 Unit,
196}
197
198
199impl SupportedRetType {
200 pub fn new(ty: &syn::Ty) -> Result<Self, MacroError> {
201 let ty = resolve_parens(ty);
202 if let Some(int_ty) = as_simple_integer(ty) {
203 return Ok(SupportedRetType::Integer(int_ty));
204 }
205 if let Some(item_ty) = as_vec_simple_integer_type(ty) {
206 return Ok(SupportedRetType::IntegerVec(item_ty));
207 }
208 if let syn::Ty::Tup(ref items) = *ty {
209 if items.is_empty() {
210 return Ok(SupportedRetType::Unit);
211 }
212 }
213 Err(MacroError::UnhandledRetType { ty: ty.clone() })?
214 }
215
216 pub fn unit() -> Self {
217 SupportedRetType::Unit
218 }
219}
220
221impl ToTokens for SupportedRetType {
222 fn to_tokens(&self, tokens: &mut Tokens) {
223 use SupportedRetType::*;
224 match *self {
225 IntegerVec(int_ty) => tokens.append(quote! { Vec<#int_ty> }),
226 Integer(int_ty) => int_ty.to_tokens(tokens),
227 Unit => tokens.append("()"),
228 }
229 }
230}