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
125#[cfg(target_endian = "little")]
126fn fixed_primitive_byte_size<T: CandidType>() -> Option<usize> {
127 use super::internal::TypeId;
128 let tid = TypeId::of::<T>();
129 if tid == TypeId::of::<bool>() || tid == TypeId::of::<u8>() || tid == TypeId::of::<i8>() {
130 Some(1)
131 } else if tid == TypeId::of::<u16>() || tid == TypeId::of::<i16>() {
132 Some(2)
133 } else if tid == TypeId::of::<u32>() || tid == TypeId::of::<i32>() || tid == TypeId::of::<f32>()
134 {
135 Some(4)
136 } else if tid == TypeId::of::<u64>() || tid == TypeId::of::<i64>() || tid == TypeId::of::<f64>()
137 {
138 Some(8)
139 } else {
140 None
141 }
142}
143
144impl<T> CandidType for [T]
145where
146 T: CandidType,
147{
148 fn _ty() -> Type {
149 TypeInner::Vec(T::ty()).into()
150 }
151 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
152 where
153 S: Serializer,
154 {
155 let mut ser = serializer.serialize_vec(self.len())?;
156 #[cfg(target_endian = "little")]
157 if let Some(element_size) = fixed_primitive_byte_size::<T>() {
158 let bytes = unsafe {
159 std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len() * element_size)
160 };
161 if Compound::try_write_raw_elements(&mut ser, bytes)? {
162 return Ok(());
163 }
164 }
165 for e in self {
166 Compound::serialize_element(&mut ser, &e)?;
167 }
168 Ok(())
169 }
170}
171#[cfg_attr(docsrs, doc(cfg(feature = "serde_bytes")))]
172#[cfg(feature = "serde_bytes")]
173impl CandidType for serde_bytes::ByteBuf {
174 fn _ty() -> Type {
175 TypeInner::Vec(TypeInner::Nat8.into()).into()
176 }
177 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
178 where
179 S: Serializer,
180 {
181 serializer.serialize_blob(self.as_slice())
182 }
183}
184#[cfg_attr(docsrs, doc(cfg(feature = "serde_bytes")))]
185#[cfg(feature = "serde_bytes")]
186impl CandidType for serde_bytes::Bytes {
187 fn _ty() -> Type {
188 TypeInner::Vec(TypeInner::Nat8.into()).into()
189 }
190 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
191 where
192 S: Serializer,
193 {
194 serializer.serialize_blob(self)
195 }
196}
197#[cfg_attr(docsrs, doc(cfg(feature = "serde_bytes")))]
198#[cfg(feature = "serde_bytes")]
199impl<const N: usize> CandidType for serde_bytes::ByteArray<N> {
200 fn _ty() -> Type {
201 TypeInner::Vec(TypeInner::Nat8.into()).into()
202 }
203 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
204 where
205 S: Serializer,
206 {
207 serializer.serialize_blob(self.as_slice())
208 }
209}
210
211macro_rules! map_impl {
212 ($ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound:ident)* >) => {
213 impl<K, V $(, $typaram)*> CandidType for $ty<K, V $(, $typaram)*>
214 where
215 K: CandidType $(+ $kbound1 $(+ $kbound2)*)*,
216 V: CandidType,
217 $($typaram: $bound,)*
218 {
219 fn _ty() -> Type {
220 let tuple = TypeInner::Record(vec![
221 Field {
222 id: Label::Id(0).into(),
223 ty: K::ty(),
224 },
225 Field {
226 id: Label::Id(1).into(),
227 ty: V::ty(),
228 },
229 ]).into();
230 TypeInner::Vec(tuple).into()
231 }
232 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
233 where
234 S: Serializer,
235 {
236 let mut ser = serializer.serialize_vec(self.len())?;
237 for e in self.iter() {
238 Compound::serialize_element(&mut ser, &e)?;
239 }
240 Ok(())
241 }
242 }
243 }
244}
245macro_rules! seq_impl {
246 ($ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)* $(, $typaram:ident : $bound:ident)* >) => {
247 impl<K $(, $typaram)*> CandidType for $ty<K $(, $typaram)*>
248 where
249 K: CandidType $(+ $kbound1 $(+ $kbound2)*)*,
250 $($typaram: $bound,)*
251 {
252 fn _ty() -> Type {
253 TypeInner::Vec(K::ty()).into()
254 }
255 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
256 where
257 S: Serializer,
258 {
259 let mut ser = serializer.serialize_vec(self.len())?;
260 for e in self.iter() {
261 Compound::serialize_element(&mut ser, &e)?;
262 }
263 Ok(())
264 }
265 }
266 }
267}
268use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
269use std::hash::{BuildHasher, Hash};
270map_impl!(BTreeMap<K: Ord, V>);
271map_impl!(HashMap<K: Eq + Hash, V, H: BuildHasher>);
272
273impl<K: CandidType> CandidType for Vec<K> {
274 fn _ty() -> Type {
275 TypeInner::Vec(K::ty()).into()
276 }
277 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
278 where
279 S: Serializer,
280 {
281 self.as_slice().idl_serialize(serializer)
282 }
283}
284seq_impl!(VecDeque<K>);
285seq_impl!(LinkedList<K>);
286seq_impl!(BinaryHeap<K: Ord>);
287seq_impl!(BTreeSet<K: Ord>);
288seq_impl!(HashSet<K: Eq + Hash, H: BuildHasher>);
289
290impl<T: CandidType, const N: usize> CandidType for [T; N] {
291 fn _ty() -> Type {
292 TypeInner::Vec(T::ty()).into()
293 }
294 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
295 where
296 S: Serializer,
297 {
298 self.as_slice().idl_serialize(serializer)
299 }
300}
301
302impl<T, E> CandidType for Result<T, E>
303where
304 T: CandidType,
305 E: CandidType,
306{
307 fn _ty() -> Type {
308 TypeInner::Variant(vec![
309 Field {
311 id: Label::Named("Ok".to_owned()).into(),
312 ty: T::ty(),
313 },
314 Field {
315 id: Label::Named("Err".to_owned()).into(),
316 ty: E::ty(),
317 },
318 ])
319 .into()
320 }
321 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
322 where
323 S: Serializer,
324 {
325 match *self {
326 Result::Ok(ref v) => {
327 let mut ser = serializer.serialize_variant(0)?;
328 Compound::serialize_element(&mut ser, v)
329 }
330 Result::Err(ref e) => {
331 let mut ser = serializer.serialize_variant(1)?;
332 Compound::serialize_element(&mut ser, e)
333 }
334 }
335 }
336}
337
338impl<T> CandidType for Box<T>
339where
340 T: ?Sized + CandidType,
341{
342 fn _ty() -> Type {
343 T::ty()
344 }
345 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
346 where
347 S: Serializer,
348 {
349 (**self).idl_serialize(serializer)
350 }
351}
352
353impl<T> CandidType for std::cmp::Reverse<T>
354where
355 T: CandidType,
356{
357 fn _ty() -> Type {
358 T::ty()
359 }
360 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
361 where
362 S: Serializer,
363 {
364 self.0.idl_serialize(serializer)
365 }
366}
367
368impl<T> CandidType for &T
369where
370 T: ?Sized + CandidType,
371{
372 fn id() -> TypeId {
373 TypeId::of::<&T>()
374 } fn _ty() -> Type {
376 T::ty()
377 }
378 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
379 where
380 S: Serializer,
381 {
382 (**self).idl_serialize(serializer)
383 }
384}
385impl<T> CandidType for &mut T
386where
387 T: ?Sized + CandidType,
388{
389 fn id() -> TypeId {
390 TypeId::of::<&T>()
391 } fn _ty() -> Type {
393 T::ty()
394 }
395 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
396 where
397 S: Serializer,
398 {
399 (**self).idl_serialize(serializer)
400 }
401}
402
403impl<T> CandidType for std::borrow::Cow<'_, T>
404where
405 T: ?Sized + CandidType + ToOwned,
406{
407 fn _ty() -> Type {
408 T::ty()
409 }
410 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
411 where
412 S: Serializer,
413 {
414 (**self).idl_serialize(serializer)
415 }
416}
417
418impl<T> CandidType for std::cell::Cell<T>
419where
420 T: CandidType + Copy,
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.get().idl_serialize(serializer)
430 }
431}
432
433impl<T> CandidType for std::cell::RefCell<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 use serde::ser::Error;
445 match self.try_borrow() {
446 Ok(v) => v.idl_serialize(serializer),
447 Err(_) => Err(S::Error::custom("already mutably borrowed")),
448 }
449 }
450}
451
452impl<T> CandidType for std::rc::Rc<T>
453where
454 T: CandidType,
455{
456 fn _ty() -> Type {
457 T::ty()
458 }
459 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
460 where
461 S: Serializer,
462 {
463 self.as_ref().idl_serialize(serializer)
464 }
465}
466
467impl<T> CandidType for std::sync::Arc<T>
468where
469 T: CandidType,
470{
471 fn _ty() -> Type {
472 T::ty()
473 }
474 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
475 where
476 S: Serializer,
477 {
478 self.as_ref().idl_serialize(serializer)
479 }
480}
481
482impl<T> CandidType for std::marker::PhantomData<T>
483where
484 T: CandidType,
485{
486 fn _ty() -> Type {
487 T::ty()
488 }
489 fn idl_serialize<S>(&self, _: S) -> Result<(), S::Error>
490 where
491 S: Serializer,
492 {
493 use serde::ser::Error;
494 Err(S::Error::custom("`PhantomData` cannot be serialized"))
495 }
496}
497
498macro_rules! tuple_impls {
499 ($($len:expr => ($($n:tt $name:ident)+))+) => {
500 $(
501 impl<$($name),+> CandidType for ($($name,)+)
502 where
503 $($name: CandidType,)+
504 {
505 fn _ty() -> Type {
506 TypeInner::Record(vec![
507 $(Field{ id: Label::Id($n).into(), ty: $name::ty() },)+
508 ]).into()
509 }
510 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
511 where S: Serializer,
512 {
513 let mut ser = serializer.serialize_struct()?;
514 $(
515 Compound::serialize_element(&mut ser, &self.$n)?;
516 )+
517 Ok(())
518 }
519 }
520 )+
521 }
522}
523
524tuple_impls! {
525 1 => (0 T0)
526 2 => (0 T0 1 T1)
527 3 => (0 T0 1 T1 2 T2)
528 4 => (0 T0 1 T1 2 T2 3 T3)
529 5 => (0 T0 1 T1 2 T2 3 T3 4 T4)
530 6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
531 7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
532 8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
533 9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
534 10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
535 11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10)
536 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)
537 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)
538 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)
539 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)
540 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)
541}
542
543impl CandidType for std::time::SystemTime {
544 fn _ty() -> Type {
545 TypeInner::Record(vec![
546 Field {
547 id: Label::Named("nanos_since_epoch".to_owned()).into(),
548 ty: u32::ty(),
549 },
550 Field {
551 id: Label::Named("secs_since_epoch".to_owned()).into(),
552 ty: u64::ty(),
553 },
554 ])
555 .into()
556 }
557 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
558 where
559 S: Serializer,
560 {
561 use serde::ser::Error;
562
563 let duration_since_epoch = self
564 .duration_since(std::time::UNIX_EPOCH)
565 .map_err(|_| S::Error::custom("SystemTime must be later than UNIX_EPOCH"))?;
566
567 let secs: u64 = duration_since_epoch.as_secs();
568 let nanos: u32 = duration_since_epoch.subsec_nanos();
569
570 let mut ser = serializer.serialize_struct()?;
571 ser.serialize_element(&nanos)?;
572 ser.serialize_element(&secs)?;
573
574 Ok(())
575 }
576}
577
578impl CandidType for std::time::Duration {
579 fn _ty() -> Type {
580 TypeInner::Record(vec![
581 Field {
582 id: Label::Named("secs".to_owned()).into(),
583 ty: u64::ty(),
584 },
585 Field {
586 id: Label::Named("nanos".to_owned()).into(),
587 ty: u32::ty(),
588 },
589 ])
590 .into()
591 }
592 fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
593 where
594 S: Serializer,
595 {
596 let secs: u64 = self.as_secs();
597 let nanos: u32 = self.subsec_nanos();
598
599 let mut ser = serializer.serialize_struct()?;
600 ser.serialize_element(&secs)?;
601 ser.serialize_element(&nanos)?;
602
603 Ok(())
604 }
605}