code-moniker-workspace 0.4.0

Workspace model, ports, snapshots, linkage, and change analysis for code-moniker.
Documentation
use std::sync::Arc;

use crate::live::WorkspaceLiveRefreshPlan;
use crate::snapshot::{
	ResourceGeneration, WorkspaceFailure, WorkspaceResult, WorkspaceSnapshot, WorkspaceTransition,
};

pub(crate) struct WorkspaceState {
	next_generation: u64,
	snapshot: Option<Arc<WorkspaceSnapshot>>,
	last_failure: Option<WorkspaceFailure>,
	pub(crate) pending: WorkspaceLiveRefreshPlan,
}

impl WorkspaceState {
	pub(crate) fn new() -> Self {
		Self {
			next_generation: 1,
			snapshot: None,
			last_failure: None,
			pending: WorkspaceLiveRefreshPlan::default(),
		}
	}

	pub(crate) fn allocate_generation(&mut self) -> ResourceGeneration {
		let generation = ResourceGeneration::new(self.next_generation);
		self.next_generation += 1;
		generation
	}

	pub(crate) fn publish(
		&mut self,
		result: WorkspaceResult<WorkspaceSnapshot>,
	) -> WorkspaceTransition {
		match result {
			Ok(snapshot) => self.publish_snapshot(snapshot),
			Err(failure) => self.publish_failure(failure),
		}
	}

	pub(crate) fn adopt_snapshot_arc(
		&mut self,
		snapshot: Arc<WorkspaceSnapshot>,
	) -> WorkspaceTransition {
		let generation = snapshot.generation;
		self.next_generation = self.next_generation.max(snapshot.generation.value() + 1);
		self.snapshot = Some(snapshot);
		self.last_failure = None;
		WorkspaceTransition::Ready { generation }
	}

	pub(crate) fn snapshot(&self) -> Option<&WorkspaceSnapshot> {
		self.snapshot.as_deref()
	}

	pub(crate) fn snapshot_arc(&self) -> Option<Arc<WorkspaceSnapshot>> {
		self.snapshot.clone()
	}

	pub(crate) fn last_failure(&self) -> Option<&WorkspaceFailure> {
		self.last_failure.as_ref()
	}

	fn publish_snapshot(&mut self, snapshot: WorkspaceSnapshot) -> WorkspaceTransition {
		let generation = snapshot.generation;
		self.snapshot = Some(Arc::new(snapshot));
		self.last_failure = None;
		WorkspaceTransition::Ready { generation }
	}

	fn publish_failure(&mut self, failure: WorkspaceFailure) -> WorkspaceTransition {
		let preserved_generation = self.snapshot.as_ref().map(|snapshot| snapshot.generation);
		self.last_failure = Some(failure.clone());
		WorkspaceTransition::Failed {
			failure,
			preserved_generation,
		}
	}
}