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
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use syn::{spanned::Spanned, Error, Fields, ItemStruct, Result};
pub fn derive(input: ItemStruct) -> Result<TokenStream> {
match input.fields {
Fields::Named(fields) => {
let (name, vis, generics) = (input.ident, input.vis, input.generics);
let serializers = fields.named.into_iter().map(|f| {
let name = f.ident;
quote! {
s.serialize_field(concat!(stringify!(#name), "_x"), &self.data.#name[0])?;
s.serialize_field(concat!(stringify!(#name), "_y"), &self.data.#name[1])?;
s.serialize_field(concat!(stringify!(#name), "_z"), &self.data.#name[2])?;
}
});
let fields_count = serializers.len() * 3 + 1;
let timescale_ident = format_ident!("Timescale{}", name);
Ok(quote! {
#[doc(hidden)]
#[derive(Debug)]
#vis struct #timescale_ident #generics {
pub time: f64,
pub data: #name #generics,
}
#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const _: () = {
extern crate serde as _serde;
extern crate timescale as _timescale;
use _serde::ser::SerializeStruct;
use _timescale::ToTimescale;
#[automatically_derived]
impl _serde::Serialize for #timescale_ident {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: _serde::Serializer,
{
let mut s = serializer.serialize_struct(stringify!(#name), #fields_count)?;
s.serialize_field("time", &self.time)?;
#(#serializers)*
s.end()
}
}
#[automatically_derived]
impl ToTimescale for #name {
type Timescale = #timescale_ident;
fn with_time(self, time: f64) -> Self::Timescale {
#timescale_ident {
time,
data: self
}
}
}
};
})
}
_ => Err(Error::new(input.span(), "struct must have named fields")),
}
}