in_toto/models/statement/
mod.rs

1pub mod state_naive;
2pub mod state_v01;
3use serde_json::Value;
4pub use state_naive::StateNaive;
5pub use state_v01::StateV01;
6
7use std::convert::TryFrom;
8use std::fmt::{Display, Formatter, Result as FmtResult};
9
10use serde::de::{Deserializer, Error as DeserializeError};
11use serde::ser::Serializer;
12use serde::{Deserialize, Serialize};
13use strum::IntoEnumIterator;
14use strum_macros::EnumIter;
15
16use super::{LinkMetadata, PredicateLayout};
17use crate::Error;
18use crate::Result;
19
20#[derive(Debug, Hash, Eq, PartialEq, Clone, Copy, EnumIter)]
21pub enum StatementVer {
22    Naive,
23    V0_1,
24}
25
26impl TryFrom<String> for StatementVer {
27    type Error = crate::Error;
28
29    fn try_from(target: String) -> Result<Self> {
30        match target.as_str() {
31            "link" => Ok(StatementVer::Naive),
32            "https://in-toto.io/Statement/v0.1" => Ok(StatementVer::V0_1),
33            _ => Err(Error::StringConvertFailed(target)),
34        }
35    }
36}
37
38impl From<StatementVer> for String {
39    fn from(value: StatementVer) -> Self {
40        match value {
41            StatementVer::Naive => "link".to_string(),
42            StatementVer::V0_1 => {
43                "https://in-toto.io/Statement/v0.1".to_string()
44            }
45        }
46    }
47}
48
49impl Serialize for StatementVer {
50    fn serialize<S>(&self, ser: S) -> ::std::result::Result<S::Ok, S::Error>
51    where
52        S: Serializer,
53    {
54        let target: String = (*self).into();
55        ser.serialize_str(&target)
56    }
57}
58
59impl<'de> Deserialize<'de> for StatementVer {
60    fn deserialize<D: Deserializer<'de>>(
61        de: D,
62    ) -> ::std::result::Result<Self, D::Error> {
63        let target: String = Deserialize::deserialize(de)?;
64        StatementVer::try_from(target)
65            .map_err(|e| DeserializeError::custom(format!("{:?}", e)))
66    }
67}
68
69impl Display for StatementVer {
70    fn fmt(&self, fmt: &mut Formatter) -> FmtResult {
71        match self {
72            StatementVer::V0_1 => fmt.write_str("v0.1")?,
73            StatementVer::Naive => fmt.write_str("naive")?,
74        }
75        Ok(())
76    }
77}
78
79#[derive(Debug, Serialize, PartialEq, Eq)]
80pub enum StatementWrapper {
81    Naive(StateNaive),
82    V0_1(StateV01),
83}
84impl<'de> Deserialize<'de> for StatementWrapper {
85    fn deserialize<D: Deserializer<'de>>(
86        de: D,
87    ) -> ::std::result::Result<Self, D::Error> {
88        let value = Value::deserialize(de)?;
89        StatementWrapper::try_from_value(value)
90            .map_err(|e| DeserializeError::custom(format!("{:?}", e)))
91    }
92}
93
94pub trait FromMerge: Sized {
95    fn merge(
96        meta: LinkMetadata,
97        predicate: Option<Box<dyn PredicateLayout>>,
98    ) -> Result<Self>;
99}
100
101impl StatementWrapper {
102    pub fn into_trait(self) -> Box<dyn StateLayout> {
103        match self {
104            StatementWrapper::Naive(link) => Box::new(link),
105            StatementWrapper::V0_1(link) => Box::new(link),
106        }
107    }
108
109    pub fn from_meta(
110        meta: LinkMetadata,
111        predicate: Option<Box<dyn PredicateLayout>>,
112        version: StatementVer,
113    ) -> Self {
114        match version {
115            StatementVer::Naive => {
116                Self::Naive(StateNaive::merge(meta, predicate).unwrap())
117            }
118            StatementVer::V0_1 => {
119                Self::V0_1(StateV01::merge(meta, predicate).unwrap())
120            }
121        }
122    }
123
124    /// Deserialize method for `StatementWrapper` from `serde:Value` by its version
125    fn from_value(value: Value, version: StatementVer) -> Result<Self> {
126        match version {
127            StatementVer::Naive => serde_json::from_value(value)
128                .map(Self::Naive)
129                .map_err(|e| e.into()),
130            StatementVer::V0_1 => serde_json::from_value(value)
131                .map(Self::V0_1)
132                .map_err(|e| e.into()),
133        }
134    }
135
136    /// Auto judge the `PredicateWrapper` version from `serde:Value`
137    pub fn judge_from_value(value: &Value) -> Result<StatementVer> {
138        for version in StatementVer::iter() {
139            let wrapper = StatementWrapper::from_value(value.clone(), version);
140            if wrapper.is_ok() {
141                return Ok(version);
142            }
143        }
144        Err(Error::Programming("no available value parser".to_string()))
145    }
146
147    // Auto deserialize for `PredicateWrapper` by any possible version.
148    pub fn try_from_value(value: Value) -> Result<Self> {
149        let version = Self::judge_from_value(&value)?;
150        StatementWrapper::from_value(value, version)
151    }
152}
153
154pub trait StateLayout {
155    fn version(&self) -> StatementVer;
156    fn into_enum(self: Box<Self>) -> StatementWrapper;
157    fn to_bytes(&self) -> Result<Vec<u8>>;
158}