use std::sync::Arc;
use crate::link_network::LinkNetwork;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct NetworkSnapshot {
version: u64,
parent_version: Option<u64>,
provenance: String,
network: Arc<LinkNetwork>,
}
impl NetworkSnapshot {
#[must_use]
pub fn new(version: u64, network: LinkNetwork, provenance: impl Into<String>) -> Self {
Self {
version,
parent_version: None,
provenance: provenance.into(),
network: Arc::new(network),
}
}
#[must_use]
pub const fn version(&self) -> u64 {
self.version
}
#[must_use]
pub const fn parent_version(&self) -> Option<u64> {
self.parent_version
}
#[must_use]
pub fn provenance(&self) -> &str {
&self.provenance
}
#[must_use]
pub fn network(&self) -> &LinkNetwork {
self.network.as_ref()
}
#[must_use]
pub fn shared_snapshot_count(&self) -> usize {
Arc::strong_count(&self.network)
}
#[must_use]
pub fn to_mutable(&self, provenance: impl Into<String>) -> MutableNetworkSnapshot {
MutableNetworkSnapshot {
base_version: self.version,
network: self.network().clone(),
provenance: provenance.into(),
}
}
fn committed(
version: u64,
parent_version: u64,
network: LinkNetwork,
provenance: String,
) -> Self {
Self {
version,
parent_version: Some(parent_version),
provenance,
network: Arc::new(network),
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct MutableNetworkSnapshot {
base_version: u64,
network: LinkNetwork,
provenance: String,
}
impl MutableNetworkSnapshot {
#[must_use]
pub const fn base_version(&self) -> u64 {
self.base_version
}
#[must_use]
pub fn provenance(&self) -> &str {
&self.provenance
}
#[must_use]
pub const fn network(&self) -> &LinkNetwork {
&self.network
}
pub fn network_mut(&mut self) -> &mut LinkNetwork {
&mut self.network
}
#[must_use]
pub fn commit(self) -> NetworkSnapshot {
let next_version = self
.base_version
.checked_add(1)
.expect("snapshot version overflow");
self.commit_as(next_version)
}
#[must_use]
pub fn commit_as(self, version: u64) -> NetworkSnapshot {
assert!(
version > self.base_version,
"snapshot version must move forward"
);
NetworkSnapshot::committed(version, self.base_version, self.network, self.provenance)
}
}
impl LinkNetwork {
#[must_use]
pub fn snapshot(&self, version: u64, provenance: impl Into<String>) -> NetworkSnapshot {
NetworkSnapshot::new(version, self.clone(), provenance)
}
}