1#![allow(dead_code)]
7
8use crate::ident;
9use crate::xdr::*;
10use alloc::string::*;
11
12pub trait HasSpecification {
14 fn spec() -> Specification;
16}
17
18pub trait XDR {
22 fn def() -> Definition;
24}
25
26impl<T: HasTypeDef> XDR for T {
27 fn def() -> Definition {
28 Definition::Type(T::type_def())
29 }
30}
31
32pub trait HasTypeDef {
37 fn type_def() -> TypeDef;
39
40 fn type_ident() -> Ident {
42 type_def_ident(Self::type_def())
43 }
44
45 fn named_declaration(name: Ident) -> Declaration {
47 named_declaration_from_type_def(name, Self::type_def())
48 }
49}
50
51pub trait HasTypeSpec {
56 fn type_spec() -> TypeSpec;
58}
59
60impl<T: HasTypeDef> HasTypeSpec for T {
61 fn type_spec() -> TypeSpec {
62 TypeSpec::Ident(T::type_ident())
63 }
64}
65
66pub(crate) fn type_def_ident(type_def: TypeDef) -> Ident {
67 match type_def {
68 TypeDef::Def(decl) => decl_ident(decl),
69 TypeDef::Enum(ident, _) => ident,
70 TypeDef::Struct(ident, _) => ident,
71 TypeDef::Union(ident, _) => ident,
72 }
73}
74
75fn decl_ident(decl: Declaration) -> Ident {
76 match decl {
77 Declaration::Named { name: ident, .. } => ident,
78 Declaration::FixedOpaque { name: ident, .. } => ident,
79 Declaration::VariableOpaque { name: ident, .. } => ident,
80 Declaration::String { name: ident, .. } => ident,
81 Declaration::FixedArray { name: ident, .. } => ident,
82 Declaration::VariableArray { name: ident, .. } => ident,
83 Declaration::Optional { name: ident, .. } => ident,
84 Declaration::Void => Ident("void".to_string()),
85 }
86}
87
88fn named_declaration_from_type_def(name: Ident, type_def: TypeDef) -> Declaration {
89 let declare_named = |ty_ident| Declaration::Named {
90 name,
91 ty: TypeSpec::Ident(ty_ident),
92 };
93
94 match type_def {
95 TypeDef::Def(decl) => match decl.name() {
96 Some(ty_ident) => declare_named(ty_ident.clone()),
97 None => decl,
98 },
99 TypeDef::Struct(ty_ident, _) => declare_named(ty_ident),
100 TypeDef::Enum(ty_ident, _) => declare_named(ty_ident),
101 TypeDef::Union(ty_ident, _) => declare_named(ty_ident),
102 }
103}
104
105macro_rules! impl_has_type_spec {
106 { $( $ty:ty => $spec:expr ),* $(,)? } =>
107 {$(
108 impl HasTypeSpec for $ty {
109 fn type_spec() -> TypeSpec {
110 $spec
111 }
112 }
113 )*};
114}
115
116impl_has_type_spec! {
117 i32 => TypeSpec::Int,
118 u32 => TypeSpec::Unsigned,
119 i64 => TypeSpec::Hyper,
120 u64 => TypeSpec::UnsignedHyper,
121 bool => TypeSpec::Bool,
122 f32 => TypeSpec::Float,
123 f64 => TypeSpec::Double,
124}
125
126#[cfg(feature = "int128")]
130#[cfg_attr(docsrs, doc(cfg(feature = "int128")))]
131impl_has_type_spec! {
133 i128 => <(i64, u64)>::type_spec(),
134 u128 => <(u64, u64)>::type_spec()
135}
136
137pub trait Declare {
142 fn declare(name: Ident) -> Declaration;
144}
145
146macro_rules! impl_declare_named {
147 { $( $ty:ty => $spec:expr ),* $(,)? } =>
148 {$(
149 impl Declare for $ty {
150 fn declare(name: Ident) -> Declaration {
151 Declaration::Named {
152 name,
153 ty: $spec
154 }
155 }
156 }
157 )*};
158}
159
160impl_declare_named! {
161 i32 => TypeSpec::Int,
162 u32 => TypeSpec::Unsigned,
163 i64 => TypeSpec::Hyper,
164 u64 => TypeSpec::UnsignedHyper,
165 bool => TypeSpec::Bool,
166 f32 => TypeSpec::Float,
167 f64 => TypeSpec::Double,
168}
169
170#[cfg(feature = "int128")]
171#[cfg_attr(docsrs, doc(cfg(feature = "int128")))]
172impl_declare_named! {
174 i128 => <(i64, u64)>::type_spec(),
175 u128 => <(u64, u64)>::type_spec(),
176}
177
178macro_rules! impl_refs {
179 ($($ty:ty),* $(,)?) => {$(
180 impl HasTypeSpec for &$ty {
181 fn type_spec() -> TypeSpec {
182 <$ty>::type_spec()
183 }
184 }
185 impl HasTypeSpec for &mut $ty {
186 fn type_spec() -> TypeSpec {
187 <$ty>::type_spec()
188 }
189 }
190 impl Declare for &$ty {
191 fn declare(name: Ident) -> Declaration {
192 <$ty>::declare(name)
193 }
194 }
195 impl Declare for &mut $ty {
196 fn declare(name: Ident) -> Declaration {
197 <$ty>::declare(name)
198 }
199 }
200 )*};
201}
202
203impl_refs! {
204 i32, u32, i64, u64, bool, f32, f64,
205}
206
207#[cfg(feature = "int128")]
208#[cfg_attr(docsrs, doc(cfg(feature = "int128")))]
209impl_refs! {
210 i128, u128,
211}
212
213impl<T: HasTypeSpec> HasTypeSpec for Option<T> {
214 fn type_spec() -> TypeSpec {
215 TypeSpec::Struct(StructBody::new(alloc::vec![Declaration::Optional {
218 name: ident("unnamed_0"),
219 opt_ty: T::type_spec(),
220 }]))
221 }
222}
223
224impl<T: HasTypeSpec> Declare for Option<T> {
225 fn declare(name: Ident) -> Declaration {
226 Declaration::Optional {
227 name,
228 opt_ty: T::type_spec(),
229 }
230 }
231}
232
233const _: () = {
234 use alloc::boxed::Box;
235
236 impl<T: HasTypeDef> HasTypeDef for Box<T> {
237 fn type_def() -> TypeDef {
238 T::type_def()
239 }
240
241 fn type_ident() -> Ident {
242 T::type_ident()
243 }
244
245 fn named_declaration(name: Ident) -> Declaration {
246 T::named_declaration(name)
247 }
248 }
249};
250
251impl<const N: usize> Declare for [u8; N] {
252 fn declare(name: Ident) -> Declaration {
253 const { assert!(N <= u32::MAX as usize, "N exceeds u32::MAX") }
254 Declaration::FixedOpaque {
255 name,
256 size: Value::Const((N as u32).into()),
257 }
258 }
259}
260
261impl<const N: usize> HasTypeSpec for [u8; N] {
264 fn type_spec() -> TypeSpec {
265 const { assert!(N <= u32::MAX as usize, "N exceeds u32::MAX") }
266 TypeSpec::Struct(StructBody::new(alloc::vec![Declaration::FixedOpaque {
269 name: ident("unnamed_0"),
270 size: Value::Const((N as u32).into()),
271 }]))
272 }
273}
274
275impl<const N: usize> Declare for &[u8; N] {
276 fn declare(name: Ident) -> Declaration {
277 <[u8; N]>::declare(name)
278 }
279}
280
281impl<const N: usize> HasTypeSpec for &[u8; N] {
282 fn type_spec() -> TypeSpec {
283 <[u8; N]>::type_spec()
284 }
285}
286
287impl<const N: usize> Declare for &mut [u8; N] {
288 fn declare(name: Ident) -> Declaration {
289 <[u8; N]>::declare(name)
290 }
291}
292
293impl<const N: usize> HasTypeSpec for &mut [u8; N] {
294 fn type_spec() -> TypeSpec {
295 <[u8; N]>::type_spec()
296 }
297}
298
299impl<const N: usize, T: HasTypeSpec> Declare for [T; N] {
300 fn declare(name: Ident) -> Declaration {
301 const { assert!(N <= u32::MAX as usize, "N exceeds u32::MAX") }
302 Declaration::FixedArray {
303 name,
304 elt_ty: T::type_spec(),
305 len: Value::Const((N as u32).into()),
306 }
307 }
308}
309
310impl<const N: usize, T: HasTypeSpec> HasTypeSpec for [T; N] {
313 fn type_spec() -> TypeSpec {
314 const { assert!(N <= u32::MAX as usize, "N exceeds u32::MAX") }
315 TypeSpec::Struct(StructBody::new(alloc::vec![Declaration::FixedArray {
318 name: ident("unnamed_0"),
319 elt_ty: T::type_spec(),
320 len: Value::Const((N as u32).into()),
321 }]))
322 }
323}
324
325impl<const N: usize, T: HasTypeSpec> HasTypeSpec for &[T; N] {
326 fn type_spec() -> TypeSpec {
327 <[T; N]>::type_spec()
328 }
329}
330
331impl<const N: usize, T: HasTypeSpec> Declare for &[T; N] {
332 fn declare(name: Ident) -> Declaration {
333 <[T; N]>::declare(name)
334 }
335}
336
337impl<const N: usize, T: HasTypeSpec> HasTypeSpec for &mut [T; N] {
338 fn type_spec() -> TypeSpec {
339 <[T; N]>::type_spec()
340 }
341}
342
343impl<const N: usize, T: HasTypeSpec> Declare for &mut [T; N] {
344 fn declare(name: Ident) -> Declaration {
345 <[T; N]>::declare(name)
346 }
347}
348
349impl HasTypeSpec for &[u8] {
350 fn type_spec() -> TypeSpec {
351 TypeSpec::Struct(StructBody::new(alloc::vec![Declaration::VariableOpaque {
352 name: ident("unnamed_0"),
353 max: Value::Const(Constant::Unsigned(u32::MAX)),
354 }]))
355 }
356}
357
358impl Declare for &[u8] {
359 fn declare(name: Ident) -> Declaration {
360 Declaration::VariableOpaque {
361 name,
362 max: Value::Const(Constant::Unsigned(u32::MAX)),
363 }
364 }
365}
366
367impl HasTypeSpec for &mut [u8] {
368 fn type_spec() -> TypeSpec {
369 <&[u8]>::type_spec()
370 }
371}
372
373impl Declare for &mut [u8] {
374 fn declare(name: Ident) -> Declaration {
375 <&[u8]>::declare(name)
376 }
377}
378
379impl HasTypeSpec for &str {
380 fn type_spec() -> TypeSpec {
381 TypeSpec::Struct(StructBody::new(alloc::vec![<&str as Declare>::declare(
382 ident("unnamed_0")
383 ),]))
384 }
385}
386
387impl Declare for &str {
388 fn declare(name: Ident) -> Declaration {
389 Declaration::String {
390 name,
391 max: Value::Const(Constant::Unsigned(u32::MAX)),
392 }
393 }
394}
395
396impl HasTypeSpec for &mut str {
397 fn type_spec() -> TypeSpec {
398 <&str>::type_spec()
399 }
400}
401
402impl Declare for &mut str {
403 fn declare(name: Ident) -> Declaration {
404 <&str>::declare(name)
405 }
406}
407
408impl<T: HasTypeSpec> HasTypeSpec for &[T] {
409 fn type_spec() -> TypeSpec {
410 TypeSpec::Struct(StructBody::new(alloc::vec![<&[T] as Declare>::declare(
411 ident("unnamed_0"),
412 )]))
413 }
414}
415
416impl<T: HasTypeSpec> Declare for &[T] {
417 fn declare(name: Ident) -> Declaration {
418 Declaration::VariableArray {
419 name,
420 elt_ty: T::type_spec(),
421 max: Value::Const(Constant::Unsigned(u32::MAX)),
422 }
423 }
424}
425
426impl<T: HasTypeSpec> HasTypeSpec for &mut [T] {
427 fn type_spec() -> TypeSpec {
428 <&[T]>::type_spec()
429 }
430}
431
432impl<T: HasTypeSpec> Declare for &mut [T] {
433 fn declare(name: Ident) -> Declaration {
434 <&[T]>::declare(name)
435 }
436}
437
438const _: () = {
439 use xdr_common::{BytesM, StaticIfNoAlloc, StringM, VecM};
440
441 impl<T, const MAX: u32> HasTypeSpec for VecM<T, MAX>
442 where
443 T: HasTypeSpec + StaticIfNoAlloc,
444 {
445 fn type_spec() -> TypeSpec {
446 TypeSpec::Struct(StructBody::new(alloc::vec![Declaration::VariableArray {
447 name: ident("unnamed_0"),
448 elt_ty: T::type_spec(),
449 max: Value::Const(Constant::Unsigned(MAX)),
450 }]))
451 }
452 }
453
454 impl<T, const MAX: u32> Declare for VecM<T, MAX>
455 where
456 T: HasTypeSpec + StaticIfNoAlloc,
457 {
458 fn declare(name: Ident) -> Declaration {
459 Declaration::VariableArray {
460 name,
461 elt_ty: T::type_spec(),
462 max: Value::Const(Constant::Unsigned(MAX)),
463 }
464 }
465 }
466
467 impl<const MAX: u32> HasTypeSpec for VecM<u8, MAX> {
471 fn type_spec() -> TypeSpec {
472 BytesM::<MAX>::type_spec()
473 }
474 }
475
476 impl<const MAX: u32> Declare for VecM<u8, MAX> {
477 fn declare(name: Ident) -> Declaration {
478 BytesM::<MAX>::declare(name)
479 }
480 }
481
482 impl<const MAX: u32> HasTypeSpec for BytesM<MAX> {
483 fn type_spec() -> TypeSpec {
484 TypeSpec::Struct(StructBody::new(alloc::vec![Declaration::VariableOpaque {
485 name: ident("unnamed_0"),
486 max: Value::Const(Constant::Unsigned(MAX)),
487 }]))
488 }
489 }
490
491 impl<const MAX: u32> Declare for BytesM<MAX> {
492 fn declare(name: Ident) -> Declaration {
493 Declaration::VariableOpaque {
494 name,
495 max: Value::Const(Constant::Unsigned(MAX)),
496 }
497 }
498 }
499
500 impl<const MAX: u32> Declare for StringM<MAX> {
501 fn declare(name: Ident) -> Declaration {
502 Declaration::String {
503 name,
504 max: Value::Const(Constant::Unsigned(MAX)),
505 }
506 }
507 }
508
509 impl<const MAX: u32> HasTypeSpec for StringM<MAX> {
510 fn type_spec() -> TypeSpec {
511 TypeSpec::Struct(StructBody::new(alloc::vec![Declaration::String {
512 name: ident("unnamed_0"),
513 max: Value::Const(Constant::Unsigned(MAX)),
514 }]))
515 }
516 }
517
518 impl<const MAX: u32> HasTypeSpec for &BytesM<MAX> {
519 fn type_spec() -> TypeSpec {
520 BytesM::<MAX>::type_spec()
521 }
522 }
523
524 impl<const MAX: u32> Declare for &BytesM<MAX> {
525 fn declare(name: Ident) -> Declaration {
526 BytesM::<MAX>::declare(name)
527 }
528 }
529
530 impl<const MAX: u32> HasTypeSpec for &mut BytesM<MAX> {
531 fn type_spec() -> TypeSpec {
532 BytesM::<MAX>::type_spec()
533 }
534 }
535
536 impl<const MAX: u32> Declare for &mut BytesM<MAX> {
537 fn declare(name: Ident) -> Declaration {
538 BytesM::<MAX>::declare(name)
539 }
540 }
541
542 impl<const MAX: u32> HasTypeSpec for &StringM<MAX> {
543 fn type_spec() -> TypeSpec {
544 StringM::<MAX>::type_spec()
545 }
546 }
547
548 impl<const MAX: u32> Declare for &StringM<MAX> {
549 fn declare(name: Ident) -> Declaration {
550 StringM::<MAX>::declare(name)
551 }
552 }
553
554 impl<const MAX: u32> HasTypeSpec for &mut StringM<MAX> {
555 fn type_spec() -> TypeSpec {
556 StringM::<MAX>::type_spec()
557 }
558 }
559
560 impl<const MAX: u32> Declare for &mut StringM<MAX> {
561 fn declare(name: Ident) -> Declaration {
562 StringM::<MAX>::declare(name)
563 }
564 }
565
566 impl<const MAX: u32> HasTypeSpec for &VecM<u8, MAX> {
567 fn type_spec() -> TypeSpec {
568 VecM::<u8, MAX>::type_spec()
569 }
570 }
571
572 impl<const MAX: u32> Declare for &VecM<u8, MAX> {
573 fn declare(name: Ident) -> Declaration {
574 VecM::<u8, MAX>::declare(name)
575 }
576 }
577
578 impl<const MAX: u32> HasTypeSpec for &mut VecM<u8, MAX> {
579 fn type_spec() -> TypeSpec {
580 VecM::<u8, MAX>::type_spec()
581 }
582 }
583
584 impl<const MAX: u32> Declare for &mut VecM<u8, MAX> {
585 fn declare(name: Ident) -> Declaration {
586 VecM::<u8, MAX>::declare(name)
587 }
588 }
589
590 impl<T, const MAX: u32> HasTypeSpec for &VecM<T, MAX>
591 where
592 T: HasTypeSpec + StaticIfNoAlloc,
593 {
594 fn type_spec() -> TypeSpec {
595 VecM::<T, MAX>::type_spec()
596 }
597 }
598
599 impl<T, const MAX: u32> Declare for &VecM<T, MAX>
600 where
601 T: HasTypeSpec + StaticIfNoAlloc,
602 {
603 fn declare(name: Ident) -> Declaration {
604 VecM::<T, MAX>::declare(name)
605 }
606 }
607
608 impl<T, const MAX: u32> HasTypeSpec for &mut VecM<T, MAX>
609 where
610 T: HasTypeSpec + StaticIfNoAlloc,
611 {
612 fn type_spec() -> TypeSpec {
613 VecM::<T, MAX>::type_spec()
614 }
615 }
616
617 impl<T, const MAX: u32> Declare for &mut VecM<T, MAX>
618 where
619 T: HasTypeSpec + StaticIfNoAlloc,
620 {
621 fn declare(name: Ident) -> Declaration {
622 VecM::<T, MAX>::declare(name)
623 }
624 }
625};
626
627const _: () = {
628 use alloc::boxed::Box;
629 use xdr_common::{BytesM, StaticIfNoAlloc, StringM, VecM};
630
631 impl<const MAX: u32> Declare for Box<BytesM<MAX>> {
632 fn declare(name: Ident) -> Declaration {
633 BytesM::<MAX>::declare(name)
634 }
635 }
636
637 impl<const MAX: u32> Declare for Box<StringM<MAX>> {
638 fn declare(name: Ident) -> Declaration {
639 StringM::<MAX>::declare(name)
640 }
641 }
642
643 impl<T, const MAX: u32> Declare for Box<VecM<T, MAX>>
644 where
645 T: HasTypeSpec + StaticIfNoAlloc,
646 {
647 fn declare(name: Ident) -> Declaration {
648 VecM::<T, MAX>::declare(name)
649 }
650 }
651
652 impl<const MAX: u32> Declare for Box<VecM<u8, MAX>> {
653 fn declare(name: Ident) -> Declaration {
654 BytesM::<MAX>::declare(name)
655 }
656 }
657
658 impl<const MAX: u32> HasTypeSpec for Box<BytesM<MAX>> {
659 fn type_spec() -> TypeSpec {
660 BytesM::<MAX>::type_spec()
661 }
662 }
663
664 impl<const MAX: u32> HasTypeSpec for Box<StringM<MAX>> {
665 fn type_spec() -> TypeSpec {
666 StringM::<MAX>::type_spec()
667 }
668 }
669
670 impl<T, const MAX: u32> HasTypeSpec for Box<VecM<T, MAX>>
671 where
672 T: HasTypeSpec + StaticIfNoAlloc,
673 {
674 fn type_spec() -> TypeSpec {
675 VecM::<T, MAX>::type_spec()
676 }
677 }
678
679 impl<const MAX: u32> HasTypeSpec for Box<VecM<u8, MAX>> {
680 fn type_spec() -> TypeSpec {
681 BytesM::<MAX>::type_spec()
682 }
683 }
684
685 impl<T: HasTypeSpec> Declare for Box<Option<T>> {
686 fn declare(name: Ident) -> Declaration {
687 <Option<T>>::declare(name)
688 }
689 }
690
691 impl<T: HasTypeSpec> HasTypeSpec for Box<Option<T>> {
692 fn type_spec() -> TypeSpec {
693 <Option<T>>::type_spec()
694 }
695 }
696};
697
698#[cfg(feature = "heapless")]
699const _: () = {
700 use heapless::{String, Vec};
701
702 fn heapless_max_value<const N: usize>() -> Value {
703 const { assert!(N <= u32::MAX as usize, "N exceeds u32::MAX") }
704 Value::Const(Constant::Unsigned(N as u32))
705 }
706
707 impl<const N: usize> HasTypeSpec for Vec<u8, N> {
708 fn type_spec() -> TypeSpec {
709 TypeSpec::Struct(StructBody::new(alloc::vec![Declaration::VariableOpaque {
710 name: ident("unnamed_0"),
711 max: heapless_max_value::<N>(),
712 }]))
713 }
714 }
715
716 impl<const N: usize> Declare for Vec<u8, N> {
717 fn declare(name: Ident) -> Declaration {
718 Declaration::VariableOpaque {
719 name,
720 max: heapless_max_value::<N>(),
721 }
722 }
723 }
724
725 impl<const N: usize> HasTypeSpec for &Vec<u8, N> {
726 fn type_spec() -> TypeSpec {
727 Vec::<u8, N>::type_spec()
728 }
729 }
730
731 impl<const N: usize> Declare for &Vec<u8, N> {
732 fn declare(name: Ident) -> Declaration {
733 Vec::<u8, N>::declare(name)
734 }
735 }
736
737 impl<const N: usize> HasTypeSpec for &mut Vec<u8, N> {
738 fn type_spec() -> TypeSpec {
739 Vec::<u8, N>::type_spec()
740 }
741 }
742
743 impl<const N: usize> Declare for &mut Vec<u8, N> {
744 fn declare(name: Ident) -> Declaration {
745 Vec::<u8, N>::declare(name)
746 }
747 }
748
749 impl<T, const N: usize> HasTypeSpec for Vec<T, N>
750 where
751 T: HasTypeSpec,
752 {
753 fn type_spec() -> TypeSpec {
754 TypeSpec::Struct(StructBody::new(alloc::vec![Declaration::VariableArray {
755 name: ident("unnamed_0"),
756 elt_ty: T::type_spec(),
757 max: heapless_max_value::<N>(),
758 }]))
759 }
760 }
761
762 impl<T, const N: usize> Declare for Vec<T, N>
763 where
764 T: HasTypeSpec,
765 {
766 fn declare(name: Ident) -> Declaration {
767 Declaration::VariableArray {
768 name,
769 elt_ty: T::type_spec(),
770 max: heapless_max_value::<N>(),
771 }
772 }
773 }
774
775 impl<T, const N: usize> HasTypeSpec for &Vec<T, N>
776 where
777 T: HasTypeSpec,
778 {
779 fn type_spec() -> TypeSpec {
780 Vec::<T, N>::type_spec()
781 }
782 }
783
784 impl<T, const N: usize> Declare for &Vec<T, N>
785 where
786 T: HasTypeSpec,
787 {
788 fn declare(name: Ident) -> Declaration {
789 Vec::<T, N>::declare(name)
790 }
791 }
792
793 impl<T, const N: usize> HasTypeSpec for &mut Vec<T, N>
794 where
795 T: HasTypeSpec,
796 {
797 fn type_spec() -> TypeSpec {
798 Vec::<T, N>::type_spec()
799 }
800 }
801
802 impl<T, const N: usize> Declare for &mut Vec<T, N>
803 where
804 T: HasTypeSpec,
805 {
806 fn declare(name: Ident) -> Declaration {
807 Vec::<T, N>::declare(name)
808 }
809 }
810
811 impl<const N: usize> HasTypeSpec for String<N> {
812 fn type_spec() -> TypeSpec {
813 TypeSpec::Struct(StructBody::new(alloc::vec![Declaration::String {
814 name: ident("unnamed_0"),
815 max: heapless_max_value::<N>(),
816 }]))
817 }
818 }
819
820 impl<const N: usize> Declare for String<N> {
821 fn declare(name: Ident) -> Declaration {
822 Declaration::String {
823 name,
824 max: heapless_max_value::<N>(),
825 }
826 }
827 }
828
829 impl<const N: usize> HasTypeSpec for &String<N> {
830 fn type_spec() -> TypeSpec {
831 String::<N>::type_spec()
832 }
833 }
834
835 impl<const N: usize> Declare for &String<N> {
836 fn declare(name: Ident) -> Declaration {
837 String::<N>::declare(name)
838 }
839 }
840
841 impl<const N: usize> HasTypeSpec for &mut String<N> {
842 fn type_spec() -> TypeSpec {
843 String::<N>::type_spec()
844 }
845 }
846
847 impl<const N: usize> Declare for &mut String<N> {
848 fn declare(name: Ident) -> Declaration {
849 String::<N>::declare(name)
850 }
851 }
852};
853
854const _: () = {
855 use alloc::vec::Vec;
856
857 impl HasTypeSpec for Vec<u8> {
858 fn type_spec() -> TypeSpec {
859 TypeSpec::Struct(StructBody::new(alloc::vec![Declaration::VariableOpaque {
860 name: ident("unnamed_0"),
861 max: Value::Const(Constant::Unsigned(u32::MAX)),
862 }]))
863 }
864 }
865
866 impl Declare for Vec<u8> {
867 fn declare(name: Ident) -> Declaration {
868 Declaration::VariableOpaque {
869 name,
870 max: Value::Const(Constant::Unsigned(u32::MAX)),
871 }
872 }
873 }
874
875 impl<T: HasTypeSpec> HasTypeSpec for Vec<T> {
876 fn type_spec() -> TypeSpec {
877 TypeSpec::Struct(StructBody::new(alloc::vec![Declaration::VariableArray {
878 name: ident("unnamed_0"),
879 elt_ty: T::type_spec(),
880 max: Value::Const(Constant::Unsigned(u32::MAX)),
881 }]))
882 }
883 }
884
885 impl<T: HasTypeSpec> Declare for Vec<T> {
886 fn declare(name: Ident) -> Declaration {
887 Declaration::VariableArray {
888 name,
889 elt_ty: T::type_spec(),
890 max: Value::Const(Constant::Unsigned(u32::MAX)),
891 }
892 }
893 }
894
895 impl HasTypeSpec for alloc::string::String {
896 fn type_spec() -> TypeSpec {
897 TypeSpec::Struct(StructBody::new(alloc::vec![
898 <alloc::string::String as Declare>::declare(ident("unnamed_0")),
899 ]))
900 }
901 }
902
903 impl Declare for alloc::string::String {
904 fn declare(name: Ident) -> Declaration {
905 Declaration::String {
906 name,
907 max: Value::Const(Constant::Unsigned(u32::MAX)),
908 }
909 }
910 }
911
912 impl HasTypeSpec for &Vec<u8> {
913 fn type_spec() -> TypeSpec {
914 Vec::<u8>::type_spec()
915 }
916 }
917
918 impl Declare for &Vec<u8> {
919 fn declare(name: Ident) -> Declaration {
920 Vec::<u8>::declare(name)
921 }
922 }
923
924 impl HasTypeSpec for &mut Vec<u8> {
925 fn type_spec() -> TypeSpec {
926 Vec::<u8>::type_spec()
927 }
928 }
929
930 impl Declare for &mut Vec<u8> {
931 fn declare(name: Ident) -> Declaration {
932 Vec::<u8>::declare(name)
933 }
934 }
935
936 impl<T: HasTypeSpec> HasTypeSpec for &Vec<T> {
937 fn type_spec() -> TypeSpec {
938 Vec::<T>::type_spec()
939 }
940 }
941
942 impl<T: HasTypeSpec> Declare for &Vec<T> {
943 fn declare(name: Ident) -> Declaration {
944 Vec::<T>::declare(name)
945 }
946 }
947
948 impl<T: HasTypeSpec> HasTypeSpec for &mut Vec<T> {
949 fn type_spec() -> TypeSpec {
950 Vec::<T>::type_spec()
951 }
952 }
953
954 impl<T: HasTypeSpec> Declare for &mut Vec<T> {
955 fn declare(name: Ident) -> Declaration {
956 Vec::<T>::declare(name)
957 }
958 }
959
960 impl HasTypeSpec for &alloc::string::String {
961 fn type_spec() -> TypeSpec {
962 alloc::string::String::type_spec()
963 }
964 }
965
966 impl Declare for &alloc::string::String {
967 fn declare(name: Ident) -> Declaration {
968 alloc::string::String::declare(name)
969 }
970 }
971
972 impl HasTypeSpec for &mut alloc::string::String {
973 fn type_spec() -> TypeSpec {
974 alloc::string::String::type_spec()
975 }
976 }
977
978 impl Declare for &mut alloc::string::String {
979 fn declare(name: Ident) -> Declaration {
980 alloc::string::String::declare(name)
981 }
982 }
983};
984
985impl Declare for () {
992 fn declare(_name: Ident) -> Declaration {
993 Declaration::Void
994 }
995}
996
997impl<T> Declare for core::marker::PhantomData<T> {
998 fn declare(_name: Ident) -> Declaration {
999 Declaration::Void
1000 }
1001}
1002
1003impl<T> Declare for T
1004where
1005 T: HasTypeDef,
1006{
1007 fn declare(name: Ident) -> Declaration {
1008 T::named_declaration(name)
1009 }
1010}
1011
1012impl<T: HasTypeDef> HasTypeDef for &T {
1014 fn type_def() -> TypeDef {
1015 T::type_def()
1016 }
1017
1018 fn type_ident() -> Ident {
1019 T::type_ident()
1020 }
1021
1022 fn named_declaration(name: Ident) -> Declaration {
1023 T::named_declaration(name)
1024 }
1025}
1026
1027impl<T: HasTypeDef> HasTypeDef for &mut T {
1028 fn type_def() -> TypeDef {
1029 T::type_def()
1030 }
1031
1032 fn type_ident() -> Ident {
1033 T::type_ident()
1034 }
1035
1036 fn named_declaration(name: Ident) -> Declaration {
1037 T::named_declaration(name)
1038 }
1039}
1040
1041macro_rules! impl_tuple_types {
1045 ( $($idx:tt : $t:ident),+ ) => {
1046 impl<$($t),+> HasTypeSpec for ($($t,)+)
1048 where
1049 $( $t: Declare, )+
1050 {
1051 fn type_spec() -> TypeSpec {
1052 let body = StructBody::new(alloc::vec![
1054 $(
1055 $t::declare(ident(concat!("unnamed_", stringify!($idx)))),
1056 )+
1057 ]);
1058
1059 TypeSpec::Struct(body)
1061 }
1062 }
1063
1064 impl<$($t),+> Declare for ($($t,)+)
1066 where
1067 $( $t: Declare, )+
1068 {
1069 fn declare(name: Ident) -> Declaration {
1070 Declaration::Named {
1071 name,
1072 ty: Self::type_spec(),
1073 }
1074 }
1075 }
1076 };
1077}
1078
1079impl_tuple_types!(0: T0);
1081impl_tuple_types!(0: T0, 1: T1);
1082impl_tuple_types!(0: T0, 1: T1, 2: T2);
1083impl_tuple_types!(0: T0, 1: T1, 2: T2, 3: T3);
1084impl_tuple_types!(0: T0, 1: T1, 2: T2, 3: T3, 4: T4);
1085impl_tuple_types!(0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5);
1086impl_tuple_types!(0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6);
1087impl_tuple_types!(0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6, 7: T7);
1088impl_tuple_types!(0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6, 7: T7, 8: T8);
1089impl_tuple_types!(0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6, 7: T7, 8: T8, 9: T9);
1090impl_tuple_types!(0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6, 7: T7, 8: T8, 9: T9, 10: T10);
1091impl_tuple_types!(0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6, 7: T7, 8: T8, 9: T9, 10: T10, 11: T11);
1092impl_tuple_types!(0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6, 7: T7, 8: T8, 9: T9, 10: T10, 11: T11, 12: T12);
1093impl_tuple_types!(0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6, 7: T7, 8: T8, 9: T9, 10: T10, 11: T11, 12: T12, 13: T13);
1094impl_tuple_types!(0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6, 7: T7, 8: T8, 9: T9, 10: T10, 11: T11, 12: T12, 13: T13, 14: T14);
1095impl_tuple_types!(0: T0, 1: T1, 2: T2, 3: T3, 4: T4, 5: T5, 6: T6, 7: T7, 8: T8, 9: T9, 10: T10, 11: T11, 12: T12, 13: T13, 14: T14, 15: T15);