1use std::collections::HashMap;
5
6#[allow(unused_imports)]
7use core_extensions::SelfOps;
8
9use quote::{quote, quote_spanned, ToTokens};
10
11use syn::Ident;
12
13use as_derive_utils::to_token_fn::ToTokenFnMut;
14
15use crate::parse_utils::parse_str_as_ident;
16
17pub(crate) mod attribute_parsing;
18mod macro_impl;
19
20pub(crate) use self::{
21 attribute_parsing::{parse_impl_interfacetype, ImplInterfaceType},
22 macro_impl::the_macro,
23};
24
25#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
29pub enum DefaultVal {
30 Unimplemented,
32 Implemented,
34 Hidden,
37}
38
39impl From<bool> for DefaultVal {
40 fn from(b: bool) -> Self {
41 if b {
42 DefaultVal::Implemented
43 } else {
44 DefaultVal::Unimplemented
45 }
46 }
47}
48
49#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
54pub struct UsableBy {
55 robject: bool,
56 dyn_trait: bool,
57}
58
59impl UsableBy {
60 pub const DYN_TRAIT: Self = Self {
61 robject: false,
62 dyn_trait: true,
63 };
64 pub const ROBJECT_AND_DYN_TRAIT: Self = Self {
65 robject: true,
66 dyn_trait: true,
67 };
68
69 pub const fn robject(&self) -> bool {
70 self.robject
71 }
72 pub const fn dyn_trait(&self) -> bool {
73 self.dyn_trait
74 }
75}
76
77#[derive(Debug, Copy, Clone)]
81pub struct UsableTrait {
82 pub which_trait: WhichTrait,
83 pub name: &'static str,
84 pub full_path: &'static str,
85}
86
87macro_rules! usable_traits {
88 (
89 $(
90 $field:ident=
91 (
92 $which_trait:ident,
93 $full_path:expr,
94 $default_value:expr,
95 $usable_by:expr
96 ),
97 )*
98 ) => (
99 pub static TRAIT_LIST:&[UsableTrait]=&[$(
101 UsableTrait{
102 name:stringify!($which_trait),
103 which_trait:WhichTrait::$which_trait,
104 full_path:$full_path,
105 },
106 )*];
107
108 #[repr(u8)]
111 #[derive(Debug,Copy,Clone,PartialEq,Eq,Ord,PartialOrd,Hash)]
112 pub enum WhichTrait{
113 $($which_trait,)*
114 }
115
116
117 impl WhichTrait{
118 pub fn default_value(self)->bool{
119 match self {
120 $( WhichTrait::$which_trait=>$default_value, )*
121 }
122 }
123 pub fn usable_by(self)->UsableBy{
124 match self {
125 $( WhichTrait::$which_trait=>$usable_by, )*
126 }
127 }
128 }
129
130 #[derive(Debug,Copy,Clone,Default)]
134 pub struct TraitStruct<T>{
135 $(pub $field:T,)*
136 }
137
138 impl TraitStruct<UsableTrait>{
139 pub const TRAITS:Self=TraitStruct{$(
140 $field:UsableTrait{
141 name:stringify!($which_trait),
142 which_trait:WhichTrait::$which_trait,
143 full_path:$full_path,
144 },
145 )*};
146 }
147
148 impl<T> TraitStruct<T>{
149 pub fn as_ref(&self)->TraitStruct<&T>{
150 TraitStruct{
151 $($field:&self.$field,)*
152 }
153 }
154
155 pub fn map<F,U>(self,mut f:F)->TraitStruct<U>
156 where F:FnMut(WhichTrait,T)->U
157 {
158 TraitStruct{
159 $($field:f(WhichTrait::$which_trait,self.$field),)*
160 }
161 }
162
163 #[allow(clippy::wrong_self_convention)]
165 pub fn to_vec(self)->Vec<T>{
166 vec![
167 $( self.$field ,)*
168 ]
169 }
170 }
171
172 impl<T> ::std::ops::Index<WhichTrait> for TraitStruct<T>{
173 type Output=T;
174 fn index(&self, index: WhichTrait) -> &Self::Output {
175 match index {
176 $( WhichTrait::$which_trait=>&self.$field, )*
177 }
178 }
179 }
180
181 impl<T> ::std::ops::IndexMut<WhichTrait> for TraitStruct<T>{
182 fn index_mut(&mut self, index: WhichTrait) -> &mut Self::Output {
183 match index {
184 $( WhichTrait::$which_trait=>&mut self.$field, )*
185 }
186 }
187 }
188 )
189}
190
191use self::UsableBy as UB;
192
193usable_traits! {
194 clone=(Clone,"::std::clone::Clone",false,UB::ROBJECT_AND_DYN_TRAIT),
195 default=(Default,"::std::default::Default",false,UB::DYN_TRAIT),
196 display=(Display,"::std::fmt::Display",false,UB::ROBJECT_AND_DYN_TRAIT),
197 debug=(Debug,"::std::fmt::Debug",false,UB::ROBJECT_AND_DYN_TRAIT),
198 serialize=(Serialize,"::serde::Serialize",false,UB::DYN_TRAIT),
199 eq=(Eq,"::std::cmp::Eq",false,UB::DYN_TRAIT),
200 partial_eq=(PartialEq,"::std::cmp::PartialEq",false,UB::DYN_TRAIT),
201 ord=(Ord,"::std::cmp::Ord",false,UB::DYN_TRAIT),
202 partial_ord=(PartialOrd,"::std::cmp::PartialOrd",false,UB::DYN_TRAIT),
203 hash=(Hash,"::std::hash::Hash",false,UB::DYN_TRAIT),
204 deserialize=(Deserialize,"::serde::Deserialize",false,UB::DYN_TRAIT),
205 send=(Send,"::std::marker::Send",false ,UB::ROBJECT_AND_DYN_TRAIT),
206 sync=(Sync,"::std::marker::Sync",false ,UB::ROBJECT_AND_DYN_TRAIT),
207 iterator=(Iterator,"::std::iter::Iterator",false,UB::DYN_TRAIT),
208 double_ended_iterator=(
209 DoubleEndedIterator,"::std::iter::DoubleEndedIterator",false,UB::DYN_TRAIT
210 ),
211 fmt_write=(FmtWrite,"::std::fmt::Write",false,UB::DYN_TRAIT),
212 io_write=(IoWrite,"::std::io::Write",false,UB::DYN_TRAIT),
213 io_seek=(IoSeek,"::std::io::Seek",false,UB::DYN_TRAIT),
214 io_read=(IoRead,"::std::io::Read",false,UB::DYN_TRAIT),
215 io_buf_read=(IoBufRead,"::std::io::BufRead",false,UB::DYN_TRAIT),
216 error=(Error,"::std::error::Error",false,UB::ROBJECT_AND_DYN_TRAIT),
217 unpin=(Unpin,"::std::marker::Unpin",false,UB::ROBJECT_AND_DYN_TRAIT),
218}
219
220pub(crate) fn private_associated_type() -> syn::Ident {
221 parse_str_as_ident("define_this_in_the_impl_InterfaceType_macro")
222}
223
224pub(crate) fn impl_interfacetype_tokenizer<'a>(
230 name: &'a Ident,
231 generics: &'a syn::Generics,
232 impl_interfacetype: Option<&'a ImplInterfaceType>,
233) -> impl ToTokens + 'a {
234 ToTokenFnMut::new(move |ts| {
235 let ImplInterfaceType { impld, unimpld } = match impl_interfacetype {
236 Some(x) => x,
237 None => return,
238 };
239
240 let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
241
242 let const_ident = crate::parse_utils::parse_str_as_ident(&format!(
243 "_impl_InterfaceType_constant_{}",
244 name,
245 ));
246
247 let impld_a = impld;
248 let impld_b = impld;
249
250 let unimpld_a = unimpld;
251 let unimpld_b = unimpld;
252
253 let priv_assocty = private_associated_type();
254
255 quote!(
256 const #const_ident:()={
257 use abi_stable::{
258 type_level::{
259 impl_enum::{
260 Implemented as __Implemented,
261 Unimplemented as __Unimplemented,
262 },
263 trait_marker,
264 },
265 };
266 impl #impl_generics abi_stable::InterfaceType for #name #ty_generics
267 #where_clause
268 {
269 #( type #impld_a=__Implemented<trait_marker::#impld_b>; )*
270 #( type #unimpld_a=__Unimplemented<trait_marker::#unimpld_b>; )*
271 type #priv_assocty=();
272 }
273 };
274 )
275 .to_tokens(ts);
276 })
277}
278
279