serde_arrays/
serializable.rs

1// Copyright 2021 Travis Veazey
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// https://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// https://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8use crate::wrapper::ArrayWrap;
9use serde::ser::{Serialize, SerializeTuple, Serializer};
10#[cfg(feature = "alloc")]
11extern crate alloc;
12#[cfg(feature = "alloc")]
13use alloc::vec::Vec;
14
15/// Trait for types serializable using `serde_arrays`
16///
17/// In order to serialize data using this crate, the type needs to implement this trait. While this
18/// approach has limitations in what can be supported (namely it limits support to only those types
19/// this trait is explicitly implemented on), the trade off is a significant increase in ergonomics.
20///
21/// If the greater flexibility lost by this approach is needed, see [`serde_with`][serde_with].
22///
23/// [serde_with]: https://crates.io/crates/serde_with/
24pub trait Serializable<T: Serialize, const N: usize> {
25    fn serialize<S>(&self, ser: S) -> Result<S::Ok, S::Error>
26    where
27        S: Serializer;
28}
29
30impl<T: Serialize, const N: usize, const M: usize> Serializable<T, N> for [[T; N]; M] {
31    fn serialize<S>(&self, ser: S) -> Result<S::Ok, S::Error>
32    where
33        S: Serializer,
34    {
35        // Fixed-length structures, including arrays, are supported in Serde as tuples
36        // See: https://serde.rs/impl-serialize.html#serializing-a-tuple
37        let mut s = ser.serialize_tuple(N)?;
38        for item in self {
39            let wrapped = ArrayWrap::new(item);
40            s.serialize_element(&wrapped)?;
41        }
42        s.end()
43    }
44}
45
46#[cfg(feature = "alloc")]
47impl<T: Serialize, const N: usize> Serializable<T, N> for Vec<[T; N]> {
48    fn serialize<S>(&self, ser: S) -> Result<S::Ok, S::Error>
49    where
50        S: Serializer,
51    {
52        use serde::ser::SerializeSeq;
53        let mut s = ser.serialize_seq(Some(self.len()))?;
54        for item in self {
55            let wrapped = ArrayWrap::new(item);
56            s.serialize_element(&wrapped)?;
57        }
58        s.end()
59    }
60}
61
62impl<T: Serialize, const N: usize> Serializable<T, N> for [T; N] {
63    fn serialize<S>(&self, ser: S) -> Result<S::Ok, S::Error>
64    where
65        S: Serializer,
66    {
67        serialize_as_tuple(self, ser)
68    }
69}
70
71/// Serialize an array
72///
73/// In Serde arrays (and other fixed-length structures) are supported as tuples
74fn serialize_as_tuple<S, T, const N: usize>(data: &[T; N], ser: S) -> Result<S::Ok, S::Error>
75where
76    S: Serializer,
77    T: Serialize,
78{
79    // See: https://serde.rs/impl-serialize.html#serializing-a-tuple
80    let mut s = ser.serialize_tuple(N)?;
81    for item in data {
82        s.serialize_element(item)?;
83    }
84    s.end()
85}