specta_typescript/
branded.rs1use std::borrow::Cow;
2
3use specta::datatype::DataType;
4
5#[macro_export]
42macro_rules! branded {
43 (
45 $(#[$attr:meta])*
46 $vis:vis struct $ident:ident<$($generic:ident),+ $(,)?> ( $ty:ty ) $(as $ts_name:literal)?
47 ) => {
48 $(#[$attr])*
49 $vis struct $ident<$($generic),+>($ty);
50
51 impl<$($generic: specta::Type),+> specta::Type for $ident<$($generic),+> {
52 fn definition(types: &mut specta::Types) -> specta::datatype::DataType {
53 let ty = <$ty as specta::Type>::definition(types);
54 let brand: &'static str = branded!(@brand $ident $( $ts_name )?);
55
56 specta::datatype::DataType::Reference(
57 specta::datatype::Reference::opaque(
58 $crate::Branded::new(std::borrow::Cow::Borrowed(brand), ty)
59 )
60 )
61 }
62 }
63 };
64
65 (
67 $(#[$attr:meta])*
68 $vis:vis struct $ident:ident ( $ty:ty ) $(as $ts_name:literal)?
69 ) => {
70 $(#[$attr])*
71 $vis struct $ident($ty);
72
73 impl specta::Type for $ident {
74 fn definition(types: &mut specta::Types) -> specta::datatype::DataType {
75 let ty = <$ty as specta::Type>::definition(types);
76 let brand: &'static str = branded!(@brand $ident $( $ts_name )?);
77
78 specta::datatype::DataType::Reference(
79 specta::datatype::Reference::opaque(
80 $crate::Branded::new(std::borrow::Cow::Borrowed(brand), ty)
81 )
82 )
83 }
84 }
85 };
86
87 (@brand $ident:ident $ts_name:literal) => {
89 $ts_name
90 };
91 (@brand $ident:ident) => {
92 stringify!($ident)
93 };
94}
95
96#[derive(Debug, Clone, PartialEq, Eq, Hash)]
97pub struct Branded {
99 brand: Cow<'static, str>,
100 ty: DataType,
101}
102
103impl Branded {
104 pub fn new(brand: impl Into<Cow<'static, str>>, ty: DataType) -> Self {
106 Self {
107 brand: brand.into(),
108 ty,
109 }
110 }
111
112 pub fn brand(&self) -> &Cow<'static, str> {
114 &self.brand
115 }
116
117 pub fn ty(&self) -> &DataType {
119 &self.ty
120 }
121}