]> git.proxmox.com Git - rustc.git/blob - vendor/time-macros/src/serde_format_description.rs
New upstream version 1.68.2+dfsg1
[rustc.git] / vendor / time-macros / src / serde_format_description.rs
1 use proc_macro::{Ident, TokenStream, TokenTree};
2
3 pub(crate) fn build(
4 mod_name: Ident,
5 ty: TokenTree,
6 format: TokenStream,
7 raw_format_string: Option<String>,
8 ) -> TokenStream {
9 let ty_s = &*ty.to_string();
10
11 let format_description_display = raw_format_string.unwrap_or_else(|| format.to_string());
12
13 let visitor = if cfg!(feature = "parsing") {
14 quote! {
15 struct Visitor;
16 struct OptionVisitor;
17
18 impl<'a> ::serde::de::Visitor<'a> for Visitor {
19 type Value = __TimeSerdeType;
20
21 fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
22 write!(
23 f,
24 concat!(
25 "a(n) `",
26 #(ty_s),
27 "` in the format \"{}\"",
28 ),
29 #(format_description_display.as_str())
30 )
31 }
32
33 fn visit_str<E: ::serde::de::Error>(
34 self,
35 value: &str
36 ) -> Result<__TimeSerdeType, E> {
37 __TimeSerdeType::parse(value, &DESCRIPTION).map_err(E::custom)
38 }
39 }
40
41 impl<'a> ::serde::de::Visitor<'a> for OptionVisitor {
42 type Value = Option<__TimeSerdeType>;
43
44 fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
45 write!(
46 f,
47 concat!(
48 "an `Option<",
49 #(ty_s),
50 ">` in the format \"{}\"",
51 ),
52 #(format_description_display.as_str())
53 )
54 }
55
56 fn visit_some<D: ::serde::de::Deserializer<'a>>(
57 self,
58 deserializer: D
59 ) -> Result<Option<__TimeSerdeType>, D::Error> {
60 deserializer
61 .deserialize_any(Visitor)
62 .map(Some)
63 }
64
65 fn visit_none<E: ::serde::de::Error>(
66 self
67 ) -> Result<Option<__TimeSerdeType>, E> {
68 Ok(None)
69 }
70 }
71 }
72 } else {
73 quote!()
74 };
75
76 let serialize_primary = if cfg!(feature = "formatting") {
77 quote! {
78 pub fn serialize<S: ::serde::Serializer>(
79 datetime: &__TimeSerdeType,
80 serializer: S,
81 ) -> Result<S::Ok, S::Error> {
82 use ::serde::Serialize;
83 datetime
84 .format(&DESCRIPTION)
85 .map_err(::time::error::Format::into_invalid_serde_value::<S>)?
86 .serialize(serializer)
87 }
88 }
89 } else {
90 quote!()
91 };
92
93 let deserialize_primary = if cfg!(feature = "parsing") {
94 quote! {
95 pub fn deserialize<'a, D: ::serde::Deserializer<'a>>(
96 deserializer: D
97 ) -> Result<__TimeSerdeType, D::Error> {
98 use ::serde::Deserialize;
99 deserializer.deserialize_any(Visitor)
100 }
101 }
102 } else {
103 quote!()
104 };
105
106 let serialize_option = if cfg!(feature = "formatting") {
107 quote! {
108 pub fn serialize<S: ::serde::Serializer>(
109 option: &Option<__TimeSerdeType>,
110 serializer: S,
111 ) -> Result<S::Ok, S::Error> {
112 use ::serde::Serialize;
113 option.map(|datetime| datetime.format(&DESCRIPTION))
114 .transpose()
115 .map_err(::time::error::Format::into_invalid_serde_value::<S>)?
116 .serialize(serializer)
117 }
118 }
119 } else {
120 quote!()
121 };
122
123 let deserialize_option = if cfg!(feature = "parsing") {
124 quote! {
125 pub fn deserialize<'a, D: ::serde::Deserializer<'a>>(
126 deserializer: D
127 ) -> Result<Option<__TimeSerdeType>, D::Error> {
128 use ::serde::Deserialize;
129 deserializer.deserialize_option(OptionVisitor)
130 }
131 }
132 } else {
133 quote!()
134 };
135
136 let deserialize_option_imports = if cfg!(feature = "parsing") {
137 quote! {
138 use super::{OptionVisitor, Visitor};
139 }
140 } else {
141 quote!()
142 };
143
144 quote! {
145 mod #(mod_name) {
146 use ::time::#(ty) as __TimeSerdeType;
147
148 const DESCRIPTION: &[::time::format_description::FormatItem<'_>] = #S(format);
149
150 #S(visitor)
151 #S(serialize_primary)
152 #S(deserialize_primary)
153
154 pub(super) mod option {
155 use super::{DESCRIPTION, __TimeSerdeType};
156 #S(deserialize_option_imports)
157
158 #S(serialize_option)
159 #S(deserialize_option)
160 }
161 }
162 }
163 }