#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Statistics {
Fermionic,
Bosonic,
}
pub trait StatisticsType: Copy + Default {
const STATISTICS: Statistics;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct Fermionic;
impl StatisticsType for Fermionic {
const STATISTICS: Statistics = Statistics::Fermionic;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct Bosonic;
impl StatisticsType for Bosonic {
const STATISTICS: Statistics = Statistics::Bosonic;
}
pub trait StatisticsMarker {
fn statistics() -> Statistics;
}
impl StatisticsMarker for Fermionic {
fn statistics() -> Statistics {
Statistics::Fermionic
}
}
impl StatisticsMarker for Bosonic {
fn statistics() -> Statistics {
Statistics::Bosonic
}
}
impl Statistics {
pub fn is_fermionic(self) -> bool {
matches!(self, Statistics::Fermionic)
}
pub fn is_bosonic(self) -> bool {
matches!(self, Statistics::Bosonic)
}
pub fn as_str(self) -> &'static str {
match self {
Statistics::Fermionic => "fermionic",
Statistics::Bosonic => "bosonic",
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_statistics_type_trait() {
assert_eq!(Fermionic::STATISTICS, Statistics::Fermionic);
assert_eq!(Bosonic::STATISTICS, Statistics::Bosonic);
}
#[test]
fn test_statistics_marker_trait() {
assert_eq!(Fermionic::statistics(), Statistics::Fermionic);
assert_eq!(Bosonic::statistics(), Statistics::Bosonic);
}
#[test]
fn test_statistics_utility_methods() {
assert!(Statistics::Fermionic.is_fermionic());
assert!(!Statistics::Fermionic.is_bosonic());
assert!(!Statistics::Bosonic.is_fermionic());
assert!(Statistics::Bosonic.is_bosonic());
assert_eq!(Statistics::Fermionic.as_str(), "fermionic");
assert_eq!(Statistics::Bosonic.as_str(), "bosonic");
}
}