in_toto/models/statement/
mod.rs1pub 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 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 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 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}