in_toto/models/predicate/
mod.rs1pub mod link_v02;
4pub mod slsa_provenance_v01;
5pub mod slsa_provenance_v02;
6use std::convert::TryFrom;
7
8pub use link_v02::LinkV02;
9use serde_json::Value;
10pub use slsa_provenance_v01::SLSAProvenanceV01;
11pub use slsa_provenance_v02::SLSAProvenanceV02;
12
13use serde::de::{Deserializer, Error as DeserializeError};
14use serde::ser::Serializer;
15use serde::{Deserialize, Serialize};
16use strum::IntoEnumIterator;
17use strum_macros::EnumIter;
18
19use crate::{Error, Result};
20
21#[derive(Debug, Hash, PartialEq, Eq, EnumIter, Clone, Copy)]
22pub enum PredicateVer {
23 LinkV0_2,
24 SLSAProvenanceV0_1,
25 SLSAProvenanceV0_2,
26}
27
28impl TryFrom<String> for PredicateVer {
29 type Error = crate::Error;
30
31 fn try_from(target: String) -> Result<Self> {
32 match target.as_str() {
33 "https://in-toto.io/Link/v0.2" => Ok(PredicateVer::LinkV0_2),
34 "https://slsa.dev/provenance/v0.1" => {
35 Ok(PredicateVer::SLSAProvenanceV0_1)
36 }
37 "https://slsa.dev/provenance/v0.2" => {
38 Ok(PredicateVer::SLSAProvenanceV0_2)
39 }
40 _ => Err(Error::StringConvertFailed(target)),
41 }
42 }
43}
44
45impl From<PredicateVer> for String {
46 fn from(value: PredicateVer) -> Self {
47 match value {
48 PredicateVer::LinkV0_2 => {
49 "https://in-toto.io/Link/v0.2".to_string()
50 }
51 PredicateVer::SLSAProvenanceV0_1 => {
52 "https://slsa.dev/provenance/v0.1".to_string()
53 }
54 PredicateVer::SLSAProvenanceV0_2 => {
55 "https://slsa.dev/provenance/v0.2".to_string()
56 }
57 }
58 }
59}
60
61impl Serialize for PredicateVer {
62 fn serialize<S>(&self, ser: S) -> ::std::result::Result<S::Ok, S::Error>
63 where
64 S: Serializer,
65 {
66 let target: String = (*self).into();
67 ser.serialize_str(&target)
68 }
69}
70
71impl<'de> Deserialize<'de> for PredicateVer {
72 fn deserialize<D: Deserializer<'de>>(
73 de: D,
74 ) -> ::std::result::Result<Self, D::Error> {
75 let target: String = Deserialize::deserialize(de)?;
76 PredicateVer::try_from(target)
77 .map_err(|e| DeserializeError::custom(format!("{:?}", e)))
78 }
79}
80
81#[derive(Debug, Serialize, PartialEq, Eq, Clone)]
82#[serde(untagged)]
83pub enum PredicateWrapper {
84 LinkV0_2(LinkV02),
85 SLSAProvenanceV0_1(SLSAProvenanceV01),
86 SLSAProvenanceV0_2(SLSAProvenanceV02),
87}
88
89impl<'de> Deserialize<'de> for PredicateWrapper {
90 fn deserialize<D: Deserializer<'de>>(
91 de: D,
92 ) -> ::std::result::Result<Self, D::Error> {
93 let value = Value::deserialize(de)?;
94 PredicateWrapper::try_from_value(value)
95 .map_err(|e| DeserializeError::custom(format!("{:?}", e)))
96 }
97}
98
99impl PredicateWrapper {
100 pub fn into_trait(self) -> Box<dyn PredicateLayout> {
102 match self {
103 PredicateWrapper::LinkV0_2(link) => Box::new(link),
104 PredicateWrapper::SLSAProvenanceV0_1(proven) => Box::new(proven),
105 PredicateWrapper::SLSAProvenanceV0_2(proven) => Box::new(proven),
106 }
107 }
108
109 fn from_value(value: Value, version: PredicateVer) -> Result<Self> {
111 match version {
112 PredicateVer::LinkV0_2 => serde_json::from_value(value)
113 .map(Self::LinkV0_2)
114 .map_err(|e| e.into()),
115 PredicateVer::SLSAProvenanceV0_1 => serde_json::from_value(value)
116 .map(Self::SLSAProvenanceV0_1)
117 .map_err(|e| e.into()),
118 PredicateVer::SLSAProvenanceV0_2 => serde_json::from_value(value)
119 .map(Self::SLSAProvenanceV0_2)
120 .map_err(|e| e.into()),
121 }
122 }
123
124 pub fn judge_from_value(value: &Value) -> Result<PredicateVer> {
126 println!("{:?}", value);
127 for version in PredicateVer::iter() {
128 let wrapper = PredicateWrapper::from_value(value.clone(), version);
129 if wrapper.is_ok() {
130 return Ok(version);
131 }
132 }
133 Err(Error::Programming("no available value parser".to_string()))
134 }
135
136 pub fn try_from_value(value: Value) -> Result<Self> {
138 let version = Self::judge_from_value(&value)?;
139 PredicateWrapper::from_value(value, version)
140 }
141}
142
143pub trait PredicateLayout {
144 fn version(&self) -> PredicateVer;
146 fn into_enum(self: Box<Self>) -> PredicateWrapper;
148 fn to_bytes(&self) -> Result<Vec<u8>>;
150}