use alloy_primitives::Address;
use nectar_postage::{BatchId, StampDigest, StampError};
use nectar_postage_issuer::StampIssuer;
use nectar_primitives::SwarmAddress;
use crate::Snapshot;
use crate::error::UsageError;
const fn map_usage_error(err: UsageError) -> StampError {
match err {
UsageError::BucketFull { bucket, capacity } => StampError::BucketFull { bucket, capacity },
_ => StampError::InvalidIndex,
}
}
#[derive(Debug, Clone)]
pub struct SnapshotIssuer {
snapshot: Snapshot,
owner: Address,
}
impl SnapshotIssuer {
pub const fn new(snapshot: Snapshot, owner: Address) -> Self {
Self { snapshot, owner }
}
pub const fn snapshot(&self) -> &Snapshot {
&self.snapshot
}
pub const fn snapshot_mut(&mut self) -> &mut Snapshot {
&mut self.snapshot
}
pub fn into_snapshot(self) -> Snapshot {
self.snapshot
}
pub const fn owner(&self) -> Address {
self.owner
}
}
impl StampIssuer for SnapshotIssuer {
fn prepare_stamp(
&mut self,
address: &SwarmAddress,
timestamp: u64,
) -> core::result::Result<StampDigest, StampError> {
let index = self
.snapshot
.record_address(self.owner, address)
.map_err(map_usage_error)?;
Ok(StampDigest::new(
*address,
self.snapshot.table_ref().batch_id(),
index,
timestamp,
))
}
fn batch_id(&self) -> BatchId {
self.snapshot.table_ref().batch_id()
}
fn batch_depth(&self) -> u8 {
self.snapshot.table_ref().depth()
}
fn bucket_depth(&self) -> u8 {
self.snapshot.table_ref().bucket_depth()
}
fn max_bucket_utilization(&self) -> u32 {
self.snapshot.table_ref().max_count()
}
fn bucket_utilization(&self, bucket: u32) -> u32 {
self.snapshot.table_ref().count(bucket).unwrap_or(0)
}
fn bucket_has_capacity(&self, bucket: u32) -> bool {
self.snapshot.table_ref().is_mutable()
|| self
.snapshot
.table_ref()
.has_capacity(bucket)
.unwrap_or(false)
}
fn stamps_issued(&self) -> Option<u64> {
if self.snapshot.table_ref().is_mutable() {
None
} else {
Some(self.snapshot.table_ref().total_issued())
}
}
}