conjure_codegen/
aliases.rs1use proc_macro2::TokenStream;
15use quote::quote;
16
17use crate::context::{BaseModule, Context};
18use crate::types::objects::AliasDefinition;
19
20pub fn generate(ctx: &Context, def: &AliasDefinition) -> TokenStream {
21 let name = ctx.type_name(def.type_name().name());
22 let alias = ctx.rust_type(BaseModule::Objects, def.type_name(), def.alias());
23 let result = ctx.result_ident(def.type_name());
24 let docs = ctx.docs(def.docs());
25
26 let mut type_attrs = vec![quote!(#[serde(crate = "conjure_object::serde", transparent)])];
27 let mut field_attrs = vec![];
28 let mut derives = vec![
29 "Debug",
30 "Clone",
31 "conjure_object::serde::Deserialize",
32 "conjure_object::serde::Serialize",
33 ];
34
35 if ctx.is_copy(def.alias()) {
36 derives.push("Copy");
37 }
38
39 if ctx.is_double(def.alias()) {
40 derives.push("conjure_object::private::DeriveWith");
41 type_attrs.push(quote!(#[derive_with(PartialEq, Eq, PartialOrd, Ord, Hash)]));
42 field_attrs.push(quote!(#[derive_with(with = conjure_object::private::DoubleWrapper)]));
43 } else {
44 derives.push("PartialEq");
45 derives.push("Eq");
46 derives.push("PartialOrd");
47 derives.push("Ord");
48 derives.push("Hash");
49 }
50
51 if ctx.is_default(def.alias()) {
52 derives.push("Default");
53 }
54
55 let derives = derives.iter().map(|s| s.parse::<TokenStream>().unwrap());
56 type_attrs.insert(0, quote!(#[derive(#(#derives),*)]));
58
59 let display = if ctx.is_display(def.alias()) {
60 quote! {
61 impl std::fmt::Display for #name {
62 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63 std::fmt::Display::fmt(&self.0, fmt)
64 }
65 }
66 }
67 } else {
68 quote!()
69 };
70
71 let plain = if ctx.is_plain(def.alias()) {
72 quote! {
73 impl conjure_object::Plain for #name {
74 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75 conjure_object::Plain::fmt(&self.0, fmt)
76 }
77 }
78
79 impl conjure_object::FromPlain for #name {
80 type Err = <#alias as conjure_object::FromPlain>::Err;
81
82 #[inline]
83 fn from_plain(s: &str) -> #result<#name, Self::Err> {
84 conjure_object::FromPlain::from_plain(s).map(#name)
85 }
86 }
87 }
88 } else {
89 quote!()
90 };
91
92 let from_iterator = match ctx.is_from_iter(BaseModule::Objects, def.type_name(), def.alias()) {
93 Some(item) => quote! {
94 impl std::iter::FromIterator<#item> for #name {
95 fn from_iter<T>(iter: T) -> Self
96 where
97 T: std::iter::IntoIterator<Item = #item>,
98 {
99 #name(std::iter::FromIterator::from_iter(iter))
100 }
101 }
102 },
103 None => quote!(),
104 };
105
106 let dealiased_type = ctx.rust_type(
107 BaseModule::Objects,
108 def.type_name(),
109 ctx.dealiased_type(def.alias()),
110 );
111
112 quote! {
113 #docs
114 #(#type_attrs)*
115 pub struct #name(#(#field_attrs)* pub #alias);
116
117 #display
118
119 #plain
120
121 #from_iterator
122
123 impl std::convert::From<#dealiased_type> for #name {
124 #[inline]
125 fn from(v: #dealiased_type) -> Self {
126 #name(std::convert::From::from(v))
127 }
128 }
129
130 impl std::ops::Deref for #name {
131 type Target = #alias;
132
133 #[inline]
134 fn deref(&self) -> &#alias {
135 &self.0
136 }
137 }
138
139 impl std::ops::DerefMut for #name {
140 #[inline]
141 fn deref_mut(&mut self) -> &mut #alias {
142 &mut self.0
143 }
144 }
145
146 impl std::convert::AsRef<#dealiased_type> for #name {
147 #[inline]
148 fn as_ref(&self) -> &#dealiased_type {
149 &self.0
150 }
151 }
152 }
153}