furtif_core/structs/assignment_tools/
safe.rs

1// This program is free software: you can redistribute it and/or modify
2// it under the terms of the Lesser GNU General Public License as published
3// by the Free Software Foundation, either version 3 of the License, or
4// (at your option) any later version.
5
6// This program is distributed in the hope that it will be useful,
7// but WITHOUT ANY WARRANTY; without even the implied warranty of
8// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9// Lesser GNU General Public License for more details.
10
11// You should have received a copy of the Lesser GNU General Public License
12// along with this program.  If not, see <https://www.gnu.org/licenses/>.
13
14// Copyright 2024 Frederic Dambreville, Jean Dezert Developers.
15
16
17use std::fmt::Display;
18
19use hashed_type_def::HashedTypeDef;
20// #[cfg(not(feature = "silx-types"))] use crate::fake_slx::u128slx;
21// #[cfg(feature = "silx-types")] use silx_types::u128slx;
22use crate::types::u128slx;
23
24#[cfg(feature = "serde")] use serde::{ Serialize as SerdeSerialize, Deserialize as SerdeDeserialize, };
25#[cfg(feature = "rkyv")] use rkyv::{ Archive, Serialize as RkyvSerialize, Deserialize as RkyvDeserialize, };
26
27#[derive(HashedTypeDef, Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord,)]
28#[cfg_attr(feature = "rkyv", derive(Archive,RkyvSerialize,RkyvDeserialize))]
29/// Definition of safe element
30/// * Safe element combines the element's actual encoding (which generally gives no information about the original lattice) with the hash of its lattice
31/// * `X` : type of the encoding
32pub struct SafeElement<X> {
33    pub (crate) code: X,
34    pub (crate) lattice_hash: u128slx,
35}
36
37impl<X> Display for SafeElement<X> where X: Display {
38    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39        self.code.fmt(f)
40    }
41}
42
43// implementation of Serde serialization
44#[cfg(feature = "serde")]
45mod serding {
46    // #[cfg(not(feature = "silx-types"))] use crate::fake_slx::FakeSlx;
47    // #[cfg(feature = "silx-types")] use silx_types::{IntoSlx, SlxInto};
48    use crate::types::{ SlxInto, IntoSlx, };
49    use super::{ 
50        SafeElement as SerdingSafeElement, SerdeSerialize, SerdeDeserialize,
51    };
52    #[derive(SerdeSerialize,SerdeDeserialize)]
53    pub struct SafeElement<X> {
54        element: X, lattice_hash: u128,
55    }
56    impl<'de, X> SerdeDeserialize<'de> for SerdingSafeElement<X> where X: SerdeDeserialize<'de>, {
57        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
58        where D: serde::Deserializer<'de> {
59            let SafeElement { element, lattice_hash} = SafeElement::<X>::deserialize(deserializer)?;
60            let lattice_hash = lattice_hash.slx();
61            Ok(Self { code: element, lattice_hash, })
62        }
63    }
64    impl<X> SerdeSerialize for SerdingSafeElement<X>  where X: Clone + SerdeSerialize, {
65        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
66        where S: serde::Serializer {
67            let SerdingSafeElement { code: element, lattice_hash } = self;
68            let element = element.clone();
69            let lattice_hash = lattice_hash.unslx();
70            let safe_element = SafeElement { element, lattice_hash, };
71            safe_element.serialize(serializer)
72        }
73    }
74}
75
76/// Structure for safe array (for internal use)
77/// * A safe array contains a lattice hash and a sequence of encoded elements from this lattice  
78/// * `X` : type of the element encoding
79#[derive(HashedTypeDef, Debug,)]
80pub struct SafeArray<'a,X> {
81    pub (crate) product: Vec<&'a X>,
82    pub (crate) lattice_hash: u128slx,
83}
84
85impl<X> SafeElement<X> {
86    /// Unsafe constructor for safe element
87    /// * the constructor is unsafe, as there is no consistency check that the encoded element comes from the lattice 
88    /// * `element: X` : encoded element
89    /// * `lattice_hash: u128slx` : lattice hash
90    /// * Output: safe element
91    pub unsafe fn unsafe_new(element: X, lattice_hash: u128slx,) -> Self {
92        Self { code: element, lattice_hash }
93    }
94
95    /// Get encoded element
96    /// * Output: encoded element
97    pub fn encoded(&self) -> X where X: Clone { self.code.clone() }
98
99    /// Get lattice hash
100    /// * Output: lattice hash
101    pub fn lattice_hash(&self) -> u128slx { self.lattice_hash }
102}
103
104impl<'a,X> SafeArray<'a,X> {
105    pub fn len(&self) -> usize { self.product.len() }
106
107    /// Get lattice hash
108    /// * Output: lattice hash
109    pub fn lattice_hash(&self) -> u128slx { self.lattice_hash }
110}