stackstring 0.4.4

A fixed-size string
Documentation
use super::String;

use core::convert::TryFrom;
use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error};

impl<const L: usize> Serialize for String<L> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de, const L: usize> Deserialize<'de> for String<L> {
    fn deserialize<D>(deserializer: D) -> Result<String<L>, D::Error>
    where
        D: Deserializer<'de>,
    {
        let s: ::std::string::String = Deserialize::deserialize(deserializer)?;

        Self::try_from(s.as_str())
            .map_err(|e| D::Error::custom(format!("Expected a String with len {}, got {}", L, e)))
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use serde::{Deserialize, Serialize};
    use serde_json::{from_str, to_string};

    #[derive(Serialize, Deserialize)]
    struct S {
        x: String<10>,
    }

    #[test]
    fn deserialize() {
        let json_str = r#"{
            "x": "somestring"
        }"#;

        let s: S = from_str(json_str).unwrap();

        assert_eq!("somestring", s.x);
    }

    #[test]
    fn serialize() {
        let x = String::try_from_str_padded("asd").unwrap();

        let s = S { x };

        let serialized = to_string(&s).unwrap();

        assert_eq!(r#"{"x":"asd       "}"#, serialized);
    }

    // TODO: figure out why &str doesn't work in this case
    #[test]
    fn serialize_deserialize_bincode() {
        let x = String::try_from_str_padded("asd").unwrap();
        let s = S { x };

        let mut buf = Vec::new();
        let bin_config = bincode::config::standard();

        bincode::serde::encode_into_std_write(&s, &mut buf, bin_config).unwrap();

        let s2: S = bincode::serde::decode_from_std_read(&mut buf.as_slice(), bin_config).unwrap();
    }
}