use sim_lib_compute_model::ModeledComputeProfile;
use crate::profile::ComputeDeviceIdentity;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ComputeEvidenceKind {
Modeled,
HostEmulated,
PhysicalDevice,
}
impl ComputeEvidenceKind {
pub fn as_str(self) -> &'static str {
match self {
Self::Modeled => "modeled",
Self::HostEmulated => "host-emulated",
Self::PhysicalDevice => "physical-device",
}
}
}
impl TryFrom<&str> for ComputeEvidenceKind {
type Error = PhysicalEvidenceError;
fn try_from(value: &str) -> std::result::Result<Self, Self::Error> {
match value {
"modeled" => Ok(Self::Modeled),
"host-emulated" => Ok(Self::HostEmulated),
"physical-device" => Ok(Self::PhysicalDevice),
other => Err(PhysicalEvidenceError::new(format!(
"unknown compute evidence kind: {other}"
))),
}
}
}
pub trait ComputePhysicalEvidence {
fn evidence_kind(&self) -> ComputeEvidenceKind;
fn claimed_identity(&self) -> Option<&ComputeDeviceIdentity> {
None
}
fn observed_identity(&self) -> Option<&ComputeDeviceIdentity> {
None
}
}
impl ComputePhysicalEvidence for ModeledComputeProfile {
fn evidence_kind(&self) -> ComputeEvidenceKind {
ComputeEvidenceKind::Modeled
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PhysicalEvidenceError {
message: String,
}
impl PhysicalEvidenceError {
fn new(message: impl Into<String>) -> Self {
Self {
message: message.into(),
}
}
}
impl std::fmt::Display for PhysicalEvidenceError {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.write_str(&self.message)
}
}
impl std::error::Error for PhysicalEvidenceError {}
pub fn verify_physical(
evidence: &(impl ComputePhysicalEvidence + ?Sized),
) -> std::result::Result<(), PhysicalEvidenceError> {
if evidence.evidence_kind() != ComputeEvidenceKind::PhysicalDevice {
return Err(PhysicalEvidenceError::new(format!(
"compute evidence is {}, not physical-device",
evidence.evidence_kind().as_str()
)));
}
match (evidence.claimed_identity(), evidence.observed_identity()) {
(Some(claimed), Some(observed)) if claimed == observed => Ok(()),
(Some(_), Some(_)) => Err(PhysicalEvidenceError::new(
"compute evidence identity was renamed after capture",
)),
_ => Err(PhysicalEvidenceError::new(
"compute physical evidence is missing observed identity",
)),
}
}