use std::collections::BTreeSet;
use crate::{Binding, Network, Regex};
pub fn import(data: &str) -> Network {
let mut net = Network::new();
enum State {
Certifications,
Delegations,
}
let mut state = State::Certifications;
for line in data.lines() {
if line.is_empty() {
if matches!(state, State::Certifications) {
state = State::Delegations;
}
continue;
}
match state {
State::Certifications => {
let (issuer, rest) = line.split_once(" -> ").expect("FIXME");
assert!(rest.starts_with('('));
assert!(rest.ends_with(')'));
let rest = &rest[1..rest.len() - 1];
let (target_id, target_user) = rest.split_once(", ").expect("FIXME");
net.add_binding(
issuer.into(),
Binding {
cert: target_id.into(),
identity: target_user.into(),
},
);
}
State::Delegations => {
let (rest, regexes) = if line.ends_with(']') {
let (rest, regex) = line.split_once(" [\"").unwrap();
assert!(regex.ends_with("\"]"));
let regex = ®ex[0..regex.len() - 2];
let regexes: Vec<_> = regex
.split("\", \"")
.map(|r| Regex::new(r.to_string()))
.collect();
(rest, regexes)
} else {
(line, vec![])
};
let (issuer, rest) = rest.split_once(" -> ").expect("FIXME");
let pos = rest.rfind(' ').expect("FIXME");
let (target, trust) = rest.split_at(pos);
let trust = &trust[1..]; let (amount, depth) = trust.split_once("/").expect("FIXME");
let amount: u8 = amount.parse().expect("FIXME");
let depth: u8 = depth.parse().expect("FIXME");
net.add_delegation(issuer.into(), target.into(), amount, depth.into(), regexes);
}
}
}
net
}
pub fn export(network: &Network) -> String {
let mut bindings = BTreeSet::new();
for certification in network.certifications.values().flatten() {
bindings.insert(format!(
"{} -> ({}, {})\n",
certification.issuer.0, certification.target.cert.0, certification.target.identity.0,
));
}
let mut delegations = BTreeSet::new();
for delegation in network.delegations.values().flatten() {
let regex = if delegation.regexes.is_empty() {
"".to_string()
} else {
format!(
" [{}]",
delegation
.regexes
.iter()
.map(|r| format!("\"{}\"", &r.0))
.collect::<Vec<_>>()
.join(", ")
)
};
delegations.insert(format!(
"{} -> {} {}/{}{}\n",
delegation.issuer.0,
delegation.target.0,
delegation.trust_amount,
u8::from(delegation.trust_depth),
regex
));
}
let mut out = String::new();
for binding in bindings {
out.push_str(&binding);
}
out.push('\n');
for delegation in delegations {
out.push_str(&delegation);
}
out
}