string_interner/
serde_impl.rs

1use crate::{backend::Backend, StringInterner, Symbol};
2use alloc::boxed::Box;
3use core::{default::Default, fmt, hash::BuildHasher, marker};
4use serde::{
5    de::{Deserialize, Deserializer, SeqAccess, Visitor},
6    ser::{Serialize, SerializeSeq, Serializer},
7};
8
9impl<B, H> Serialize for StringInterner<B, H>
10where
11    B: Backend,
12    <B as Backend>::Symbol: Symbol,
13    for<'a> &'a B: IntoIterator<Item = (<B as Backend>::Symbol, &'a str)>,
14    H: BuildHasher,
15{
16    fn serialize<T>(&self, serializer: T) -> Result<T::Ok, T::Error>
17    where
18        T: Serializer,
19    {
20        let mut seq = serializer.serialize_seq(Some(self.len()))?;
21        for (_symbol, string) in self {
22            seq.serialize_element(string)?
23        }
24        seq.end()
25    }
26}
27
28impl<'de, B, H> Deserialize<'de> for StringInterner<B, H>
29where
30    B: Backend,
31    <B as Backend>::Symbol: Symbol,
32    H: BuildHasher + Default,
33{
34    fn deserialize<D>(deserializer: D) -> Result<StringInterner<B, H>, D::Error>
35    where
36        D: Deserializer<'de>,
37    {
38        deserializer.deserialize_seq(StringInternerVisitor::default())
39    }
40}
41
42struct StringInternerVisitor<B, H>
43where
44    B: Backend,
45    <B as Backend>::Symbol: Symbol,
46    H: BuildHasher,
47{
48    mark: marker::PhantomData<(<B as Backend>::Symbol, B, H)>,
49}
50
51impl<B, H> Default for StringInternerVisitor<B, H>
52where
53    B: Backend,
54    <B as Backend>::Symbol: Symbol,
55    H: BuildHasher,
56{
57    fn default() -> Self {
58        StringInternerVisitor {
59            mark: marker::PhantomData,
60        }
61    }
62}
63
64impl<'de, B, H> Visitor<'de> for StringInternerVisitor<B, H>
65where
66    B: Backend,
67    <B as Backend>::Symbol: Symbol,
68    H: BuildHasher + Default,
69{
70    type Value = StringInterner<B, H>;
71
72    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
73        formatter.write_str("Expected a contiguous sequence of strings.")
74    }
75
76    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
77    where
78        A: SeqAccess<'de>,
79    {
80        let mut interner: StringInterner<B, H> =
81            StringInterner::with_capacity_and_hasher(seq.size_hint().unwrap_or(0), H::default());
82        while let Some(s) = seq.next_element::<Box<str>>()? {
83            interner.get_or_intern(s);
84        }
85        Ok(interner)
86    }
87}
88
89macro_rules! impl_serde_for_symbol {
90    ($name:ident, $ty:ty) => {
91        impl ::serde::Serialize for $crate::symbol::$name {
92            fn serialize<T: ::serde::Serializer>(
93                &self,
94                serializer: T,
95            ) -> ::core::result::Result<T::Ok, T::Error> {
96                self.value.serialize(serializer)
97            }
98        }
99
100        impl<'de> ::serde::Deserialize<'de> for $crate::symbol::$name {
101            fn deserialize<D: ::serde::Deserializer<'de>>(
102                deserializer: D,
103            ) -> ::core::result::Result<Self, D::Error> {
104                let index = <$ty as ::serde::Deserialize<'de>>::deserialize(deserializer)?;
105                let ::core::option::Option::Some(symbol) = Self::new(index) else {
106                    return ::core::result::Result::Err(<D::Error as ::serde::de::Error>::custom(
107                        ::core::concat!(
108                            "invalid index value for `",
109                            ::core::stringify!($name),
110                            "`"
111                        ),
112                    ));
113                };
114                ::core::result::Result::Ok(symbol)
115            }
116        }
117    };
118}
119impl_serde_for_symbol!(SymbolU16, u16);
120impl_serde_for_symbol!(SymbolU32, u32);
121impl_serde_for_symbol!(SymbolUsize, usize);