#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
Hash,
PartialOrd,
Ord,
otel_arrow_dfe_telemetry_macros::AttributeEnum,
)]
pub enum AdmissionDimension {
Bytes,
Messages,
}
impl AdmissionDimension {
pub const ALL: &'static [AdmissionDimension] =
&[AdmissionDimension::Bytes, AdmissionDimension::Messages];
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::Bytes => "bytes",
Self::Messages => "messages",
}
}
const fn bit(self) -> u32 {
match self {
Self::Bytes => 1 << 0,
Self::Messages => 1 << 1,
}
}
}
impl std::fmt::Display for AdmissionDimension {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct AdmissionDimensionSet(u32);
impl AdmissionDimensionSet {
pub const EMPTY: Self = Self(0);
#[must_use]
pub const fn single(dimension: AdmissionDimension) -> Self {
Self(dimension.bit())
}
#[must_use]
pub const fn with(self, dimension: AdmissionDimension) -> Self {
Self(self.0 | dimension.bit())
}
#[must_use]
pub const fn contains(self, dimension: AdmissionDimension) -> bool {
self.0 & dimension.bit() != 0
}
#[must_use]
pub const fn is_empty(self) -> bool {
self.0 == 0
}
#[must_use]
pub fn to_display_string(self) -> String {
let members: Vec<&'static str> = AdmissionDimension::ALL
.iter()
.filter(|dimension| self.contains(**dimension))
.map(|dimension| dimension.as_str())
.collect();
format!("[{}]", members.join(", "))
}
}
impl FromIterator<AdmissionDimension> for AdmissionDimensionSet {
fn from_iter<I: IntoIterator<Item = AdmissionDimension>>(iter: I) -> Self {
iter.into_iter()
.fold(Self::EMPTY, |set, dimension| set.with(dimension))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn dimension_set_reports_every_advertised_member() {
let set = AdmissionDimensionSet::single(AdmissionDimension::Bytes)
.with(AdmissionDimension::Messages);
assert!(set.contains(AdmissionDimension::Bytes));
assert!(set.contains(AdmissionDimension::Messages));
assert!(!set.is_empty());
}
#[test]
fn dimension_set_excludes_unadvertised_members() {
let set = AdmissionDimensionSet::single(AdmissionDimension::Messages);
assert!(!set.contains(AdmissionDimension::Bytes));
assert!(set.contains(AdmissionDimension::Messages));
}
#[test]
fn empty_dimension_set_contains_nothing() {
let set = AdmissionDimensionSet::EMPTY;
assert!(set.is_empty());
for dimension in AdmissionDimension::ALL {
assert!(!set.contains(*dimension));
}
}
#[test]
fn dimension_set_display_is_stable_and_ordered() {
let set: AdmissionDimensionSet = [AdmissionDimension::Messages, AdmissionDimension::Bytes]
.into_iter()
.collect();
assert_eq!(set.to_display_string(), "[bytes, messages]");
assert_eq!(
AdmissionDimensionSet::EMPTY.to_display_string(),
"[]".to_owned()
);
}
}