use std::{collections::BTreeSet, fmt};
use lexe_enclave::enclave::{MachineId, Measurement};
use lexe_std::fmt::DisplayIter;
#[cfg(test)]
use proptest_derive::Arbitrary;
use serde::{Deserialize, Serialize};
#[cfg(test)]
use crate::test_utils::arbitrary;
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[cfg_attr(test, derive(Arbitrary))]
pub struct MeasurementStruct {
pub measurement: Measurement,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[cfg_attr(test, derive(Arbitrary))]
pub struct CurrentEnclaves {
#[serde(rename = "releases", alias = "enclaves")]
pub enclaves: BTreeSet<NodeEnclave>,
}
impl CurrentEnclaves {
pub fn latest(&self) -> Option<&NodeEnclave> {
self.enclaves.last()
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[cfg_attr(test, derive(Arbitrary))]
pub struct EnclavesToProvision {
pub enclaves: BTreeSet<NodeEnclave>,
}
impl fmt::Display for EnclavesToProvision {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
DisplayIter(self.enclaves.iter()).fmt(f)
}
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[cfg_attr(test, derive(Arbitrary))]
pub struct NodeEnclave {
#[cfg_attr(test, proptest(strategy = "arbitrary::any_semver_version()"))]
pub version: semver::Version,
pub measurement: Measurement,
pub machine_id: MachineId,
}
impl Ord for NodeEnclave {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.version
.cmp_precedence(&other.version)
.then_with(|| self.machine_id.cmp(&other.machine_id))
}
}
impl PartialOrd for NodeEnclave {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl fmt::Display for NodeEnclave {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let version = &self.version;
let measurement = &self.measurement;
let machine_id = &self.machine_id;
write!(
f,
"(version=node-v{version}, measurement={measurement}, machine_id={machine_id})"
)
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::test_utils::roundtrip;
#[test]
fn measurement_struct_roundtrip() {
roundtrip::query_string_roundtrip_proptest::<MeasurementStruct>();
}
#[test]
fn node_enclave_roundtrip() {
roundtrip::json_value_roundtrip_proptest::<NodeEnclave>();
}
}