1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use serde_derive_internals::{ast, ast::Container as SerdeContainer, attr};
use crate::{attrs::TsifyContainerAttrs, error_tracker::ErrorTracker};
/// Data structure storing information about a type decorated with `#[derive(Tsify)]`.
/// This structure also keeps information that was parsed via Serde's macros.
pub struct Container<'a> {
/// Errors that occurred during processing.
pub errors: ErrorTracker,
/// Attributes passed to the `#[derive(Tsify)]` macro.
pub attrs: TsifyContainerAttrs,
/// Information about the type as parsed by Serde.
pub serde_container: SerdeContainer<'a>,
/// The `ident` of the type, with `type_prefix` and `type_suffix` applied.
pub ident_str: String,
/// The name serde serializes the type under.
pub name: String,
}
impl<'a> Container<'a> {
pub fn new(serde_container: SerdeContainer<'a>) -> Self {
let input = &serde_container.original;
let attrs = TsifyContainerAttrs::from_derive_input(input);
let errors = ErrorTracker::new();
let attrs = match attrs {
Ok(attrs) => attrs,
Err(err) => {
errors.syn_error(err);
Default::default()
}
};
// No affix: this is the value serde writes, and serde knows nothing about
// `type_prefix` or `type_suffix`. Every other wire-facing name -- variant tags,
// field keys -- already comes straight from serde.
let name = serde_container.attrs.name().serialize_name().to_string();
let ident_str = attrs
.ty_config
.format_name(serde_container.ident.to_string());
Self {
errors,
attrs,
serde_container,
ident_str,
name,
}
}
pub fn from_derive_input(input: &'a syn::DeriveInput) -> syn::Result<Self> {
let cx = serde_derive_internals::Ctxt::new();
let serde_cont =
SerdeContainer::from_ast(&cx, input, serde_derive_internals::Derive::Serialize);
match serde_cont {
Some(serde_container) => {
cx.check()?;
Ok(Self::new(serde_container))
}
None => Err(cx.check().expect_err("serde_cont is None")),
}
}
/// The `ident` of the type as written in the Rust code.
pub fn ident(&self) -> &syn::Ident {
&self.serde_container.ident
}
/// The `ident` of the type as a string, with `type_prefix` and `type_suffix` applied.
pub fn ident_str(&self) -> String {
self.ident_str.clone()
}
/// The name of the generated declaration -- not `name()`, which reaches the wire.
pub fn declaration_name(&self) -> String {
self.attrs
.rename
.clone()
.unwrap_or_else(|| self.ident_str())
}
#[inline]
pub fn serde_attrs(&self) -> &attr::Container {
&self.serde_container.attrs
}
/// Whether or not Serde has marked this type as `transparent`.
pub fn transparent(&self) -> bool {
self.serde_attrs().transparent()
}
/// The name serde serializes the type under. This is wire data rather than a type
/// name, so no affix is applied.
pub fn name(&self) -> String {
self.name.clone()
}
/// Information about the generics associated with the type as parsed by Serde.
pub fn generics(&self) -> &syn::Generics {
self.serde_container.generics
}
/// Remove the default from every type parameter because in the generated impls
/// they look like associated types: "error: associated type bindings are not
/// allowed here".
pub fn generics_without_defaults(&self) -> syn::Generics {
let generics = self.generics();
syn::Generics {
params: generics
.params
.iter()
.map(|param| match param {
syn::GenericParam::Type(param) => syn::GenericParam::Type(syn::TypeParam {
eq_token: None,
default: None,
..param.clone()
}),
_ => param.clone(),
})
.collect(),
..generics.clone()
}
}
/// Information about the data fields of the type as parsed by Serde.
pub fn serde_data(&self) -> &ast::Data<'_> {
&self.serde_container.data
}
/// Add a new error to the list of processing errors.
pub fn syn_error(&self, err: syn::Error) {
self.errors.syn_error(err);
}
/// Return all accumulated errors.
pub fn check(self) -> syn::Result<()> {
self.errors.check()
}
}