in_toto/models/layout/
metadata.rs1use chrono::{DateTime, Duration, Utc};
4use serde::de::{Deserialize, Deserializer, Error as DeserializeError};
5use serde::ser::{Error as SerializeError, Serialize, Serializer};
6
7use std::collections::HashMap;
8
9use crate::crypto::KeyId;
10use crate::crypto::PublicKey;
11use crate::interchange::{DataInterchange, Json};
12use crate::models::{Metadata, MetadataType, MetadataWrapper};
13use crate::Result;
14
15use super::Layout;
16use super::{inspection::Inspection, step::Step};
17
18pub struct LayoutMetadataBuilder {
20 expires: DateTime<Utc>,
21 readme: String,
22 keys: HashMap<KeyId, PublicKey>,
23 steps: Vec<Step>,
24 inspect: Vec<Inspection>,
25}
26
27impl Default for LayoutMetadataBuilder {
28 fn default() -> Self {
29 LayoutMetadataBuilder::new()
30 }
31}
32
33impl LayoutMetadataBuilder {
34 pub fn new() -> Self {
39 LayoutMetadataBuilder {
40 steps: Vec::new(),
41 inspect: Vec::new(),
42 keys: HashMap::new(),
43 expires: Utc::now() + Duration::days(365),
44 readme: String::new(),
45 }
46 }
47
48 pub fn expires(mut self, expires: DateTime<Utc>) -> Self {
50 self.expires = expires;
51 self
52 }
53
54 pub fn readme(mut self, readme: String) -> Self {
56 self.readme = readme;
57 self
58 }
59
60 pub fn add_step(mut self, step: Step) -> Self {
62 self.steps.push(step);
63 self
64 }
65
66 pub fn add_steps(mut self, mut steps: Vec<Step>) -> Self {
68 self.steps.append(&mut steps);
69 self
70 }
71
72 pub fn steps(mut self, steps: Vec<Step>) -> Self {
74 self.steps = steps;
75 self
76 }
77
78 pub fn add_inspect(mut self, inspect: Inspection) -> Self {
80 self.inspect.push(inspect);
81 self
82 }
83
84 pub fn add_inspects(mut self, mut inspects: Vec<Inspection>) -> Self {
86 self.inspect.append(&mut inspects);
87 self
88 }
89
90 pub fn inspects(mut self, step: Vec<Inspection>) -> Self {
92 self.inspect = step;
93 self
94 }
95
96 pub fn add_key(mut self, key: PublicKey) -> Self {
98 self.keys.insert(key.key_id().clone(), key);
99 self
100 }
101
102 pub fn build(self) -> Result<LayoutMetadata> {
103 Ok(LayoutMetadata::new(
104 self.expires,
105 self.readme,
106 self.keys,
107 self.steps,
108 self.inspect,
109 ))
110 }
111}
112
113#[derive(Debug, Clone, PartialEq, Eq)]
115pub struct LayoutMetadata {
116 pub steps: Vec<Step>,
117 pub inspect: Vec<Inspection>,
118 pub keys: HashMap<KeyId, PublicKey>,
119 pub expires: DateTime<Utc>,
120 pub readme: String,
121}
122
123impl LayoutMetadata {
124 pub fn new(
125 expires: DateTime<Utc>,
126 readme: String,
127 keys: HashMap<KeyId, PublicKey>,
128 steps: Vec<Step>,
129 inspect: Vec<Inspection>,
130 ) -> Self {
131 LayoutMetadata {
132 steps,
133 inspect,
134 keys,
135 expires,
136 readme,
137 }
138 }
139}
140
141impl Metadata for LayoutMetadata {
142 fn typ(&self) -> MetadataType {
143 MetadataType::Layout
144 }
145
146 fn into_enum(self: Box<Self>) -> MetadataWrapper {
147 MetadataWrapper::Layout(*self)
148 }
149
150 fn to_bytes(&self) -> Result<Vec<u8>> {
151 Json::canonicalize(&Json::serialize(self)?)
152 }
153}
154
155impl Serialize for LayoutMetadata {
156 fn serialize<S>(&self, ser: S) -> ::std::result::Result<S::Ok, S::Error>
157 where
158 S: Serializer,
159 {
160 Layout::from(self)
161 .map_err(|e| SerializeError::custom(format!("{:?}", e)))?
162 .serialize(ser)
163 }
164}
165
166impl<'de> Deserialize<'de> for LayoutMetadata {
167 fn deserialize<D: Deserializer<'de>>(
168 de: D,
169 ) -> ::std::result::Result<Self, D::Error> {
170 let intermediate: Layout = Deserialize::deserialize(de)?;
171 intermediate
172 .try_into()
173 .map_err(|e| DeserializeError::custom(format!("{:?}", e)))
174 }
175}