Skip to main content

feanor_math/
serialization.rs

1use serde::de::*;
2use serde::{Deserializer, Serialize, Serializer};
3
4use crate::ring::*;
5
6/// Trait for rings whose elements can be serialized.
7///
8/// Serialization and deserialization mostly follow the principles of the `serde` crate, with
9/// the main difference that ring elements cannot be serialized/deserialized on their own, but
10/// only w.r.t. a specific ring.
11#[stability::unstable(feature = "enable")]
12pub trait SerializableElementRing: RingBase {
13    /// Deserializes an element of this ring from the given deserializer.
14    fn deserialize<'de, D>(&self, deserializer: D) -> Result<Self::Element, D::Error>
15    where
16        D: Deserializer<'de>;
17
18    /// Serializes an element of this ring to the given serializer.
19    fn serialize<S>(&self, el: &Self::Element, serializer: S) -> Result<S::Ok, S::Error>
20    where
21        S: Serializer;
22}
23
24/// Wrapper of a ring that implements [`serde::DeserializationSeed`] by trying to deserialize an
25/// element w.r.t. the wrapped ring.
26#[stability::unstable(feature = "enable")]
27#[derive(Clone)]
28pub struct DeserializeWithRing<R: RingStore>
29where
30    R::Type: SerializableElementRing,
31{
32    ring: R,
33}
34
35impl<R> DeserializeWithRing<R>
36where
37    R::Type: SerializableElementRing,
38    R: RingStore,
39{
40    #[stability::unstable(feature = "enable")]
41    pub fn new(ring: R) -> Self { Self { ring } }
42}
43
44impl<'de, R> DeserializeSeed<'de> for DeserializeWithRing<R>
45where
46    R::Type: SerializableElementRing,
47    R: RingStore,
48{
49    type Value = El<R>;
50
51    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
52    where
53        D: Deserializer<'de>,
54    {
55        self.ring.get_ring().deserialize(deserializer)
56    }
57}
58
59/// Wraps a ring and a reference to one of its elements. Implements [`serde::Serialize`] and
60/// will serialize the element w.r.t. the ring.
61#[stability::unstable(feature = "enable")]
62pub struct SerializeWithRing<'a, R: RingStore>
63where
64    R::Type: SerializableElementRing,
65{
66    ring: R,
67    el: &'a El<R>,
68}
69
70impl<'a, R: RingStore> SerializeWithRing<'a, R>
71where
72    R::Type: SerializableElementRing,
73{
74    #[stability::unstable(feature = "enable")]
75    pub fn new(el: &'a El<R>, ring: R) -> Self { Self { el, ring } }
76}
77
78impl<'a, R: RingStore> Serialize for SerializeWithRing<'a, R>
79where
80    R::Type: SerializableElementRing,
81{
82    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
83    where
84        S: Serializer,
85    {
86        self.ring.get_ring().serialize(self.el, serializer)
87    }
88}
89
90/// Wraps a ring and a one of its elements. Implements [`serde::Serialize`] and
91/// will serialize the element w.r.t. the ring.
92#[stability::unstable(feature = "enable")]
93pub struct SerializeOwnedWithRing<R: RingStore>
94where
95    R::Type: SerializableElementRing,
96{
97    ring: R,
98    el: El<R>,
99}
100
101impl<R: RingStore> SerializeOwnedWithRing<R>
102where
103    R::Type: SerializableElementRing,
104{
105    #[stability::unstable(feature = "enable")]
106    pub fn new(el: El<R>, ring: R) -> Self { Self { el, ring } }
107}
108
109impl<R: RingStore> Serialize for SerializeOwnedWithRing<R>
110where
111    R::Type: SerializableElementRing,
112{
113    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
114    where
115        S: Serializer,
116    {
117        self.ring.get_ring().serialize(&self.el, serializer)
118    }
119}
120
121#[stability::unstable(feature = "enable")]
122#[cfg(any(test, feature = "generic_tests"))]
123pub mod generic_tests {
124
125    use super::*;
126
127    #[stability::unstable(feature = "enable")]
128    pub fn test_serialization<R: RingStore, I: Iterator<Item = El<R>>>(ring: R, edge_case_elements: I)
129    where
130        R::Type: SerializableElementRing,
131    {
132        let edge_case_elements = edge_case_elements.collect::<Vec<_>>();
133
134        let serializer = serde_assert::Serializer::builder().is_human_readable(true).build();
135        for x in &edge_case_elements {
136            let tokens = ring.get_ring().serialize(&x, &serializer).unwrap();
137            let mut deserializer = serde_assert::Deserializer::builder(tokens)
138                .is_human_readable(true)
139                .build();
140            let result = ring.get_ring().deserialize(&mut deserializer).unwrap();
141            assert_el_eq!(ring, &result, &x);
142        }
143
144        let serializer = serde_assert::Serializer::builder().is_human_readable(false).build();
145        for x in &edge_case_elements {
146            let tokens = ring.get_ring().serialize(&x, &serializer).unwrap();
147            let mut deserializer = serde_assert::Deserializer::builder(tokens)
148                .is_human_readable(false)
149                .build();
150            let result = ring.get_ring().deserialize(&mut deserializer).unwrap();
151            assert_el_eq!(ring, &result, &x);
152        }
153    }
154
155    #[stability::unstable(feature = "enable")]
156    pub fn test_serialize_deserialize<T: Serialize + for<'de> Deserialize<'de> + PartialEq>(x: T) {
157        let serializer = serde_assert::Serializer::builder().is_human_readable(true).build();
158        let tokens = x.serialize(&serializer).unwrap();
159        let mut deserializer = serde_assert::Deserializer::builder(tokens)
160            .is_human_readable(true)
161            .build();
162        let result = T::deserialize(&mut deserializer).unwrap();
163        assert!(result == x);
164
165        let serializer = serde_assert::Serializer::builder().is_human_readable(false).build();
166        let tokens = x.serialize(&serializer).unwrap();
167        let mut deserializer = serde_assert::Deserializer::builder(tokens)
168            .is_human_readable(false)
169            .build();
170        let result = T::deserialize(&mut deserializer).unwrap();
171        assert!(result == x);
172    }
173}
174
175#[cfg(test)]
176use crate::integer::{BigIntRing, IntegerRingStore};
177
178#[test]
179fn test_serialize() {
180    let value = BigIntRing::RING.add(BigIntRing::RING.power_of_two(128), BigIntRing::RING.one());
181    let json = serde_json::to_string(&SerializeWithRing::new(&value, BigIntRing::RING)).unwrap();
182    assert_eq!("\"340282366920938463463374607431768211457\"", json);
183}