#枚举 #变体 #计数器 #擦除 #检查 #默认 #variant-counter

无std variant_counter_derived

Rust的枚举变体计数器

6个版本 (3个破坏性更新)

0.4.0 2021年9月15日
0.3.0 2021年8月16日
0.2.2 2021年8月13日
0.1.0 2021年8月11日

#erase中排名第9

每月下载量37
variant_counter中使用

MIT许可证

26KB
521

variant-counter

Crates.io docs.rs

用于计数Rust枚举变体的高效且优雅的crate。

开始使用

#[derive(VariantCount)]

#[derive(VariantCount)]
pub enum Enum {
    Variant1,
    Variant2,
}

记录你的变体

let mut counter = Enum::counter();
counter.record(&Enum::Variant1);

使用erase_*()方法擦除记录

counter.erase_variant1();

这些erase_*()方法在erase功能标志下,默认禁用。

使用check_*()方法检查记录

assert_eq!(counter.check_variant1(), 1);

这些check_*()方法在check功能标志下,默认禁用。

使用discard()reset()数据

// Clear the `Enum::Variant1`'s data.
counter.discard(&Enum::Variant1);

// Clear all variants data.
counter.reset();

忽略一个变体

#[derive(VariantCount)]
pub enum Level {
    #[counter(ignore)]
    Trace,
    Debug,
    Info,
    Warn,
    Error,
}

如果一个变体被忽略,则在记录该变体时不会产生影响。

let mut counter = Level::counter();
// Record nothing...
counter.record(&Level::Trace);

聚合你的数据

let data = counter.aggregate();

分组变体

#[derive(VariantCount)]
pub enum Platform {
    #[counter(group = "Mobile")]
    Android,
    #[counter(group = "Mobile")]
    IOS,
    #[counter(group = "Desktop")]
    Windows,
    #[counter(group = "Desktop")]
    Linux,
    #[counter(group = "Desktop")]
    MacOS,
    #[counter(group = "Desktop")]
    ChromeOS,
    Others,
}

let counter = Platform::counter();
// Group version of aggregate method
let group_data = counter.group_aggregate();

统计

// Sum
counter.sum();

// Average
counter.avg();

// Variance
counter.variance();

// Standard deviation
counter.sd();

加权

#[derive(VariantCount)]
enum Rating {
    #[counter(weight = 1)]
    Hated,
    #[counter(weight = 2)]
    Disliked,
    #[counter(weight = 3)]
    Ok,
    #[counter(weight = 4)]
    Liked,
    #[counter(weight = 5)]
    Loved,
}

let mut counter = Rating::counter();
counter.record(&Rating::Loved);

let w = counter.weighted();

// Sum
w.sum();

// Average
w.avg();

// Variance
w.variance();

// Standard deviation
w.sd();

宏展开

你可以使用carg-expand来展开派生的VariantCount宏。以下是展开的代码

enum Enum {
    Variant1,
    Variant2,
}
impl Enum {
    #[inline]
    const fn variant_count() -> usize {
        2usize
    }
}
impl variant_counter::VariantCount for Enum {
    type Counter = EnumCounter;
    fn counter() -> Self::Counter {
        EnumCounter::new()
    }
}
/// The concrete counter struct auto-generated by macro.
#[must_use]
struct EnumCounter {
    /// An array store the frequency of each variant which not be ignored.
    frequency: [usize; 2usize],
}
impl EnumCounter {
    const fn new() -> EnumCounter {
        EnumCounter {
            frequency: [0; 2usize],
        }
    }
    /// Record a variant. It has no effect if you record an ignored variant.
    fn record(&mut self, target: &Enum) {
        let pair = match target {
            Enum::Variant1 => Some(0usize),
            Enum::Variant2 => Some(1usize),
            _ => None,
        };
        if let Some(index) = pair {
            self.frequency[index] = self.frequency[index].saturating_add(1);
        }
    }
    /// Discard the record of the target variant.
    /// It has no effect if you discard an ignored variant.
    fn discard(&mut self, target: &Enum) {
        let index = match target {
            Enum::Variant1 => Some(0usize),
            Enum::Variant2 => Some(1usize),
            _ => None,
        };
        if let Some(index) = index {
            self.frequency[index] = 0;
        }
    }
    /// Reset the records.
    fn reset(&mut self) {
        self.frequency = [0; 2usize];
    }
    /// Aggregate the data to a HashMap.
    #[cfg(feature = "std")]
    fn aggregate(&self) -> std::collections::HashMap<&'static str, usize> {
        IntoIterator::into_iter([
            ("Variant1", self.frequency[0usize]),
            ("Variant2", self.frequency[1usize]),
        ])
        .collect()
    }
    /// Get the sum of frequency.
    #[inline]
    fn sum(&self) -> usize {
        self.frequency.iter().sum()
    }
}

功能标志

  • full:启用所有功能。

  • check:为变体生成check方法。

  • erase:为变体生成erase方法。

  • stats:生成统计方法,例如 avg()variance(),以及 sd() 等。

  • std:启用 std crate 支持。默认启用。请禁用此功能以支持 no_std

依赖项

~1.5MB
~35K SLoC