wot_network/
network.rs

1use std::collections::HashMap;
2
3use crate::{Binding, Certificate, Certification, Delegation, Identity, Regex, TrustDepth};
4
5/// A "Web of Trust" network consisting of [Certification]s and [Delegation]s.
6///
7/// A [Network] represents a snapshot of valid nodes and edges in a set of OpenPGP Certificates
8/// at a reference time.
9///
10/// **NOTE**:
11///
12/// Users of this crate will usually want to create a `wot-network` graph from OpenPGP certificates.
13/// This involves applying all relevant OpenPGP semantics and forming a network of exactly
14/// those nodes and edges that are valid and active at the reference time.
15///
16/// One implementation of formation of `wot-network` graphs is available in
17/// [wot-network-rpgpie](https://crates.io/crates/wot-network-rpgpie).
18#[derive(Debug, PartialEq, Clone)]
19pub struct Network {
20    // Certifications on a binding
21    pub certifications: HashMap<Binding, Vec<Certification>>,
22
23    // Delegations on a cert
24    pub delegations: HashMap<Certificate, Vec<Delegation>>,
25}
26
27impl Default for Network {
28    fn default() -> Self {
29        Self::new()
30    }
31}
32
33impl Network {
34    pub fn new() -> Self {
35        Self {
36            certifications: Default::default(),
37            delegations: Default::default(),
38        }
39    }
40
41    pub fn num_edges(&self) -> usize {
42        self.certifications.len() + self.delegations.len()
43    }
44
45    pub fn add_binding(
46        &mut self,
47        issuer: Certificate,
48        target_cert: Certificate,
49        target_user_id: Identity,
50    ) {
51        // FIXME: less Certificate cloning!?
52
53        let edge = Certification {
54            issuer: issuer.clone(),
55            target: target_cert.clone(),
56            user_id: target_user_id.clone(),
57        };
58
59        if let Some(edges) = self.certifications.get_mut(&Binding {
60            cert: target_cert.clone(),
61            identity: target_user_id.clone(),
62        }) {
63            // add edge to pre-existing EdgeSet
64            edges.push(edge);
65        } else {
66            // make a new EdgeSet, put this edge in
67            let list = vec![edge];
68
69            self.certifications.insert(
70                Binding {
71                    cert: target_cert,
72                    identity: target_user_id,
73                },
74                list,
75            );
76        }
77    }
78
79    pub fn add_delegation(
80        &mut self,
81        issuer: Certificate,
82        target_cert: Certificate,
83        trust_amount: u8,
84        trust_depth: TrustDepth,
85        regexes: Vec<Regex>,
86    ) {
87        // FIXME: less Certificate cloning!?
88
89        let edge = Delegation {
90            issuer: issuer.clone(),
91            target: target_cert.clone(),
92            trust_amount,
93            trust_depth,
94            regexes,
95        };
96
97        if let Some(edges) = self.delegations.get_mut(&target_cert) {
98            // Add edge to pre-existing EdgeSet
99            edges.push(edge);
100        } else {
101            // Make a new EdgeSet
102            let list = vec![edge];
103
104            // Add this EdgeSet to the Network
105            self.delegations.insert(target_cert, list);
106        }
107    }
108}