use core::fmt;
use core::num::NonZeroU32;
#[repr(transparent)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct VariableId(u32);
impl VariableId {
#[must_use]
pub const fn from_raw(raw: u32) -> Self {
Self(raw)
}
#[must_use]
pub const fn raw(self) -> u32 {
self.0
}
#[must_use]
pub const fn as_usize(self) -> usize {
self.0 as usize
}
}
impl fmt::Display for VariableId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "V{}", self.0)
}
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct EnvironmentId(u32);
impl EnvironmentId {
#[must_use]
pub const fn from_raw(raw: u32) -> Self {
Self(raw)
}
#[must_use]
pub const fn raw(self) -> u32 {
self.0
}
}
impl fmt::Display for EnvironmentId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "E{}", self.0)
}
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct DynamicRuleId(u32);
impl DynamicRuleId {
#[must_use]
pub const fn from_raw(raw: u32) -> Self {
Self(raw)
}
#[must_use]
pub const fn raw(self) -> u32 {
self.0
}
}
impl fmt::Display for DynamicRuleId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "DR{}", self.0)
}
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct DistributionRef(u32);
impl DistributionRef {
#[must_use]
pub const fn from_raw(raw: u32) -> Self {
Self(raw)
}
#[must_use]
pub const fn raw(self) -> u32 {
self.0
}
}
impl fmt::Display for DistributionRef {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "DRef{}", self.0)
}
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct RegimeId(u32);
impl RegimeId {
#[must_use]
pub const fn from_raw(raw: u32) -> Self {
Self(raw)
}
#[must_use]
pub const fn raw(self) -> u32 {
self.0
}
}
impl fmt::Display for RegimeId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "R{}", self.0)
}
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Lag(u32);
impl Lag {
pub const CONTEMPORANEOUS: Self = Self(0);
#[must_use]
pub const fn from_raw(raw: u32) -> Self {
Self(raw)
}
#[must_use]
pub const fn historical(steps: NonZeroU32) -> Self {
Self(steps.get())
}
#[must_use]
pub const fn raw(self) -> u32 {
self.0
}
#[must_use]
pub const fn is_contemporaneous(self) -> bool {
self.0 == 0
}
}
impl fmt::Display for Lag {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "L{}", self.0)
}
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct ComponentId(VariableId);
impl ComponentId {
#[must_use]
pub const fn from_variable(variable: VariableId) -> Self {
Self(variable)
}
#[must_use]
pub const fn variable(self) -> VariableId {
self.0
}
#[must_use]
pub const fn from_raw(raw: u32) -> Self {
Self(VariableId::from_raw(raw))
}
#[must_use]
pub const fn raw(self) -> u32 {
self.0.raw()
}
#[must_use]
pub const fn as_usize(self) -> usize {
self.0.as_usize()
}
}
impl fmt::Display for ComponentId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "C{}", self.0.raw())
}
}
impl From<VariableId> for ComponentId {
fn from(variable: VariableId) -> Self {
Self::from_variable(variable)
}
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct CategoryDomainId(u32);
impl CategoryDomainId {
#[must_use]
pub const fn from_raw(raw: u32) -> Self {
Self(raw)
}
#[must_use]
pub const fn raw(self) -> u32 {
self.0
}
}
impl fmt::Display for CategoryDomainId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "C{}", self.0)
}
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct QueryId(u32);
impl QueryId {
#[must_use]
pub const fn from_raw(raw: u32) -> Self {
Self(raw)
}
#[must_use]
pub const fn raw(self) -> u32 {
self.0
}
#[must_use]
pub const fn as_usize(self) -> usize {
self.0 as usize
}
}
impl fmt::Display for QueryId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Q{}", self.0)
}
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct ModelId(u32);
impl ModelId {
#[must_use]
pub const fn from_raw(raw: u32) -> Self {
Self(raw)
}
#[must_use]
pub const fn raw(self) -> u32 {
self.0
}
#[must_use]
pub const fn as_usize(self) -> usize {
self.0 as usize
}
}
impl fmt::Display for ModelId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "M{}", self.0)
}
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
pub struct StateVersion(u64);
impl StateVersion {
pub const ZERO: Self = Self(0);
#[must_use]
pub const fn from_raw(raw: u64) -> Self {
Self(raw)
}
#[must_use]
pub const fn raw(self) -> u64 {
self.0
}
#[must_use]
pub const fn next(self) -> Self {
Self(self.0.wrapping_add(1))
}
}
impl fmt::Display for StateVersion {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "S{}", self.0)
}
}
#[cfg(test)]
mod tests {
use super::*;
use core::mem::size_of;
#[test]
fn ids_are_copyable_and_compact() {
assert_eq!(size_of::<VariableId>(), 4);
assert_eq!(size_of::<EnvironmentId>(), 4);
assert_eq!(size_of::<DynamicRuleId>(), 4);
assert_eq!(size_of::<DistributionRef>(), 4);
assert_eq!(size_of::<RegimeId>(), 4);
assert_eq!(size_of::<Lag>(), 4);
assert_eq!(size_of::<CategoryDomainId>(), 4);
assert_eq!(size_of::<ComponentId>(), 4);
assert_eq!(size_of::<QueryId>(), 4);
assert_eq!(size_of::<ModelId>(), 4);
assert_eq!(size_of::<StateVersion>(), 8);
}
#[test]
fn lag_zero_is_contemporaneous() {
assert!(Lag::CONTEMPORANEOUS.is_contemporaneous());
assert!(!Lag::historical(NonZeroU32::new(1).expect("nonzero")).is_contemporaneous());
}
}