1use std::{borrow::Cow, collections::BTreeMap, fmt::Debug};
2
3use serde::{self, Serialize};
4
5#[derive(Debug, Serialize)]
6#[cfg_attr(feature = "generate", derive(serde::Deserialize))]
7pub struct TypeRoot {
8 #[serde(rename = "f")]
9 pub file: String,
10 #[serde(rename = "l")]
11 pub line: u32,
12 #[serde(rename = "i")]
13 pub inner: Named<RootItem>,
14 #[serde(rename = "e")]
16 pub extras: Vec<Named<ContainerFormat>>,
17}
18
19#[derive(Debug, Serialize)]
21#[cfg_attr(feature = "generate", derive(serde::Deserialize))]
22pub enum RootItem {
23 Container(ContainerFormat),
24 Function(FunctionFormat),
25}
26
27#[derive(Serialize)]
28#[cfg_attr(feature = "generate", derive(serde::Deserialize))]
29pub struct Spanned<T> {
30 #[serde(rename = "$")]
31 pub value: T,
32 #[serde(rename = "_")]
33 #[serde(skip_serializing_if = "is_null_bytes", default)]
34 pub bytes: (usize, usize),
36}
37
38fn is_null_bytes(value: &(usize, usize)) -> bool {
39 value.0 == 0 && value.1 == 0
40}
41
42impl<T: Debug> Debug for Spanned<T> {
43 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44 f.write_fmt(format_args!("#{:?} ", self.bytes))?;
45 self.value.fmt(f)
46 }
47}
48
49#[derive(Debug, Serialize)]
53#[cfg_attr(feature = "generate", derive(serde::Deserialize))]
54pub enum Format {
55 Incomplete {
56 debug: String,
57 },
58 TypeName {
60 ident: String,
61 generics: Vec<Format>,
62 },
63
64 Unit,
66 Bool,
67 I8,
68 I16,
69 I32,
70 I64,
71 I128,
72 ISIZE,
73 U8,
74 U16,
75 U32,
76 U64,
77 U128,
78 USIZE,
79 F32,
80 F64,
81 Char,
82 Str,
83 Bytes,
84
85 Option(Box<Format>),
87 Never,
89 Seq(Box<Format>),
91 Map {
93 key: Box<Format>,
94 value: Box<Format>,
95 },
96
97 Tuple(Vec<Format>),
99 TupleArray {
102 content: Box<Format>,
103 size: usize,
104 },
105}
106
107impl Format {
108 pub fn is_primitive(&self) -> bool {
109 match self {
110 Format::Unit
112 | Format::Bool
113 | Format::I8
114 | Format::I16
115 | Format::I32
116 | Format::I64
117 | Format::I128
118 | Format::ISIZE
119 | Format::U8
120 | Format::U16
121 | Format::U32
122 | Format::U64
123 | Format::U128
124 | Format::USIZE
125 | Format::F32
126 | Format::F64
127 | Format::Char
128 | Format::Str
129 | Format::Bytes => true,
130 _ => false,
131 }
132 }
133 pub fn is_typename(&self) -> Option<(&str, &[Format])> {
134 match self {
135 Format::TypeName { ident, generics } => Some((&ident, &generics)),
136 _ => None,
137 }
138 }
139 pub fn as_ident(&self) -> Cow<'static, str> {
140 Cow::Borrowed(match self {
141 Format::Incomplete { debug } => todo!("Unknown ident incomplete: {debug}"),
142 Format::TypeName { ident, generics } => {
143 return Cow::Owned({
144 let mut buf = format!("{ident}");
145 for gen in generics.iter() {
146 buf.push('_');
147 buf.push_str(&gen.as_ident());
148 }
149 buf
150 })
151 }
152 Format::Unit => "Nil",
153 Format::Bool => "Bool",
154 Format::I8 => "I8",
155 Format::I16 => "I16",
156 Format::I32 => "I32",
157 Format::I64 => "I64",
158 Format::I128 => "I128",
159 Format::ISIZE => "ISIZE",
160 Format::U8 => "U8",
161 Format::U16 => "U16",
162 Format::U32 => "U32",
163 Format::U64 => "U64",
164 Format::U128 => "U128",
165 Format::USIZE => "USIZE",
166 Format::F32 => "F32",
167 Format::F64 => "F64",
168 Format::Char => "Char",
169 Format::Str => "Str",
170 Format::Bytes => "Bytes",
171 Format::Option(of) => return Cow::Owned(format!("{}_Option", of.as_ident())),
172 Format::Never => "Never",
173 Format::Seq(of) => return Cow::Owned(format!("{}_List", of.as_ident())),
174 Format::Map { key, value } => {
175 return Cow::Owned(format!("{}_{}_Map", key.as_ident(), value.as_ident()))
176 }
177 Format::Tuple(of) => {
178 return Cow::Owned(format!(
179 "{}Tuple",
180 of.iter()
181 .flat_map(|v| [v.as_ident(), Cow::Borrowed("_")])
182 .collect::<String>()
183 ))
184 }
185 Format::TupleArray { content, size } => {
186 return Cow::Owned(format!("{}_{}_TupleOf", content.as_ident(), size))
187 }
188 })
189 }
190 pub fn replace_incomplete(&mut self, replacement: Format) {
191 if let Format::Incomplete { .. } = self {
192 *self = replacement;
193 return;
194 }
195 if self.is_primitive() || self.is_typename().is_some() {
196 return;
197 }
198 match (self, replacement) {
199 (Format::Option(ref mut original), Format::Option(replacement)) => {
200 original.replace_incomplete(*replacement);
201 }
202 (Format::Seq(ref mut original), Format::Seq(replacement)) => {
203 original.replace_incomplete(*replacement);
204 }
205 (
206 Format::Map {
207 ref mut key,
208 ref mut value,
209 },
210 Format::Map {
211 key: replace_key,
212 value: replace_value,
213 },
214 ) => {
215 key.replace_incomplete(*replace_key);
216 value.replace_incomplete(*replace_value);
217 }
218 (Format::Tuple(ref mut original), Format::Tuple(replacement_vec)) => {
219 for (original_item, replacement) in original.iter_mut().zip(replacement_vec) {
220 original_item.replace_incomplete(replacement);
221 }
222 }
223 (
224 Format::TupleArray {
225 ref mut content, ..
226 },
227 Format::TupleArray {
228 content: replacement_content,
229 ..
230 },
231 ) => {
232 content.replace_incomplete(*replacement_content);
233 }
234 (original, replacement) => {
235 panic!("Failed to merge original and replacement:\n{original:#?}\nREPLACEMENT\n{replacement:#?}")
236 }
237 }
238 }
239}
240
241#[derive(Debug, Serialize)]
244#[cfg_attr(feature = "generate", derive(serde::Deserialize))]
245pub enum ContainerFormat {
246 UnitStruct,
248 NewTypeStruct(Box<Format>),
250 TupleStruct(Vec<Format>),
252 Struct(Vec<Named<Format>>),
254 Enum(BTreeMap<u32, Named<VariantFormat>>),
257}
258
259#[derive(Debug, Serialize)]
260#[cfg_attr(feature = "generate", derive(serde::Deserialize))]
261pub enum VariantFormat {
263 Unit,
265 NewType(Box<Format>),
267 Tuple(Vec<Format>),
269 Struct(Vec<Named<Format>>),
271}
272
273#[derive(Debug, Serialize)]
275#[cfg_attr(feature = "generate", derive(serde::Deserialize))]
276pub struct FunctionFormat {
277 pub is_async: bool,
278 pub self_opt: Option<Named<Format>>,
279 pub params: Vec<Named<Format>>,
280 pub ret: Box<Format>,
281}
282
283#[derive(Debug, Serialize)]
284#[cfg_attr(feature = "generate", derive(serde::Deserialize))]
285pub struct Named<T> {
288 #[serde(rename = "id")]
289 pub rust_ident: Spanned<String>,
290 #[serde(rename = "gn")]
291 pub rust_generics: Vec<Spanned<String>>,
292 #[serde(skip_serializing_if = "Option::is_none", default)]
293 #[serde(rename = "docs")]
294 pub rust_docs: Option<String>,
295 #[serde(skip_serializing_if = "Vec::is_empty", default)]
296 #[serde(rename = "sa")]
297 pub serde_attrs: Vec<Spanned<(Spanned<String>, Spanned<String>)>>,
298 #[serde(skip_serializing_if = "Vec::is_empty", default)]
299 #[serde(rename = "sf")]
300 pub serde_flags: Vec<Spanned<String>>,
301 #[serde(skip_serializing_if = "Vec::is_empty", default)]
302 #[serde(rename = "ca")]
303 pub codegen_attrs: Vec<Spanned<(Spanned<String>, Spanned<String>)>>,
304 #[serde(skip_serializing_if = "Vec::is_empty", default)]
305 #[serde(rename = "cf")]
306 pub codegen_flags: Vec<Spanned<String>>,
307 #[serde(rename = "$")]
308 pub value: T,
309}
310
311impl<T> Named<T> {
312 pub fn builtin(ident: &str, docs: &str, bytes: Option<(usize, usize)>, value: T) -> Self {
313 Named {
314 rust_ident: Spanned {
315 value: ident.to_string(),
316 bytes: bytes.unwrap_or_default(),
317 },
318 rust_generics: Vec::new(),
319 rust_docs: {
320 let docs = docs.trim();
321 if docs.is_empty() {
322 None
323 } else {
324 Some(docs.to_string())
325 }
326 },
327 serde_attrs: Vec::new(),
328 serde_flags: Vec::new(),
329 codegen_attrs: Vec::new(),
330 codegen_flags: Vec::new(),
331 value,
332 }
333 }
334}
335
336#[derive(Debug, Serialize)]
337#[cfg_attr(feature = "generate", derive(serde::Deserialize))]
338pub enum EnumRepresentation {
339 External,
342 Untagged,
344 Tagged {
347 tag: Spanned<String>,
348 content: Option<Spanned<String>>,
349 },
350}
351
352impl<T> Named<T> {
353 pub fn serialize_name(&self) -> &str {
354 self.serde_attrs
355 .iter()
356 .filter_map(|attr| {
357 if attr.value.0.value == "rename" {
358 Some(&attr.value.1.value)
359 } else {
360 None
361 }
362 })
363 .last()
364 .unwrap_or(&self.rust_ident.value)
365 }
366}