Skip to main content

crev_data/proof/
trust.rs

1use crate::{
2    Error, Level, ParseError, Result,
3    proof::{self, CommonOps, Content, content::ValidationResult},
4    serde_content_serialize, serde_draft_serialize,
5};
6
7use derive_builder::Builder;
8use serde::{Deserialize, Serialize};
9
10use std::fmt;
11
12use super::{OverrideItem, OverrideItemDraft};
13
14const CURRENT_TRUST_PROOF_SERIALIZATION_VERSION: i64 = -1;
15
16fn cur_version() -> i64 {
17    CURRENT_TRUST_PROOF_SERIALIZATION_VERSION
18}
19
20#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialOrd, Ord, PartialEq, Eq, Default)]
21#[serde(rename_all = "lowercase")]
22pub enum TrustLevel {
23    Distrust,
24    None,
25    Low,
26    #[default]
27    Medium,
28    High,
29}
30
31impl fmt::Display for TrustLevel {
32    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33        use TrustLevel::*;
34        f.pad(match self {
35            Distrust => "distrust",
36            None => "none",
37            Low => "low",
38            Medium => "medium",
39            High => "high",
40        })
41    }
42}
43
44#[derive(thiserror::Error, Debug)]
45#[error(
46    "Can't convert string to TrustLevel. Possible values are: \"none\" or \"untrust\", \"low\", \"medium\", \"high\" and \"distrust\"."
47)]
48pub struct FromStrErr;
49
50impl std::str::FromStr for TrustLevel {
51    type Err = FromStrErr;
52
53    fn from_str(s: &str) -> std::result::Result<TrustLevel, FromStrErr> {
54        Ok(match s {
55            "none" | "untrust" => TrustLevel::None,
56            "low" => TrustLevel::Low,
57            "medium" => TrustLevel::Medium,
58            "high" => TrustLevel::High,
59            "distrust" => TrustLevel::Distrust,
60            _ => return Err(FromStrErr),
61        })
62    }
63}
64
65impl std::convert::From<Level> for TrustLevel {
66    fn from(l: Level) -> Self {
67        match l {
68            Level::None => TrustLevel::None,
69            Level::Low => TrustLevel::Low,
70            Level::Medium => TrustLevel::Medium,
71            Level::High => TrustLevel::High,
72        }
73    }
74}
75
76impl TrustLevel {
77    #[allow(unused)]
78    fn from_str(s: &str) -> Result<TrustLevel> {
79        Ok(match s {
80            "distrust" => TrustLevel::Distrust,
81            "none" => TrustLevel::None,
82            "low" => TrustLevel::Low,
83            "medium" => TrustLevel::Medium,
84            "high" => TrustLevel::High,
85            _ => return Err(Error::UnknownLevel(s.into())),
86        })
87    }
88}
89
90/// Body of a Trust Proof
91#[derive(Clone, Debug, Builder, Serialize, Deserialize)]
92pub struct Trust {
93    #[serde(flatten)]
94    pub common: proof::Common,
95    pub ids: Vec<crate::PublicId>,
96    #[builder(default = "Default::default()")]
97    pub trust: TrustLevel,
98    #[serde(skip_serializing_if = "String::is_empty", default = "Default::default")]
99    #[builder(default = "Default::default()")]
100    pub comment: String,
101    #[serde(
102        default = "Default::default",
103        skip_serializing_if = "Vec::is_empty",
104        rename = "override"
105    )]
106    #[builder(default = "Default::default()")]
107    pub override_: Vec<OverrideItem>,
108}
109
110impl TrustBuilder {
111    pub fn from<VALUE: Into<crate::PublicId>>(&mut self, value: VALUE) -> &mut Self {
112        if let Some(ref mut common) = self.common {
113            common.from = value.into();
114        } else {
115            self.common = Some(proof::Common {
116                kind: Some(Trust::KIND.into()),
117                version: cur_version(),
118                date: crev_common::now(),
119                from: value.into(),
120                original: None,
121            });
122        }
123        self
124    }
125}
126
127impl fmt::Display for Trust {
128    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129        self.serialize_to(f).map_err(|_| fmt::Error)
130    }
131}
132
133impl proof::CommonOps for Trust {
134    fn common(&self) -> &proof::Common {
135        &self.common
136    }
137
138    fn kind(&self) -> &str {
139        // Backfill the `kind` if it is empty (legacy format)
140        self.common.kind.as_deref().unwrap_or(Self::KIND)
141    }
142}
143
144impl Trust {
145    pub const KIND: &'static str = "trust";
146
147    pub fn touch_date(&mut self) {
148        self.common.date = crev_common::now();
149    }
150}
151
152/// Like `Trust` but serializes for interactive editing
153#[derive(Clone, Debug, Serialize, Deserialize)]
154pub struct Draft {
155    pub trust: TrustLevel,
156    #[serde(default = "Default::default", skip_serializing_if = "String::is_empty")]
157    comment: String,
158    #[serde(
159        default = "Default::default",
160        skip_serializing_if = "Vec::is_empty",
161        rename = "override"
162    )]
163    override_: Vec<OverrideItemDraft>,
164}
165
166impl From<Trust> for Draft {
167    fn from(trust: Trust) -> Self {
168        Draft {
169            trust: trust.trust,
170            comment: trust.comment,
171            override_: trust.override_.into_iter().map(Into::into).collect(),
172        }
173    }
174}
175
176impl fmt::Display for Draft {
177    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
178        serde_draft_serialize!(self, fmt);
179        Ok(())
180    }
181}
182
183impl proof::Content for Trust {
184    fn serialize_to(&self, fmt: &mut dyn std::fmt::Write) -> fmt::Result {
185        serde_content_serialize!(self, fmt);
186        Ok(())
187    }
188
189    fn validate_data(&self) -> ValidationResult<()> {
190        self.ensure_kind_is(Self::KIND)?;
191        Ok(())
192    }
193}
194
195impl Trust {
196    fn draft_title(&self) -> String {
197        match self.ids.len() {
198            0 => "Trust for noone?!".into(),
199            1 => format!("Trust for {} {}", self.ids[0].id, self.ids[0].url_display()),
200            n => format!(
201                "Trust for {} {} and {} other",
202                self.ids[0].id,
203                self.ids[0].url_display(),
204                n - 1
205            ),
206        }
207    }
208}
209
210impl proof::ContentWithDraft for Trust {
211    fn to_draft(&self) -> proof::Draft {
212        proof::Draft {
213            title: self.draft_title(),
214            body: Draft::from(self.clone()).to_string(),
215        }
216    }
217
218    fn apply_draft(&self, s: &str) -> Result<Self> {
219        let draft = Draft::parse(s)?;
220
221        let mut copy = self.clone();
222        copy.trust = draft.trust;
223        copy.comment = draft.comment;
224        copy.override_ = draft.override_.into_iter().map(Into::into).collect();
225
226        copy.validate_data()?;
227        Ok(copy)
228    }
229}
230
231impl Draft {
232    pub fn parse(s: &str) -> std::result::Result<Self, ParseError> {
233        serde_yaml::from_str(s).map_err(ParseError::Draft)
234    }
235}