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中使用
26KB
521 行
variant-counter
用于计数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