use crate::ids::{ManagedCanisterBinding, ReleaseBuildId};
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct FixtureImportAuthority {
pub target: ManagedCanisterBinding,
pub installation: [u8; 32],
pub release_build_id: ReleaseBuildId,
pub content_id: [u8; 32],
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct FixtureImportLease {
generation: u64,
authority: Box<FixtureImportAuthority>,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum FixtureImporterRegistryError {
Busy,
Registration,
}
pub struct FixtureImporterRegistry<I> {
importer: Option<I>,
generation: u64,
active: Option<FixtureImportLease>,
}
impl<I: Copy> FixtureImporterRegistry<I> {
pub const fn new() -> Self {
Self {
importer: None,
generation: 0,
active: None,
}
}
#[cfg(feature = "internal-test-fixtures")]
pub const fn fetch_in_flight(&self) -> bool {
self.active.is_some()
}
pub const fn register(&mut self, importer: I) -> Result<(), FixtureImporterRegistryError> {
if self.importer.is_some() {
return Err(FixtureImporterRegistryError::Registration);
}
self.importer = Some(importer);
Ok(())
}
pub const fn importer(&self) -> Option<I> {
self.importer
}
pub fn acquire(
&mut self,
authority: FixtureImportAuthority,
) -> Result<FixtureImportLease, FixtureImporterRegistryError> {
if self.active.is_some() {
return Err(FixtureImporterRegistryError::Busy);
}
let generation = self
.generation
.checked_add(1)
.ok_or(FixtureImporterRegistryError::Busy)?;
let lease = FixtureImportLease {
generation,
authority: Box::new(authority),
};
self.generation = generation;
self.active = Some(lease.clone());
Ok(lease)
}
pub fn abandon(&mut self) {
self.active = None;
}
pub fn is_current(&self, lease: &FixtureImportLease) -> bool {
self.active.as_ref() == Some(lease)
}
pub fn release(&mut self, lease: &FixtureImportLease) {
if self.is_current(lease) {
self.active = None;
}
}
}