#![deny(missing_docs)]
type Estimator = Box<dyn FnMut(&str) -> u64 + Send>;
pub struct TokenStream {
estimator: Estimator,
count: u64,
chars: u64,
}
impl TokenStream {
pub fn new() -> Self {
Self::with_estimator(default_estimator)
}
pub fn with_estimator<F>(est: F) -> Self
where
F: FnMut(&str) -> u64 + Send + 'static,
{
Self {
estimator: Box::new(est),
count: 0,
chars: 0,
}
}
pub fn push(&mut self, chunk: &str) -> u64 {
self.chars += chunk.chars().count() as u64;
self.count += (self.estimator)(chunk);
self.count
}
pub fn count(&self) -> u64 {
self.count
}
pub fn chars(&self) -> u64 {
self.chars
}
pub fn reset(&mut self) {
self.count = 0;
self.chars = 0;
}
}
impl Default for TokenStream {
fn default() -> Self {
Self::new()
}
}
impl std::fmt::Debug for TokenStream {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("TokenStream")
.field("count", &self.count)
.field("chars", &self.chars)
.finish()
}
}
fn default_estimator(chunk: &str) -> u64 {
let chars = chunk.chars().count() as f64;
if chars == 0.0 {
0
} else {
(chars / 4.0).ceil() as u64
}
}