pub mod claude;
pub mod google;
pub mod openai;
pub mod registry;
use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TokenCount {
Estimated(usize),
Exact(usize),
}
impl TokenCount {
pub fn value(&self) -> usize {
match self {
Self::Estimated(n) | Self::Exact(n) => *n,
}
}
pub fn is_estimated(&self) -> bool {
matches!(self, Self::Estimated(_))
}
pub fn is_exact(&self) -> bool {
matches!(self, Self::Exact(_))
}
}
impl fmt::Display for TokenCount {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Estimated(n) => write!(f, "~{}", n),
Self::Exact(n) => write!(f, "{}", n),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TokenDetail {
pub id: u32,
pub text: String,
}
pub trait Tokenizer: Send + Sync {
fn count_tokens(&self, text: &str) -> anyhow::Result<usize>;
fn get_model_info(&self) -> ModelInfo;
fn encode_with_details(&self, _text: &str) -> anyhow::Result<Option<Vec<TokenDetail>>> {
Ok(None)
}
}
#[derive(Debug, Clone)]
pub struct ModelInfo {
pub name: String,
pub encoding: String,
pub context_window: usize,
pub description: String,
}
impl fmt::Display for ModelInfo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} ({})", self.name, self.encoding)
}
}
#[derive(Debug, Clone)]
pub struct TokenizationResult {
pub token_count: usize,
pub model_info: ModelInfo,
pub token_details: Option<Vec<TokenDetail>>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_token_count_display_estimated() {
let count = TokenCount::Estimated(42);
assert_eq!(format!("{}", count), "~42");
}
#[test]
fn test_token_count_display_exact() {
let count = TokenCount::Exact(42);
assert_eq!(format!("{}", count), "42");
}
#[test]
fn test_token_count_value() {
assert_eq!(TokenCount::Estimated(42).value(), 42);
assert_eq!(TokenCount::Exact(42).value(), 42);
}
#[test]
fn test_token_count_is_estimated() {
assert!(TokenCount::Estimated(42).is_estimated());
assert!(!TokenCount::Exact(42).is_estimated());
}
#[test]
fn test_token_count_is_exact() {
assert!(!TokenCount::Estimated(42).is_exact());
assert!(TokenCount::Exact(42).is_exact());
}
#[test]
fn test_token_count_equality() {
assert_eq!(TokenCount::Estimated(42), TokenCount::Estimated(42));
assert_eq!(TokenCount::Exact(42), TokenCount::Exact(42));
assert_ne!(TokenCount::Estimated(42), TokenCount::Exact(42));
}
}