simple_si_units_macros/
lib.rs1#![no_std]
2#![warn(missing_docs)]
3#![ doc = include_str!("../README.md")]
4use proc_macro::TokenStream;
5use quote::{quote};
6use syn::*;
7
8#[proc_macro_derive(UnitStruct)]
31pub fn derive_unit(tokens: TokenStream) -> TokenStream {
32 let input: syn::DeriveInput = syn::parse(tokens).expect("syn::parse failed on proc macro \
34 input for simple_si_units_macros::UnitStruct");
35
36 impl_derive_unit(&input)
38}
39
40fn impl_derive_unit(input: &syn::DeriveInput) -> TokenStream {
41 let requirements_msg = "Derive macro simple_si_units::UnitStruct can only be applied to structs \
42 with a single field, whose type implements core::ops::{Add, Sub, Div, Mul} (eg \
43 <T: NumLike>). For \
44 example:\n\nuse simple_si_units::{UnitStruct, NumLike};\n#[derive(UnitStruct, Debug, Copy, Clone)\
45 ]\nstruct MyNewUnitStruct<T: NumLike>{\n pub x: \
46 T\n}\n\nfn \
47 weighted_sum<T: NumLike>(a: MyNewUnitStruct<T>, b: MyNewUnitStruct<T>, weight: f64) -> MyNewUnitStruct<T> where T:\
48 NumLike + From<f64>\n{\n return weight*a + (1.-weight)*b;\n}\n";
49 let name = &input.ident;
50 let fields = match &input.data {
51 Data::Struct(DataStruct {
52 fields: Fields::Named(fields),
53 ..
54 }) => &fields.named,
55 _ => panic!("Only structs with named fields can derive simple_si_units::UnitStruct.\n\n{}",
56 requirements_msg),
57 };
58 if fields.len() != 1 {
59 panic!("proc macro simple_si_units::UnitStruct can only be used on structs with a single \
60 named field. \n\n{}", requirements_msg)
61 }
62 let data_name = &fields[0].ident.as_ref().unwrap();
63 let data_type = &fields[0].ty;
64 let gen = quote! {
65 #[doc="This struct implements the Copy marker trait if it's member data type also has the \
66 Copy trait"]
67 impl<#data_type> core::marker::Copy for #name<#data_type>
68 where #data_type: NumLike + core::marker::Copy { }
69 #[doc="This struct implements the PartialEq trait if it's member data type also has the \
70 PartialEq trait"]
71 impl<#data_type> core::cmp::PartialEq for #name<#data_type>
72 where #data_type: NumLike + core::cmp::PartialEq {
73 fn eq(&self, other: &Self) -> bool {
74 #data_type::eq(&self.#data_name, &other.#data_name)
75 }
76 fn ne(&self, other: &Self) -> bool {
77 #data_type::ne(&self.#data_name, &other.#data_name)
78 }
79 }
80 #[doc="This struct implements the core::cmp::Eq trait if it's member data type also has the \
81 core::cmp::Eq trait"]
82 impl<#data_type> core::cmp::Eq for #name<#data_type>
83 where #data_type: NumLike + core::cmp::PartialEq + core::cmp::Eq {}
84 #[doc="This struct implements the Hash trait if it's member data type also has the \
85 Hash trait"]
86 impl<#data_type> core::hash::Hash for #name<#data_type>
87 where #data_type: NumLike + core::hash::Hash {
88 fn hash<H: core::hash::Hasher>(&self, hasher: &mut H) {
89 #data_type::hash(&self.#data_name, hasher);
90 }
91 }
92 #[doc="This struct implements the PartialOrd trait if it's member data type also has the \
93 PartialOrd trait"]
94 impl<#data_type> core::cmp::PartialOrd for #name<#data_type>
95 where #data_type: NumLike + core::cmp::PartialOrd {
96 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
97 #data_type::partial_cmp(&self.#data_name, &other.#data_name)
98 }
99 }
100 #[doc="This struct implements the Ord trait if it's member data type also has the \
101 Ord trait"]
102 impl<#data_type> core::cmp::Ord for #name<#data_type>
103 where #data_type: NumLike + core::cmp::Ord {
104 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
105 #data_type::cmp(&self.#data_name, &other.#data_name)
106 }
107 }
108
109 #[doc="Adding two unit values of the same type returns a new unit value of the same type"]
110 impl<#data_type: NumLike> core::ops::Add<Self> for #name<#data_type> {
111 type Output = Self;
112 fn add(self, rhs: Self) -> Self::Output {
113 return Self{#data_name: self.#data_name + rhs.#data_name}
114 }
115 }
116 #[doc="Adds the given unit value to this unit value"]
117 impl<#data_type: NumLike> core::ops::AddAssign for #name<#data_type> {
118 fn add_assign(&mut self, rhs: Self){
119 self.#data_name += rhs.#data_name;
120 }
121 }
122 #[doc="Subtracting two unit values of the same type returns a new unit value of the same \
123 type"]
124 impl<#data_type: NumLike> core::ops::Sub<Self> for
125 #name<#data_type> {
126 type Output = Self;
127 fn sub(self, rhs: Self) -> Self::Output {
128 return Self{#data_name: self.#data_name - rhs.#data_name}
129 }
130 }
131 #[doc="Subtracts the given unit value from this unit value"]
132 impl<#data_type: NumLike> core::ops::SubAssign for #name<#data_type> {
133 fn sub_assign(&mut self, rhs: Self){
134 self.#data_name -= rhs.#data_name;
135 }
136 }
137 #[doc="Dividing a unit value by another of the same type returns a scalar value"]
138 impl<#data_type: NumLike> core::ops::Div<Self> for
139 #name<#data_type> {
140 type Output = #data_type;
141 fn div(self, rhs: Self) -> Self::Output {
142 return self.#data_name / rhs.#data_name;
143 }
144 }
145 #[doc="Dividing a unit value by a scalar value returns a unit value"]
146 impl<#data_type: NumLike> core::ops::Div<#data_type> for
147 #name<#data_type> {
148 type Output = Self;
149 fn div(self, rhs: #data_type) -> Self::Output {
150 return Self{#data_name: self.#data_name / rhs}
151 }
152 }
153 #[doc="Divides this unit value by a scalar"]
154 impl<#data_type: NumLike> core::ops::DivAssign<#data_type> for #name<#data_type> {
155 fn div_assign(&mut self, rhs: #data_type){
156 self.#data_name /= rhs;
157 }
158 }
159 #[doc="Multiplying a unit value by a scalar value returns a unit value"]
160 impl<#data_type: NumLike> core::ops::Mul<#data_type> for
161 #name<#data_type> {
162 type Output = Self;
163 fn mul(self, rhs: #data_type) -> Self::Output {
164 return Self{#data_name: self.#data_name * rhs}
165 }
166 }
167 #[doc="Multiplying a unit value by a scalar value returns a unit value"]
168 impl<#data_type> core::ops::Mul<&#data_type> for #name<#data_type>
169 where #data_type: NumLike {
170 type Output = #name<#data_type>;
171 fn mul(self, rhs: &#data_type) -> Self::Output {
172 #name{#data_name: self.#data_name * rhs.clone()}
173 }
174 }
175 #[doc="Multiplying a unit value by a scalar value returns a unit value"]
176 impl<#data_type> core::ops::Mul<&#data_type> for &#name<#data_type>
177 where #data_type: NumLike {
178 type Output = #name<#data_type>;
179 fn mul(self, rhs: &#data_type) -> Self::Output {
180 #name{#data_name: self.#data_name.clone() * rhs.clone()}
181 }
182 }
183 #[doc="Multiplies this unit value by a scalar"]
184 impl<#data_type: NumLike> core::ops::MulAssign<#data_type> for #name<#data_type> {
185 fn mul_assign(&mut self, rhs: #data_type){
186 self.#data_name *= rhs;
187 }
188 }
189 #[doc="Multiplying a unit value by a scalar value returns a unit value"]
190 impl<#data_type>
191 core::ops::Mul<#name<#data_type>> for
192 f64 where #data_type: NumLike + From<f64>{
193 type Output = #name<#data_type>;
194 fn mul(self, rhs: #name<#data_type>) -> Self::Output {
195 return #name{#data_name: #data_type::from(self) * rhs.#data_name}
196 }
197 }
198 #[doc="Multiplying a unit value by a scalar value returns a unit value"]
199 impl<#data_type>
200 core::ops::Mul<#name<#data_type>> for
201 f32 where #data_type: NumLike + From<f32>{
202 type Output = #name<#data_type>;
203 fn mul(self, rhs: #name<#data_type>) -> Self::Output {
204 return #name{#data_name: #data_type::from(self) * rhs.#data_name}
205 }
206 }
207 #[doc="Multiplying a unit value by a scalar value returns a unit value"]
208 impl<#data_type>
209 core::ops::Mul<#name<#data_type>> for
210 u8 where #data_type: NumLike + From<u8>{
211 type Output = #name<#data_type>;
212 fn mul(self, rhs: #name<#data_type>) -> Self::Output {
213 return #name{#data_name: #data_type::from(self) * rhs.#data_name}
214 }
215 }
216 #[doc="Multiplying a unit value by a scalar value returns a unit value"]
217 impl<#data_type>
218 core::ops::Mul<#name<#data_type>> for
219 i8 where #data_type: NumLike + From<i8>{
220 type Output = #name<#data_type>;
221 fn mul(self, rhs: #name<#data_type>) -> Self::Output {
222 return #name{#data_name: #data_type::from(self) * rhs.#data_name}
223 }
224 }
225 #[doc="Multiplying a unit value by a scalar value returns a unit value"]
226 impl<#data_type>
227 core::ops::Mul<#name<#data_type>> for
228 u16 where #data_type: NumLike + From<u16>{
229 type Output = #name<#data_type>;
230 fn mul(self, rhs: #name<#data_type>) -> Self::Output {
231 return #name{#data_name: #data_type::from(self) * rhs.#data_name}
232 }
233 }
234 #[doc="Multiplying a unit value by a scalar value returns a unit value"]
235 impl<#data_type>
236 core::ops::Mul<#name<#data_type>> for
237 i16 where #data_type: NumLike + From<i16>{
238 type Output = #name<#data_type>;
239 fn mul(self, rhs: #name<#data_type>) -> Self::Output {
240 return #name{#data_name: #data_type::from(self) * rhs.#data_name}
241 }
242 }
243 #[doc="Multiplying a unit value by a scalar value returns a unit value"]
244 impl<#data_type>
245 core::ops::Mul<#name<#data_type>> for
246 u32 where #data_type: NumLike + From<u32>{
247 type Output = #name<#data_type>;
248 fn mul(self, rhs: #name<#data_type>) -> Self::Output {
249 return #name{#data_name: #data_type::from(self) * rhs.#data_name}
250 }
251 }
252 #[doc="Multiplying a unit value by a scalar value returns a unit value"]
253 impl<#data_type>
254 core::ops::Mul<#name<#data_type>> for
255 i32 where #data_type: NumLike + From<i32>{
256 type Output = #name<#data_type>;
257 fn mul(self, rhs: #name<#data_type>) -> Self::Output {
258 return #name{#data_name: #data_type::from(self) * rhs.#data_name}
259 }
260 }
261 #[doc="Multiplying a unit value by a scalar value returns a unit value"]
262 impl<#data_type>
263 core::ops::Mul<#name<#data_type>> for
264 u64 where #data_type: NumLike + From<u64>{
265 type Output = #name<#data_type>;
266 fn mul(self, rhs: #name<#data_type>) -> Self::Output {
267 return #name{#data_name: #data_type::from(self) * rhs.#data_name}
268 }
269 }
270 #[doc="Multiplying a unit value by a scalar value returns a unit value"]
271 impl<#data_type>
272 core::ops::Mul<#name<#data_type>> for
273 i64 where #data_type: NumLike + From<i64>{
274 type Output = #name<#data_type>;
275 fn mul(self, rhs: #name<#data_type>) -> Self::Output {
276 return #name{#data_name: #data_type::from(self) * rhs.#data_name}
277 }
278 }
279 #[doc="Flips the sign of this unit value"]
280 impl<#data_type: NumLike> core::ops::Neg for
281 #name<#data_type> {
282 type Output = Self;
283 fn neg(self) -> Self::Output {
284 return Self{#data_name: self.#data_name.neg()}
285 }
286 }
287
288 #[doc="Adding two unit values of the same type returns a new unit value of the same type \
290 (automatically clones the referenced data for convenient ergonomics)"]
291 impl<#data_type: NumLike> core::ops::Add<Self> for &#name<#data_type> {
292 type Output = #name<#data_type>;
293 fn add(self, rhs: Self) -> Self::Output {
294 return Self::Output{#data_name: self.#data_name.clone() + rhs.#data_name.clone()}
295 }
296 }
297 #[doc="Subtracting two unit values of the same type returns a new unit value of the same \
298 type (automatically clones the referenced data for convenient ergonomics)"]
299 impl<#data_type: NumLike> core::ops::Sub<Self> for
300 &#name<#data_type> {
301 type Output = #name<#data_type>;
302 fn sub(self, rhs: Self) -> Self::Output {
303 return Self::Output{#data_name: self.#data_name.clone() - rhs.#data_name.clone()}
304 }
305 }
306 #[doc="Dividing a unit value by another of the same type returns a scalar value \
307 (automatically clones the referenced data for convenient ergonomics)"]
308 impl<#data_type: NumLike> core::ops::Div<Self> for
309 &#name<#data_type> {
310 type Output = #data_type;
311 fn div(self, rhs: Self) -> Self::Output {
312 return self.#data_name.clone() / rhs.#data_name.clone();
313 }
314 }
315 #[doc="Dividing a unit value by a scalar value returns a unit value (automatically clones \
316 the referenced data for convenient ergonomics)"]
317 impl<#data_type: NumLike> core::ops::Div<#data_type> for
318 &#name<#data_type> {
319 type Output = #name<#data_type>;
320 fn div(self, rhs: #data_type) -> Self::Output {
321 return Self::Output{#data_name: self.#data_name.clone() / rhs}
322 }
323 }
324 #[doc="Dividing a unit value by a scalar value returns a unit value"]
325 impl<#data_type> core::ops::Div<&#data_type> for #name<#data_type>
326 where #data_type: NumLike {
327 type Output = #name<#data_type>;
328 fn div(self, rhs: &#data_type) -> Self::Output {
329 #name{#data_name: self.#data_name / rhs.clone()}
330 }
331 }
332 #[doc="Dividing a unit value by a scalar value returns a unit value"]
333 impl<#data_type> core::ops::Div<&#data_type> for &#name<#data_type>
334 where #data_type: NumLike {
335 type Output = #name<#data_type>;
336 fn div(self, rhs: &#data_type) -> Self::Output {
337 #name{#data_name: self.#data_name.clone() / rhs.clone()}
338 }
339 }
340 #[doc="Multiplying a unit value by a scalar value returns a unit value (automatically \
341 clones the referenced data for convenient ergonomics)"]
342 impl<#data_type: NumLike> core::ops::Mul<#data_type> for
343 &#name<#data_type> {
344 type Output = #name<#data_type>;
345 fn mul(self, rhs: #data_type) -> Self::Output {
346 return Self::Output{#data_name: self.#data_name.clone() * rhs}
347 }
348 }
349 #[doc="Multiplying a unit value by a scalar value returns a unit value (automatically \
350 clones the referenced data for convenient ergonomics)"]
351 impl<#data_type>
352 core::ops::Mul<&#name<#data_type>> for
353 f64 where #data_type: NumLike + From<f64>{
354 type Output = #name<#data_type>;
355 fn mul(self, rhs: &#name<#data_type>) -> Self::Output {
356 return #name{#data_name: #data_type::from(self) * rhs.#data_name.clone()}
357 }
358 }
359 #[doc="Multiplying a unit value by a scalar value returns a unit value (automatically \
360 clones the referenced data for convenient ergonomics)"]
361 impl<#data_type>
362 core::ops::Mul<&#name<#data_type>> for
363 f32 where #data_type: NumLike + From<f32>{
364 type Output = #name<#data_type>;
365 fn mul(self, rhs: &#name<#data_type>) -> Self::Output {
366 return #name{#data_name: #data_type::from(self) * rhs.#data_name.clone()}
367 }
368 }
369 #[doc="Multiplying a unit value by a scalar value returns a unit value (automatically \
370 clones the referenced data for convenient ergonomics)"]
371 impl<#data_type>
372 core::ops::Mul<&#name<#data_type>> for
373 u8 where #data_type: NumLike + From<u8>{
374 type Output = #name<#data_type>;
375 fn mul(self, rhs: &#name<#data_type>) -> Self::Output {
376 return #name{#data_name: #data_type::from(self) * rhs.#data_name.clone()}
377 }
378 }
379 #[doc="Multiplying a unit value by a scalar value returns a unit value (automatically \
380 clones the referenced data for convenient ergonomics)"]
381 impl<#data_type>
382 core::ops::Mul<&#name<#data_type>> for
383 i8 where #data_type: NumLike + From<i8>{
384 type Output = #name<#data_type>;
385 fn mul(self, rhs: &#name<#data_type>) -> Self::Output {
386 return #name{#data_name: #data_type::from(self) * rhs.#data_name.clone()}
387 }
388 }
389 #[doc="Multiplying a unit value by a scalar value returns a unit value (automatically \
390 clones the referenced data for convenient ergonomics)"]
391 impl<#data_type>
392 core::ops::Mul<&#name<#data_type>> for
393 u16 where #data_type: NumLike + From<u16>{
394 type Output = #name<#data_type>;
395 fn mul(self, rhs: &#name<#data_type>) -> Self::Output {
396 return #name{#data_name: #data_type::from(self) * rhs.#data_name.clone()}
397 }
398 }
399 #[doc="Multiplying a unit value by a scalar value returns a unit value (automatically \
400 clones the referenced data for convenient ergonomics)"]
401 impl<#data_type>
402 core::ops::Mul<&#name<#data_type>> for
403 i16 where #data_type: NumLike + From<i16>{
404 type Output = #name<#data_type>;
405 fn mul(self, rhs: &#name<#data_type>) -> Self::Output {
406 return #name{#data_name: #data_type::from(self) * rhs.#data_name.clone()}
407 }
408 }
409 #[doc="Multiplying a unit value by a scalar value returns a unit value (automatically \
410 clones the referenced data for convenient ergonomics)"]
411 impl<#data_type>
412 core::ops::Mul<&#name<#data_type>> for
413 u32 where #data_type: NumLike + From<u32>{
414 type Output = #name<#data_type>;
415 fn mul(self, rhs: &#name<#data_type>) -> Self::Output {
416 return #name{#data_name: #data_type::from(self) * rhs.#data_name.clone()}
417 }
418 }
419 #[doc="Multiplying a unit value by a scalar value returns a unit value (automatically \
420 clones the referenced data for convenient ergonomics)"]
421 impl<#data_type>
422 core::ops::Mul<&#name<#data_type>> for
423 i32 where #data_type: NumLike + From<i32>{
424 type Output = #name<#data_type>;
425 fn mul(self, rhs: &#name<#data_type>) -> Self::Output {
426 return #name{#data_name: #data_type::from(self) * rhs.#data_name.clone()}
427 }
428 }
429 #[doc="Multiplying a unit value by a scalar value returns a unit value (automatically \
430 clones the referenced data for convenient ergonomics)"]
431 impl<#data_type>
432 core::ops::Mul<&#name<#data_type>> for
433 u64 where #data_type: NumLike + From<u64>{
434 type Output = #name<#data_type>;
435 fn mul(self, rhs: &#name<#data_type>) -> Self::Output {
436 return #name{#data_name: #data_type::from(self) * rhs.#data_name.clone()}
437 }
438 }
439 #[doc="Multiplying a unit value by a scalar value returns a unit value (automatically \
440 clones the referenced data for convenient ergonomics)"]
441 impl<#data_type>
442 core::ops::Mul<&#name<#data_type>> for
443 i64 where #data_type: NumLike + From<i64>{
444 type Output = #name<#data_type>;
445 fn mul(self, rhs: &#name<#data_type>) -> Self::Output {
446 return #name{#data_name: #data_type::from(self) * rhs.#data_name.clone()}
447 }
448 }
449 #[doc="Flips the sign of this unit value (automatically clones the referenced data for \
450 convenient ergonomics)"]
451 impl<#data_type: NumLike> core::ops::Neg for
452 &#name<#data_type> {
453 type Output = #name<#data_type>;
454 fn neg(self) -> Self::Output {
455 return Self::Output{#data_name: self.#data_name.clone().neg()}
456 }
457 }
458 };
469 let output = gen.into();
470 return output;
473}
474
475
476