1use super::internal::*;
2use super::{CandidType, Compound, Serializer};
3
4macro_rules! primitive_impl {
5 ($t:ty, $id:tt, $method:ident $($cast:tt)*) => {
6 impl CandidType for $t {
7 fn _ty() -> Type { TypeInner::$id.into() }
8 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error> where S: Serializer {
9 serializer.$method(*self $($cast)*)
10 }
11 }
12 };
13}
14
15primitive_impl!((), Null, serialize_null);
16primitive_impl!(bool, Bool, serialize_bool);
17
18primitive_impl!(i8, Int8, serialize_int8);
19primitive_impl!(i16, Int16, serialize_int16);
20primitive_impl!(i32, Int32, serialize_int32);
21primitive_impl!(i64, Int64, serialize_int64);
22
23primitive_impl!(u8, Nat8, serialize_nat8);
24primitive_impl!(u16, Nat16, serialize_nat16);
25primitive_impl!(u32, Nat32, serialize_nat32);
26primitive_impl!(u64, Nat64, serialize_nat64);
27
28primitive_impl!(f32, Float32, serialize_float32);
29primitive_impl!(f64, Float64, serialize_float64);
30
31primitive_impl!(isize, Int64, serialize_int64 as i64);
34primitive_impl!(usize, Nat64, serialize_nat64 as u64);
35
36impl CandidType for i128 {
37 fn _ty() -> Type {
38 TypeInner::Int.into()
39 }
40 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
41 where
42 S: Serializer,
43 {
44 serializer.serialize_i128(*self)
45 }
46}
47impl CandidType for u128 {
48 fn _ty() -> Type {
49 TypeInner::Nat.into()
50 }
51 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
52 where
53 S: Serializer,
54 {
55 serializer.serialize_u128(*self)
56 }
57}
58
59impl CandidType for String {
60 fn _ty() -> Type {
61 TypeInner::Text.into()
62 }
63 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
64 where
65 S: Serializer,
66 {
67 serializer.serialize_text(self)
68 }
69}
70impl CandidType for str {
71 fn _ty() -> Type {
72 TypeInner::Text.into()
73 }
74 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
75 where
76 S: Serializer,
77 {
78 serializer.serialize_text(self)
79 }
80}
81
82impl CandidType for std::path::Path {
83 fn _ty() -> Type {
84 TypeInner::Text.into()
85 }
86 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
87 where
88 S: Serializer,
89 {
90 use serde::ser::Error;
91 match self.to_str() {
92 Some(s) => s.idl_serialize(serializer),
93 None => Err(S::Error::custom("path contains invalid UTF-8 characters")),
94 }
95 }
96}
97
98impl CandidType for std::path::PathBuf {
99 fn _ty() -> Type {
100 TypeInner::Text.into()
101 }
102 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
103 where
104 S: Serializer,
105 {
106 self.as_path().idl_serialize(serializer)
107 }
108}
109
110impl<T: Sized> CandidType for Option<T>
111where
112 T: CandidType,
113{
114 fn _ty() -> Type {
115 TypeInner::Opt(T::ty()).into()
116 }
117 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
118 where
119 S: Serializer,
120 {
121 serializer.serialize_option(self.as_ref())
122 }
123}
124
125impl<T> CandidType for [T]
126where
127 T: CandidType,
128{
129 fn _ty() -> Type {
130 TypeInner::Vec(T::ty()).into()
131 }
132 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
133 where
134 S: Serializer,
135 {
136 let mut ser = serializer.serialize_vec(self.len())?;
137 for e in self {
138 Compound::serialize_element(&mut ser, &e)?;
139 }
140 Ok(())
141 }
142}
143#[cfg_attr(docsrs, doc(cfg(feature = "serde_bytes")))]
144#[cfg(feature = "serde_bytes")]
145impl CandidType for serde_bytes::ByteBuf {
146 fn _ty() -> Type {
147 TypeInner::Vec(TypeInner::Nat8.into()).into()
148 }
149 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
150 where
151 S: Serializer,
152 {
153 serializer.serialize_blob(self.as_slice())
154 }
155}
156#[cfg_attr(docsrs, doc(cfg(feature = "serde_bytes")))]
157#[cfg(feature = "serde_bytes")]
158impl CandidType for serde_bytes::Bytes {
159 fn _ty() -> Type {
160 TypeInner::Vec(TypeInner::Nat8.into()).into()
161 }
162 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
163 where
164 S: Serializer,
165 {
166 serializer.serialize_blob(self)
167 }
168}
169#[cfg_attr(docsrs, doc(cfg(feature = "serde_bytes")))]
170#[cfg(feature = "serde_bytes")]
171impl<const N: usize> CandidType for serde_bytes::ByteArray<N> {
172 fn _ty() -> Type {
173 TypeInner::Vec(TypeInner::Nat8.into()).into()
174 }
175 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
176 where
177 S: Serializer,
178 {
179 serializer.serialize_blob(self.as_slice())
180 }
181}
182
183macro_rules! map_impl {
184 ($ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound:ident)* >) => {
185 impl<K, V $(, $typaram)*> CandidType for $ty<K, V $(, $typaram)*>
186 where
187 K: CandidType $(+ $kbound1 $(+ $kbound2)*)*,
188 V: CandidType,
189 $($typaram: $bound,)*
190 {
191 fn _ty() -> Type {
192 let tuple = TypeInner::Record(vec![
193 Field {
194 id: Label::Id(0).into(),
195 ty: K::ty(),
196 },
197 Field {
198 id: Label::Id(1).into(),
199 ty: V::ty(),
200 },
201 ]).into();
202 TypeInner::Vec(tuple).into()
203 }
204 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
205 where
206 S: Serializer,
207 {
208 let mut ser = serializer.serialize_vec(self.len())?;
209 for e in self.iter() {
210 Compound::serialize_element(&mut ser, &e)?;
211 }
212 Ok(())
213 }
214 }
215 }
216}
217macro_rules! seq_impl {
218 ($ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)* $(, $typaram:ident : $bound:ident)* >) => {
219 impl<K $(, $typaram)*> CandidType for $ty<K $(, $typaram)*>
220 where
221 K: CandidType $(+ $kbound1 $(+ $kbound2)*)*,
222 $($typaram: $bound,)*
223 {
224 fn _ty() -> Type {
225 TypeInner::Vec(K::ty()).into()
226 }
227 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
228 where
229 S: Serializer,
230 {
231 let mut ser = serializer.serialize_vec(self.len())?;
232 for e in self.iter() {
233 Compound::serialize_element(&mut ser, &e)?;
234 }
235 Ok(())
236 }
237 }
238 }
239}
240use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
241use std::hash::{BuildHasher, Hash};
242map_impl!(BTreeMap<K: Ord, V>);
243map_impl!(HashMap<K: Eq + Hash, V, H: BuildHasher>);
244
245seq_impl!(Vec<K>);
246seq_impl!(VecDeque<K>);
247seq_impl!(LinkedList<K>);
248seq_impl!(BinaryHeap<K: Ord>);
249seq_impl!(BTreeSet<K: Ord>);
250seq_impl!(HashSet<K: Eq + Hash, H: BuildHasher>);
251
252impl<T: CandidType, const N: usize> CandidType for [T; N] {
253 fn _ty() -> Type {
254 TypeInner::Vec(T::ty()).into()
255 }
256 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
257 where
258 S: Serializer,
259 {
260 let mut ser = serializer.serialize_vec(N)?;
261 for e in self {
262 Compound::serialize_element(&mut ser, &e)?;
263 }
264 Ok(())
265 }
266}
267
268impl<T, E> CandidType for Result<T, E>
269where
270 T: CandidType,
271 E: CandidType,
272{
273 fn _ty() -> Type {
274 TypeInner::Variant(vec![
275 Field {
277 id: Label::Named("Ok".to_owned()).into(),
278 ty: T::ty(),
279 },
280 Field {
281 id: Label::Named("Err".to_owned()).into(),
282 ty: E::ty(),
283 },
284 ])
285 .into()
286 }
287 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
288 where
289 S: Serializer,
290 {
291 match *self {
292 Result::Ok(ref v) => {
293 let mut ser = serializer.serialize_variant(0)?;
294 Compound::serialize_element(&mut ser, v)
295 }
296 Result::Err(ref e) => {
297 let mut ser = serializer.serialize_variant(1)?;
298 Compound::serialize_element(&mut ser, e)
299 }
300 }
301 }
302}
303
304impl<T> CandidType for Box<T>
305where
306 T: ?Sized + CandidType,
307{
308 fn _ty() -> Type {
309 T::ty()
310 }
311 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
312 where
313 S: Serializer,
314 {
315 (**self).idl_serialize(serializer)
316 }
317}
318
319impl<T> CandidType for std::cmp::Reverse<T>
320where
321 T: CandidType,
322{
323 fn _ty() -> Type {
324 T::ty()
325 }
326 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
327 where
328 S: Serializer,
329 {
330 self.0.idl_serialize(serializer)
331 }
332}
333
334impl<T> CandidType for &T
335where
336 T: ?Sized + CandidType,
337{
338 fn id() -> TypeId {
339 TypeId::of::<&T>()
340 } fn _ty() -> Type {
342 T::ty()
343 }
344 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
345 where
346 S: Serializer,
347 {
348 (**self).idl_serialize(serializer)
349 }
350}
351impl<T> CandidType for &mut T
352where
353 T: ?Sized + CandidType,
354{
355 fn id() -> TypeId {
356 TypeId::of::<&T>()
357 } fn _ty() -> Type {
359 T::ty()
360 }
361 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
362 where
363 S: Serializer,
364 {
365 (**self).idl_serialize(serializer)
366 }
367}
368
369impl<T> CandidType for std::borrow::Cow<'_, T>
370where
371 T: ?Sized + CandidType + ToOwned,
372{
373 fn _ty() -> Type {
374 T::ty()
375 }
376 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
377 where
378 S: Serializer,
379 {
380 (**self).idl_serialize(serializer)
381 }
382}
383
384impl<T> CandidType for std::cell::Cell<T>
385where
386 T: CandidType + Copy,
387{
388 fn _ty() -> Type {
389 T::ty()
390 }
391 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
392 where
393 S: Serializer,
394 {
395 self.get().idl_serialize(serializer)
396 }
397}
398
399impl<T> CandidType for std::cell::RefCell<T>
400where
401 T: CandidType,
402{
403 fn _ty() -> Type {
404 T::ty()
405 }
406 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
407 where
408 S: Serializer,
409 {
410 use serde::ser::Error;
411 match self.try_borrow() {
412 Ok(v) => v.idl_serialize(serializer),
413 Err(_) => Err(S::Error::custom("already mutably borrowed")),
414 }
415 }
416}
417
418impl<T> CandidType for std::rc::Rc<T>
419where
420 T: CandidType,
421{
422 fn _ty() -> Type {
423 T::ty()
424 }
425 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
426 where
427 S: Serializer,
428 {
429 self.as_ref().idl_serialize(serializer)
430 }
431}
432
433impl<T> CandidType for std::sync::Arc<T>
434where
435 T: CandidType,
436{
437 fn _ty() -> Type {
438 T::ty()
439 }
440 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
441 where
442 S: Serializer,
443 {
444 self.as_ref().idl_serialize(serializer)
445 }
446}
447
448impl<T> CandidType for std::marker::PhantomData<T>
449where
450 T: CandidType,
451{
452 fn _ty() -> Type {
453 T::ty()
454 }
455 fn idl_serialize<S>(&self, _: S) -> Result<(), S::Error>
456 where
457 S: Serializer,
458 {
459 use serde::ser::Error;
460 Err(S::Error::custom("`PhantomData` cannot be serialized"))
461 }
462}
463
464macro_rules! tuple_impls {
465 ($($len:expr => ($($n:tt $name:ident)+))+) => {
466 $(
467 impl<$($name),+> CandidType for ($($name,)+)
468 where
469 $($name: CandidType,)+
470 {
471 fn _ty() -> Type {
472 TypeInner::Record(vec![
473 $(Field{ id: Label::Id($n).into(), ty: $name::ty() },)+
474 ]).into()
475 }
476 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
477 where S: Serializer,
478 {
479 let mut ser = serializer.serialize_struct()?;
480 $(
481 Compound::serialize_element(&mut ser, &self.$n)?;
482 )+
483 Ok(())
484 }
485 }
486 )+
487 }
488}
489
490tuple_impls! {
491 1 => (0 T0)
492 2 => (0 T0 1 T1)
493 3 => (0 T0 1 T1 2 T2)
494 4 => (0 T0 1 T1 2 T2 3 T3)
495 5 => (0 T0 1 T1 2 T2 3 T3 4 T4)
496 6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
497 7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
498 8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
499 9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
500 10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
501 11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10)
502 12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11)
503 13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12)
504 14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13)
505 15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14)
506 16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15)
507}
508
509impl CandidType for std::time::SystemTime {
510 fn _ty() -> Type {
511 TypeInner::Record(vec![
512 Field {
513 id: Label::Named("nanos_since_epoch".to_owned()).into(),
514 ty: u32::ty(),
515 },
516 Field {
517 id: Label::Named("secs_since_epoch".to_owned()).into(),
518 ty: u64::ty(),
519 },
520 ])
521 .into()
522 }
523 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
524 where
525 S: Serializer,
526 {
527 use serde::ser::Error;
528
529 let duration_since_epoch = self
530 .duration_since(std::time::UNIX_EPOCH)
531 .map_err(|_| S::Error::custom("SystemTime must be later than UNIX_EPOCH"))?;
532
533 let secs: u64 = duration_since_epoch.as_secs();
534 let nanos: u32 = duration_since_epoch.subsec_nanos();
535
536 let mut ser = serializer.serialize_struct()?;
537 ser.serialize_element(&nanos)?;
538 ser.serialize_element(&secs)?;
539
540 Ok(())
541 }
542}
543
544impl CandidType for std::time::Duration {
545 fn _ty() -> Type {
546 TypeInner::Record(vec![
547 Field {
548 id: Label::Named("secs".to_owned()).into(),
549 ty: u64::ty(),
550 },
551 Field {
552 id: Label::Named("nanos".to_owned()).into(),
553 ty: u32::ty(),
554 },
555 ])
556 .into()
557 }
558 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
559 where
560 S: Serializer,
561 {
562 let secs: u64 = self.as_secs();
563 let nanos: u32 = self.subsec_nanos();
564
565 let mut ser = serializer.serialize_struct()?;
566 ser.serialize_element(&secs)?;
567 ser.serialize_element(&nanos)?;
568
569 Ok(())
570 }
571}