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 日 |
1353 在 Rust 模式 中
每月 25 次下载
17KB
57 行
variant-counter
用于计算 Rust 枚举变体的高效且优雅的库。
开始使用
#[派生(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
包支持。默认启用。请禁用此功能以支持no_std
。
依赖关系
~1.5MB
~35K SLoC