use sim_kernel::{CapabilityName, CapabilitySet, diminish};
use crate::{BrandCaps, VehicleId};
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum TransportPlacement {
Modeled,
Cassette {
id: String,
},
LocalBridge {
name: String,
},
}
impl TransportPlacement {
pub fn modeled() -> Self {
Self::Modeled
}
pub fn cassette(id: impl Into<String>) -> Self {
Self::Cassette { id: id.into() }
}
pub fn local_bridge(name: impl Into<String>) -> Self {
Self::LocalBridge { name: name.into() }
}
pub fn kind(&self) -> &'static str {
match self {
Self::Modeled => "modeled",
Self::Cassette { .. } => "cassette",
Self::LocalBridge { .. } => "local-bridge",
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct AutoSession {
pub vehicle: VehicleId,
pub brand: BrandCaps,
pub transport: TransportPlacement,
pub grants: Vec<CapabilityName>,
}
impl AutoSession {
pub fn new(
vehicle: VehicleId,
brand: BrandCaps,
transport: TransportPlacement,
grants: Vec<CapabilityName>,
) -> Self {
Self {
vehicle,
brand,
transport,
grants,
}
}
pub fn modeled(vehicle: VehicleId, brand: BrandCaps, grants: Vec<CapabilityName>) -> Self {
Self::new(vehicle, brand, TransportPlacement::Modeled, grants)
}
pub fn with_transport(mut self, transport: TransportPlacement) -> Self {
self.transport = transport;
self
}
pub fn has_grant(&self, capability: &CapabilityName) -> bool {
self.grants.iter().any(|grant| grant == capability)
}
pub fn diminished_grants(&self, allowed: &[CapabilityName]) -> CapabilitySet {
let current = capability_set(self.grants.iter().cloned());
let allowed = capability_set(allowed.iter().cloned());
diminish(¤t, &allowed)
}
}
fn capability_set(capabilities: impl IntoIterator<Item = CapabilityName>) -> CapabilitySet {
capabilities
.into_iter()
.fold(CapabilitySet::new(), CapabilitySet::grant)
}