1use std::fmt;
2
3use bloq_circuit::DetectorParity;
4
5pub(super) fn pool_index(index: usize) -> u32 {
6 u32::try_from(index).expect("append-only pool id space exhausted")
7}
8
9pub(super) fn deserialize_pool<'de, D, T>(
10 deserializer: D,
11) -> Result<Vec<std::sync::Arc<T>>, D::Error>
12where
13 D: serde::Deserializer<'de>,
14 T: serde::Deserialize<'de>,
15{
16 let entries = <Vec<std::sync::Arc<T>> as serde::Deserialize>::deserialize(deserializer)?;
17 if let Some(last) = entries.len().checked_sub(1) {
18 u32::try_from(last)
19 .map_err(|_| serde::de::Error::custom("append-only pool id space exhausted"))?;
20 }
21 Ok(entries)
22}
23
24#[derive(
33 Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, serde::Serialize, serde::Deserialize,
34)]
35pub struct BloqNodeId(pub u32);
36
37#[derive(
39 Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, serde::Serialize, serde::Deserialize,
40)]
41pub struct TemplateId(pub u32);
42
43#[derive(
45 Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, serde::Serialize, serde::Deserialize,
46)]
47pub struct DetectorBundleId(pub u32);
48
49#[derive(
52 Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, serde::Serialize, serde::Deserialize,
53)]
54pub struct TemplateInstanceId(pub u32);
55
56#[derive(
59 Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, serde::Serialize, serde::Deserialize,
60)]
61pub struct InstanceMeasurement {
62 pub instance: TemplateInstanceId,
64 pub measurement: u32,
66}
67
68impl fmt::Display for InstanceMeasurement {
69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70 write!(f, "i{}:m{}", self.instance.0, self.measurement)
71 }
72}
73
74pub type TemplateDetectorParity = DetectorParity<u32>;
76pub type NodeDetectorParity = DetectorParity<InstanceMeasurement>;
79
80#[cfg(test)]
81mod tests {
82 #[test]
83 fn pool_indices_never_alias_after_exhaustion() {
84 assert_eq!(super::pool_index(u32::MAX as usize), u32::MAX);
85 if let Some(exhausted) = (u32::MAX as usize).checked_add(1) {
86 std::panic::catch_unwind(|| super::pool_index(exhausted))
87 .expect_err("an exhausted append-only pool must refuse insertion");
88 }
89 }
90}