1use ::serde::{ser, Deserialize, Deserializer, Serialize, Serializer};
2use chrono::{DateTime, NaiveDateTime, Utc};
3use serde::de;
4use serde::de::Visitor;
5
6use std::fmt;
7use std::str::FromStr;
8
9use prost::Message;
10
11#[derive(Clone, PartialEq, Eq, ::prost::Message, schemars::JsonSchema)]
12pub struct Timestamp {
13 #[prost(int64, tag = "1")]
17 pub seconds: i64,
18 #[prost(int32, tag = "2")]
23 pub nanos: i32,
24}
25
26impl Serialize for Timestamp {
27 fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
28 where
29 S: Serializer,
30 {
31 let mut ts = prost_types::Timestamp {
32 seconds: self.seconds,
33 nanos: self.nanos,
34 };
35 ts.normalize();
36 let dt = NaiveDateTime::from_timestamp(ts.seconds, ts.nanos as u32);
37 let dt: DateTime<Utc> = DateTime::from_utc(dt, Utc);
38 serializer.serialize_str(format!("{:?}", dt).as_str())
39 }
40}
41
42impl<'de> Deserialize<'de> for Timestamp {
43 fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
44 where
45 D: Deserializer<'de>,
46 {
47 struct TimestampVisitor;
48
49 impl<'de> Visitor<'de> for TimestampVisitor {
50 type Value = Timestamp;
51
52 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
53 formatter.write_str("Timestamp in RFC3339 format")
54 }
55
56 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
57 where
58 E: de::Error,
59 {
60 let utc: DateTime<Utc> = chrono::DateTime::from_str(value).map_err(|err| {
61 serde::de::Error::custom(format!(
62 "Failed to parse {} as datetime: {:?}",
63 value, err
64 ))
65 })?;
66 let ts = Timestamp::from(utc);
67 Ok(ts)
68 }
69 }
70 deserializer.deserialize_str(TimestampVisitor)
71 }
72}
73
74impl From<DateTime<Utc>> for Timestamp {
75 fn from(dt: DateTime<Utc>) -> Self {
76 Timestamp {
77 seconds: dt.timestamp(),
78 nanos: dt.timestamp_subsec_nanos() as i32,
79 }
80 }
81}
82#[derive(Clone, PartialEq, Eq, ::prost::Message, schemars::JsonSchema)]
83pub struct Duration {
84 #[prost(int64, tag = "1")]
88 pub seconds: i64,
89 #[prost(int32, tag = "2")]
96 pub nanos: i32,
97}
98
99impl Serialize for Duration {
100 fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
101 where
102 S: Serializer,
103 {
104 let mut d = prost_types::Duration::from(self.to_owned());
105 d.normalize();
106
107 serializer.serialize_str(d.to_string().as_str())
108 }
109}
110
111impl<'de> Deserialize<'de> for Duration {
112 fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
113 where
114 D: Deserializer<'de>,
115 {
116 struct DurationVisitor;
117
118 impl<'de> Visitor<'de> for DurationVisitor {
119 type Value = Duration;
120
121 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
122 formatter.write_str("Timestamp in RFC3339 format")
123 }
124
125 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
126 where
127 E: de::Error,
128 {
129 value
130 .parse::<prost_types::Duration>()
131 .map(Into::into)
132 .map_err(de::Error::custom)
133 }
134 }
135 deserializer.deserialize_str(DurationVisitor)
136 }
137}
138
139#[derive(Clone, PartialEq, Eq, ::prost::Message, schemars::JsonSchema)]
140pub struct Any {
141 #[prost(string, tag = "1")]
170 pub type_url: ::prost::alloc::string::String,
171 #[prost(bytes = "vec", tag = "2")]
173 pub value: ::prost::alloc::vec::Vec<u8>,
174}
175
176macro_rules! expand_as_any {
177 ($($ty:path,)*) => {
178
179
180 impl Serialize for Any {
181 fn serialize<S>(
182 &self,
183 serializer: S,
184 ) -> Result<<S as ::serde::Serializer>::Ok, <S as ::serde::Serializer>::Error>
185 where
186 S: ::serde::Serializer,
187 {
188 $(
189 if self.type_url == <$ty>::TYPE_URL {
190 let value: Result<$ty, <S as ::serde::Serializer>::Error> =
191 prost::Message::decode(self.value.as_slice()).map_err(ser::Error::custom);
192
193 if let Ok(value) = value {
194 return value.serialize(serializer);
195 }
196 }
197 )*
198
199 Err(serde::ser::Error::custom(
200 "data did not match any type that supports serialization as `Any`",
201 ))
202 }
203 }
204
205 impl<'de> Deserialize<'de> for Any {
206 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
207 where
208 D: serde::Deserializer<'de>,
209 {
210 let value = match serde_cw_value::Value::deserialize(deserializer) {
211 Ok(value) => value,
212 Err(err) => {
213 return Err(err);
214 }
215 };
216
217 let type_url = if let serde_cw_value::Value::Map(m) = value.clone() {
219 m.get(&serde_cw_value::Value::String("@type".to_string()))
220 .map(|t| match t.to_owned() {
221 serde_cw_value::Value::String(s) => Ok(s),
222 _ => Err(serde::de::Error::custom("type_url must be String")),
223 })
224 .transpose()
225 } else {
226 Err(serde::de::Error::custom("data must have map structure"))
227 }?;
228
229 match type_url {
230 Some(t) => {
232 $(
233 if t == <$ty>::TYPE_URL {
234 return <$ty>::deserialize(
235 serde_cw_value::ValueDeserializer::<serde_cw_value::DeserializerError>::new(
236 value.clone(),
237 ),
238 )
239 .map(|v| Any {
240 type_url: <$ty>::TYPE_URL.to_string(),
241 value: v.encode_to_vec(),
242 })
243 .map_err(serde::de::Error::custom);
244 }
245 )*
246 }
247 None => {
249 $(
250 if let Ok(v) = <$ty>::deserialize(
251 serde_cw_value::ValueDeserializer::<serde_cw_value::DeserializerError>::new(
252 value.clone(),
253 ),
254 ) {
255 return Ok(Any {
256 type_url: <$ty>::TYPE_URL.to_string(),
257 value: v.encode_to_vec(),
258 });
259 }
260 )*
261 }
262 };
263
264 Err(serde::de::Error::custom(
265 "data did not match any type that supports deserialization as `Any`",
266 ))
267 }
268 }
269
270 $(
271 impl TryFrom<Any> for $ty {
272 type Error = prost::DecodeError;
273
274 fn try_from(value: Any) -> Result<Self, Self::Error> {
275 prost::Message::decode(value.value.as_slice())
276 }
277 }
278 )*
279 };
280}
281
282expand_as_any!();
287
288macro_rules! impl_prost_types_exact_conversion {
289 ($t:ident | $($arg:ident),*) => {
290 impl From<$t> for prost_types::$t {
291 fn from(src: $t) -> Self {
292 prost_types::$t {
293 $(
294 $arg: src.$arg,
295 )*
296 }
297 }
298 }
299
300 impl From<prost_types::$t> for $t {
301 fn from(src: prost_types::$t) -> Self {
302 $t {
303 $(
304 $arg: src.$arg,
305 )*
306 }
307 }
308 }
309 };
310}
311
312impl_prost_types_exact_conversion! { Timestamp | seconds, nanos }
313impl_prost_types_exact_conversion! { Duration | seconds, nanos }
314impl_prost_types_exact_conversion! { Any | type_url, value }
315
316impl From<cosmwasm_std::Coin> for crate::types::cosmos::base::v1beta1::Coin {
317 fn from(cosmwasm_std::Coin { denom, amount }: cosmwasm_std::Coin) -> Self {
318 crate::types::cosmos::base::v1beta1::Coin {
319 denom,
320 amount: amount.into(),
321 }
322 }
323}
324
325impl TryFrom<crate::types::cosmos::base::v1beta1::Coin> for cosmwasm_std::Coin {
326 type Error = cosmwasm_std::StdError;
327
328 fn try_from(
329 crate::types::cosmos::base::v1beta1::Coin { denom, amount }: crate::types::cosmos::base::v1beta1::Coin,
330 ) -> cosmwasm_std::StdResult<Self> {
331 Ok(cosmwasm_std::Coin {
332 denom,
333 amount: amount.parse()?,
334 })
335 }
336}