1extern crate proc_macro;
2
3use proc_macro::TokenStream;
4use syn::parse::{Parse, ParseStream};
5use syn::{DeriveInput, Token};
6
7struct Parameters {
8 parameters: Vec<(String, syn::Ident)>,
9}
10
11impl Parameters {
12 fn get_token(&self, name: &str) -> syn::Ident {
13 let expected_value = {
14 let mut value = String::from("missing parameter:");
15 value.push_str(name);
16 value
17 };
18 self.parameters
19 .iter()
20 .filter(|e| e.0 == name)
21 .nth(0)
22 .expect(expected_value.as_str())
23 .1
24 .clone()
25 }
26}
27
28impl Parse for Parameters {
29 fn parse(input: ParseStream) -> syn::Result<Self> {
30 let content;
31
32 syn::parenthesized!(content in input);
33 let mut result = Parameters { parameters: vec![] };
34
35 loop {
36 let key: syn::Ident = content.parse()?;
37 content.parse::<Token![=]>()?;
38 let value = content.parse()?;
39 result.parameters.push((key.to_string(), value));
40
41 match content.parse::<Token![,]>() {
42 Err(_) => break,
43 _ => continue,
44 }
45 }
46 Ok(result)
47 }
48}
49
50#[proc_macro_derive(SiDisplay)]
51pub fn display_macro_derive(input: TokenStream) -> TokenStream {
52 let ast: DeriveInput = syn::parse(input).unwrap();
55 impl_display_macro(&ast)
57}
58
59#[proc_macro_derive(SiAddSubtract)]
60pub fn add_subtract_macro_derive(input: TokenStream) -> TokenStream {
61 let ast = syn::parse(input).unwrap();
64
65 impl_add_subtract_macro(&ast)
67}
68
69fn impl_add_subtract_macro(ast: &syn::DeriveInput) -> TokenStream {
70 let name = &ast.ident;
71 let generate = quote::quote! {
72 impl core::cmp::PartialEq for #name {
73 fn eq(&self, rhs: &Self) -> bool {
74 #[cfg(feature = "f32")]
75 {
76 let lhs_log = libm::floorf(libm::log10f(self.native)) as i32;
77 let rhs_log = libm::floorf(libm::log10f(rhs.native)) as i32;
78 if( lhs_log != rhs_log ){
79 return false;
80 }
81 let power_of = (crate::SIGNIFICANT_FIGURES - lhs_log - 1) as crate::NativeType;
82 (libm::roundf((self.native - rhs.native) * libm::powf(10.0 as crate::NativeType, power_of))) as i32 == 0
83 }
84
85 #[cfg(not(feature = "f32"))]
86 {
87 let lhs_log = libm::floor(libm::log10(self.native)) as i32;
88 let rhs_log = libm::floor(libm::log10(rhs.native)) as i32;
89 if( lhs_log != rhs_log ){
90 return false;
91 }
92 let power_of = (crate::SIGNIFICANT_FIGURES - lhs_log - 1) as crate::NativeType;
93 (libm::round((self.native - rhs.native) * libm::pow(10.0 as crate::NativeType, power_of))) as i32 == 0
94 }
95 }
96 }
97
98 impl #name {
99 pub const fn new(native: crate::NativeType) -> Self {
100 Self{ native }
101 }
102
103 pub fn abs(&self) -> Self {
104 Self{ native: self.native.abs() }
105 }
106
107 }
108
109 impl Into<crate::NativeType> for #name {
110 fn into(self) -> crate::NativeType {
111 self.native
112 }
113 }
114
115 impl From<crate::NativeType> for #name {
116 fn from(native: crate::NativeType) -> #name {
117 #name{ native }
118 }
119 }
120
121 impl core::cmp::PartialOrd for #name {
122 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
123 self.native.partial_cmp(&other.native)
124 }
125 }
126
127 impl core::ops::Add for #name {
128 type Output = Self;
129 fn add(self, rhs: Self) -> Self {
130 Self::from(self.native + rhs.native)
131 }
132 }
133
134 impl core::ops::Mul<crate::Scalar> for #name {
135 type Output = Self;
136 fn mul(self, rhs: crate::Scalar) -> Self {
137 Self::from(self.native * rhs.native)
138 }
139 }
140
141 impl core::ops::Div<#name> for #name {
142 type Output = crate::Scalar;
143 fn div(self, rhs: #name) -> crate::Scalar {
144 crate::Scalar::from(self.native / rhs.native)
145 }
146 }
147
148 impl core::ops::AddAssign for #name {
149 fn add_assign(&mut self, rhs: Self) {
150 *self = Self::from(self.native + rhs.native);
151 }
152 }
153
154 impl core::ops::Sub for #name {
155 type Output = Self;
156 fn sub(self, rhs: Self) -> Self {
157 Self::from(self.native - rhs.native)
158 }
159 }
160
161 impl core::ops::SubAssign for #name {
162 fn sub_assign(&mut self, rhs: Self) {
163 *self = Self::from(self.native - rhs.native);
164 }
165 }
166 };
167 generate.into()
168}
169
170#[proc_macro_derive(SiMultiplyDivideScalar)]
171pub fn add_subtract_no_divide_macro_derive(input: TokenStream) -> TokenStream {
172 let ast = syn::parse(input).unwrap();
175
176 impl_multiply_divide_scalar_macro(&ast)
178}
179
180fn impl_multiply_divide_scalar_macro(ast: &syn::DeriveInput) -> TokenStream {
181 let name = &ast.ident;
182 let generate = quote::quote! {
183
184 impl core::ops::Mul<crate::Decibel<#name>> for #name
185 {
186 type Output = Self;
187 fn mul(self, rhs: crate::Decibel<#name>) -> Self {
188 Self::from(self * rhs.ratio())
189 }
190 }
191
192 impl core::ops::Mul<#name> for crate::Scalar {
193 type Output = #name;
194 fn mul(self, rhs: #name) -> #name {
195 #name::from(self.native * rhs.native)
196 }
197 }
198
199 impl core::ops::Div<crate::Scalar> for #name {
200 type Output = #name;
201 fn div(self, rhs: crate::Scalar) -> #name {
202 #name::from(self.native / rhs.native)
203 }
204 }
205
206 };
207 generate.into()
208}
209
210fn get_parameters(ast: &DeriveInput, expect: &'static str) -> Parameters {
211 let attribute = ast
212 .attrs
213 .iter()
214 .find(|a| a.path.segments.len() == 1 && a.path.segments[0].ident == "parameters")
215 .expect(expect);
216
217 syn::parse2(attribute.tokens.clone()).expect("Invalid parameters attribute!")
218}
219
220#[proc_macro_derive(SiMultiply, attributes(parameters))]
221pub fn mult_macro_derive(input: TokenStream) -> TokenStream {
222 let ast: DeriveInput = syn::parse(input).unwrap();
225 let parameters = get_parameters(&ast, "parameters required for deriving SiMultiply");
226
227 let name = &ast.ident;
229 let lhs = parameters.get_token("lhs_mult");
230 let rhs = parameters.get_token("rhs_mult");
231 gen_multiply(name, lhs, rhs)
232}
233
234#[proc_macro_derive(SiMultiplyAlt, attributes(parameters))]
235pub fn mult_alt_macro_derive(input: TokenStream) -> TokenStream {
236 let ast: DeriveInput = syn::parse(input).unwrap();
239 let parameters = get_parameters(&ast, "parameters required for deriving SiMultiply");
240
241 let name = &ast.ident;
243 let lhs = parameters.get_token("lhs_mult_alt");
244 let rhs = parameters.get_token("rhs_mult_alt");
245 gen_multiply(name, lhs, rhs)
246}
247
248fn gen_multiply(name: &syn::Ident, lhs: syn::Ident, rhs: syn::Ident) -> TokenStream {
249 let generate = quote::quote! {
250 impl core::ops::Mul<#rhs> for #lhs {
251 type Output = #name;
252 fn mul(self, rhs: #rhs) -> #name {
253 #name::from(self.native * rhs.native)
254 }
255 }
256
257 impl core::ops::Mul<#lhs> for #rhs {
258 type Output = #name;
259 fn mul(self, rhs: #lhs) -> #name {
260 #name::from(self.native * rhs.native)
261 }
262 }
263
264
265 impl core::ops::Div<#rhs> for #name {
266 type Output = #lhs;
267 fn div(self, rhs: #rhs) -> #lhs {
268 #lhs::from(self.native / rhs.native)
269 }
270 }
271
272 impl core::ops::Div<#lhs> for #name {
273 type Output = #rhs;
274 fn div(self, rhs: #lhs) -> #rhs {
275 #rhs::from(self.native / rhs.native)
276 }
277 }
278 };
279 generate.into()
280}
281
282#[proc_macro_derive(SiSquare, attributes(parameters))]
283pub fn square_macro_derive(input: TokenStream) -> TokenStream {
284 let ast: DeriveInput = syn::parse(input).unwrap();
285 let parameters = get_parameters(&ast, "parameters required for deriving SiSquare");
286 let name = &ast.ident;
287 let square = parameters.get_token("square");
288 let generate = quote::quote! {
289 impl core::ops::Mul<#square> for #square {
290 type Output = #name;
291 fn mul(self, square: #square) -> #name {
292 #name::from(self.native * square.native)
293 }
294 }
295
296 impl core::ops::Div<#square> for #name {
297 type Output = #square;
298 fn div(self, square: #square) -> #square {
299 #square::from(self.native / square.native)
300 }
301 }
302
303 impl #name {
304 pub fn sqrt(&self) -> #square {
305 #[cfg(feature = "f32")]
306 {
307 #square::from(libm::sqrtf(self.native))
308 }
309
310 #[cfg(not(feature = "f32"))]
311 {
312 #square::from(libm::sqrt(self.native))
313 }
314 }
315 }
316
317 };
318 generate.into()
319}
320
321#[proc_macro_derive(SiInvert, attributes(parameters))]
322pub fn invert_macro_derive(input: TokenStream) -> TokenStream {
323 let ast: DeriveInput = syn::parse(input).unwrap();
324 let parameters = get_parameters(&ast, "parameters required for deriving SiSquare");
325 let name = &ast.ident;
326 let inv = parameters.get_token("inv");
327 let generate = quote::quote! {
328 impl core::ops::Mul<#inv> for #name {
329 type Output = crate::Scalar;
330 fn mul(self, inv: #inv) -> crate::Scalar {
331 crate::Scalar::from(self.native * inv.native)
332 }
333 }
334
335 impl core::ops::Mul<#name> for #inv {
336 type Output = crate::Scalar;
337 fn mul(self, name: #name) -> crate::Scalar {
338 crate::Scalar::from(self.native * name.native)
339 }
340 }
341
342
343 impl core::ops::Div<#inv> for crate::Scalar {
344 type Output = #name;
345 fn div(self, inv: #inv) -> #name {
346 #name::from(self.native / inv.native)
347 }
348 }
349
350
351 impl core::ops::Div<#name> for crate::Scalar {
352 type Output = #inv;
353 fn div(self, name: #name) -> #inv {
354 #inv::from(self.native / name.native)
355 }
356 }
357
358 };
359 generate.into()
360}
361
362#[proc_macro_derive(SiDivide, attributes(parameters))]
363pub fn divide_macro_derive(input: TokenStream) -> TokenStream {
364 let ast: DeriveInput = syn::parse(input).unwrap();
367 let parameters = get_parameters(&ast, "parameters required for deriving SiDivide");
368
369 let name = &ast.ident;
370 let lhs = parameters.get_token("lhs_div");
371 let rhs = parameters.get_token("rhs_div");
372 let generate = quote::quote! {
373 impl core::ops::Div<#rhs> for #lhs {
374 type Output = #name;
375 fn div(self, rhs: #rhs) -> #name {
376 #name::from(self.native / rhs.native)
377 }
378 }
379
380 impl core::ops::Div<#name> for #lhs {
381 type Output = #rhs;
382 fn div(self, rhs: #name) -> #rhs {
383 #rhs::from(self.native / rhs.native)
384 }
385 }
386
387 impl core::ops::Mul<#rhs> for #name {
388 type Output = #lhs;
389 fn mul(self, rhs: #rhs) -> #lhs {
390 #lhs::from(self.native * rhs.native)
391 }
392 }
393
394 impl core::ops::Mul<#name> for #rhs {
395 type Output = #lhs;
396 fn mul(self, rhs: #name) -> #lhs {
397 #lhs::from(self.native * rhs.native)
398 }
399 }
400 };
401 generate.into()
402}
403
404#[proc_macro_derive(SiConvert, attributes(parameters))]
405pub fn convert_macro_derive(input: TokenStream) -> TokenStream {
406 let ast: DeriveInput = syn::parse(input).unwrap();
409 let parameters = get_parameters(&ast, "parameters required for deriving SiDivide");
410
411 let name = &ast.ident;
412 let multiplier = parameters.get_token("multiplier");
413 let offset = parameters.get_token("offset");
414 let into = parameters.get_token("into");
415 let generate = quote::quote! {
416
417 impl From<#into> for #name {
418 fn from(value: #into) -> Self {
419 Self::from(value.native * #multiplier + #offset)
420 }
421 }
422
423 impl Into<#into> for #name {
424 fn into(self) -> #into {
425 #into::from((self.native - #offset) / #multiplier)
426 }
427 }
428 };
429 generate.into()
430}
431
432struct UnitType {
433 name: &'static str,
434 label: &'static str,
435}
436
437const UNITS: &[UnitType] = &[
438 UnitType {
439 name: "Scalar",
440 label: "scalar",
441 },
442 UnitType {
443 name: "DecibelV",
444 label: "decibelsV",
445 },
446 UnitType {
447 name: "Decibel",
448 label: "decibels",
449 },
450 UnitType {
451 name: "Mass",
452 label: "kilograms",
453 },
454 UnitType {
455 name: "Time",
456 label: "seconds",
457 },
458 UnitType {
459 name: "ElectricCurrent",
460 label: "amps",
461 },
462 UnitType {
463 name: "ThermodynamicTemperature",
464 label: "kelvin",
465 },
466 UnitType {
467 name: "AmountOfSubstance",
468 label: "moles",
469 },
470 UnitType {
471 name: "Length",
472 label: "meters",
473 },
474 UnitType {
475 name: "LengthInverse",
476 label: "1/meter",
477 },
478 UnitType {
479 name: "OrthogonalLength",
480 label: "meters",
481 },
482 UnitType {
483 name: "LuminousIntensity",
484 label: "candelas",
485 },
486 UnitType {
487 name: "PlaneAngle",
488 label: "radians",
489 },
490 UnitType {
491 name: "PlaneAngleInverse",
492 label: "1/radians",
493 },
494 UnitType {
495 name: "SolidAngle",
496 label: "steradians",
497 },
498 UnitType {
499 name: "Frequency",
500 label: "hertz",
501 },
502 UnitType {
503 name: "FrequencySquared",
504 label: "hertz^2",
505 },
506 UnitType {
507 name: "Area",
508 label: "meters^2",
509 },
510 UnitType {
511 name: "Volume",
512 label: "meters^3",
513 },
514 UnitType {
515 name: "Liters",
516 label: "liters",
517 },
518 UnitType {
519 name: "Velocity",
520 label: "meters/second",
521 },
522 UnitType {
523 name: "VelocitySquared",
524 label: "(meters/second)^2",
525 },
526 UnitType {
527 name: "Acceleration",
528 label: "meters/second^2",
529 },
530 UnitType {
531 name: "Jerk",
532 label: "meters/second^3",
533 },
534 UnitType {
535 name: "Force",
536 label: "newtons",
537 },
538 UnitType {
539 name: "Pressure",
540 label: "pascals",
541 },
542 UnitType {
543 name: "Energy",
544 label: "joules",
545 },
546 UnitType {
547 name: "EnergyPerFrequency",
548 label: "joules/hertz",
549 },
550 UnitType {
551 name: "Power",
552 label: "watts",
553 },
554 UnitType {
555 name: "ElectricCharge",
556 label: "coulombs",
557 },
558 UnitType {
559 name: "ElectricPotential",
560 label: "volts",
561 },
562 UnitType {
563 name: "Capacitance",
564 label: "farads",
565 },
566 UnitType {
567 name: "ElectricResistance",
568 label: "ohms",
569 },
570 UnitType {
571 name: "ElectricConductance",
572 label: "siemens",
573 },
574 UnitType {
575 name: "MagneticFlux",
576 label: "webers",
577 },
578 UnitType {
579 name: "MagneticFluxDensity",
580 label: "teslas",
581 },
582 UnitType {
583 name: "Inductance",
584 label: "henries",
585 },
586 UnitType {
587 name: "Temperature",
588 label: "celcius",
589 },
590 UnitType {
591 name: "LuminousFlux",
592 label: "lumens",
593 },
594 UnitType {
595 name: "Illuminance",
596 label: "lux",
597 },
598 UnitType {
599 name: "DynamicViscosity",
600 label: "pascals*seconds",
601 },
602 UnitType {
603 name: "MomentOfForce",
604 label: "newtons*meters",
605 },
606 UnitType {
607 name: "Torque",
608 label: "newtons*meters",
609 },
610 UnitType {
611 name: "AngularVelocity",
612 label: "radians/second",
613 },
614 UnitType {
615 name: "AngularVelocitySquared",
616 label: "(radians/second)^2",
617 },
618 UnitType {
619 name: "AngularAcceleration",
620 label: "radians/second^2",
621 },
622 UnitType {
623 name: "SurfaceTension",
624 label: "newtons/meter",
625 },
626 UnitType {
627 name: "HeatFluxDensity",
628 label: "watts/meter^2",
629 },
630 UnitType {
631 name: "HeatCapacity",
632 label: "joules/kelvin",
633 },
634 UnitType {
635 name: "SpecificHeatCapacity",
636 label: "joules/(kilogram*kelvin)",
637 },
638 UnitType {
639 name: "SpecificEnergy",
640 label: "joules/kilogram",
641 },
642 UnitType {
643 name: "ThermalConductivity",
644 label: "watts/(meter*kelvin)",
645 },
646 UnitType {
647 name: "EnergyDensity",
648 label: "joules/meter^3",
649 },
650 UnitType {
651 name: "ElectricFieldStrength",
652 label: "volts/meter",
653 },
654 UnitType {
655 name: "ElectricChargeDensity",
656 label: "coulombs/meter^3",
657 },
658 UnitType {
659 name: "ElectricFluxDensity",
660 label: "coulombs/meter^2",
661 },
662 UnitType {
663 name: "Permittivity",
664 label: "farads/meter",
665 },
666 UnitType {
667 name: "Permeability",
668 label: "henries/meter",
669 },
670 UnitType {
671 name: "MolarEnergy",
672 label: "joules/mole",
673 },
674 UnitType {
675 name: "MolarHeatCapacity",
676 label: "joules/(mole*kelvin)",
677 },
678 UnitType {
679 name: "Radiance",
680 label: "watts/(meter^2*steradian)",
681 },
682 UnitType {
683 name: "MassThermodynamicTemperature",
684 label: "kilograms*kelvin",
685 },
686 UnitType {
687 name: "LengthThermodynamicTemperature",
688 label: "meters*kelvin",
689 },
690 UnitType {
691 name: "AmountOfSubstanceThermodynamicTemperature",
692 label: "moles*kelvin",
693 },
694 UnitType {
695 name: "AreaSolidAngle",
696 label: "meters^2/steradian",
697 },
698 UnitType {
699 name: "PerAmountOfSubstance",
700 label: "1/mole",
701 },
702 UnitType {
703 name: "EnergyPerFrequency",
704 label: "joules/hertz",
705 },
706 UnitType {
707 name: "MassDensity",
708 label: "kilograms/meter^3",
709 },
710 UnitType {
712 name: "Feet",
713 label: "feet",
714 },
715 UnitType {
716 name: "Yard",
717 label: "yards",
718 },
719 UnitType {
720 name: "Inch",
721 label: "inches",
722 },
723 UnitType {
724 name: "Miles",
725 label: "miles",
726 },
727 UnitType {
728 name: "Acres",
729 label: "acres",
730 },
731 UnitType {
732 name: "SquareMiles",
733 label: "squaremiles",
734 },
735 UnitType {
736 name: "Pints",
737 label: "pt",
738 },
739 UnitType {
740 name: "Quarts",
741 label: "qt",
742 },
743 UnitType {
744 name: "Gallons",
745 label: "gal",
746 },
747 UnitType {
748 name: "Degrees",
749 label: "degrees",
750 },
751 UnitType {
752 name: "DegreesPerSecond",
753 label: "degrees/second",
754 },
755 UnitType {
756 name: "DegreesPerSecondSquared",
757 label: "degrees/second^2",
758 },
759 UnitType {
760 name: "DegreesFahrenheit",
761 label: "degreesF",
762 },
763 UnitType {
764 name: "DegreesRankine",
765 label: "degreesR",
766 },
767 UnitType {
768 name: "Revolutions",
769 label: "revolutions",
770 },
771 UnitType {
772 name: "RevolutionsPerMinute",
773 label: "rpm",
774 },
775 UnitType {
776 name: "NauticalMiles",
777 label: "nauticalmiles",
778 },
779 UnitType {
780 name: "Knots",
781 label: "knots",
782 },
783 UnitType {
784 name: "FeetPerSecond",
785 label: "feet/second",
786 },
787 UnitType {
788 name: "FeetPerSecondSquared",
789 label: "feet/second^2",
790 },
791 UnitType {
792 name: "FeetPerMinute",
793 label: "feet/minute",
794 },
795 UnitType {
796 name: "G",
797 label: "g",
798 },
799 UnitType {
800 name: "PoundsForce",
801 label: "lbsforce",
802 },
803 UnitType {
804 name: "Pounds",
805 label: "lbs",
806 },
807 UnitType {
808 name: "Ounces",
809 label: "oz",
810 },
811 UnitType {
812 name: "PoundsPerSquareInch",
813 label: "psi",
814 },
815 UnitType {
816 name: "PoundsPerSquareFoot",
817 label: "psf",
818 },
819 UnitType {
820 name: "InchesMercury",
821 label: "inHg",
822 },
823 UnitType {
824 name: "FootPounds",
825 label: "ftlbs",
826 },
827];
828
829fn find_unit(name: String) -> &'static UnitType {
830 for unit in UNITS {
831 if name == unit.name {
832 return unit;
833 }
834 }
835 panic!("no unit named {} was found", name);
836}
837
838fn impl_display_macro(ast: &syn::DeriveInput) -> TokenStream {
839 let name = &ast.ident;
840 let name_string = name.to_string();
841 let current_unit = find_unit(name_string);
842 let label: &'static str = current_unit.label;
843
844 let generate = quote::quote! {
845
846 #[cfg(feature = "use_defmt")]
847 impl defmt::Format for #name {
848 fn format(&self, f: defmt::Formatter<'_>) {
849 defmt::write!(f, "{} {}", self.native, #label);
850 }
851 }
852
853 #[cfg(feature = "std")]
854 impl serde::Serialize for #name {
855 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
856 where
857 S: serde::Serializer,
858 {
859 let s = std::format!("{}_{}", self.native, #label);
861 serializer.serialize_str(&s)
862 }
863 }
864
865 #[cfg(feature = "std")]
866 impl<'de> serde::Deserialize<'de> for #name {
867 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
868 where
869 D: serde::Deserializer<'de>,
870 {
871 struct UnitsVisitor;
872
873 impl<'de> serde::de::Visitor<'de> for UnitsVisitor {
874 type Value = #name;
875
876 fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
877 f.write_str(format!("a string like `10.0_{}`", #label).as_str())
878 }
879
880 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
881 where
882 E: serde::de::Error,
883 {
884 if let Some((value_str, #label)) = v.rsplit_once('_') {
886 let native: crate::NativeType = value_str
887 .parse()
888 .map_err(|_| E::custom(format!("invalid float in {}", #label).as_str()))?;
889 return Ok(#name { native });
890 }
891
892 Err(E::custom(format!("expected format `<float>_{}`", #label).as_str()))
893 }
894 }
895
896 deserializer.deserialize_str(UnitsVisitor)
897 }
898 }
899
900 #[cfg(feature = "std")]
901 impl std::fmt::Display for #name {
902 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
903 write!(f, "{} {}", self.native, #label)
904 }
905 }
906
907 #[cfg(feature = "std")]
908 impl std::fmt::Debug for #name {
909 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> {
910 f.debug_struct(stringify!(#name))
911 .field("value", &self.to_string())
912 .field("label", &#label)
913 .finish()
914 }
915 }
916 };
917 generate.into()
918}