Skip to main content

ai_lib_rust/tokens/
pricing.rs

1//! Model pricing and cost estimation.
2
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct ModelPricing { pub model: String, pub input_cost_per_1k: f64, pub output_cost_per_1k: f64, pub currency: String }
7
8impl ModelPricing {
9    pub fn new(model: &str, input: f64, output: f64) -> Self { Self { model: model.into(), input_cost_per_1k: input, output_cost_per_1k: output, currency: "USD".into() } }
10    pub fn calculate_cost(&self, input_tokens: u32, output_tokens: u32) -> CostEstimate {
11        let ic = (input_tokens as f64 / 1000.0) * self.input_cost_per_1k;
12        let oc = (output_tokens as f64 / 1000.0) * self.output_cost_per_1k;
13        CostEstimate { model: self.model.clone(), input_tokens, output_tokens, input_cost: ic, output_cost: oc, total_cost: ic + oc, currency: self.currency.clone() }
14    }
15    pub fn gpt_4o() -> Self { Self::new("gpt-4o", 0.005, 0.015) }
16    pub fn gpt_4o_mini() -> Self { Self::new("gpt-4o-mini", 0.00015, 0.0006) }
17    pub fn claude_35_sonnet() -> Self { Self::new("claude-3-5-sonnet", 0.003, 0.015) }
18    pub fn claude_3_haiku() -> Self { Self::new("claude-3-haiku", 0.00025, 0.00125) }
19    pub fn for_model(model: &str) -> Option<Self> {
20        let m = model.to_lowercase();
21        if m.contains("gpt-4o-mini") { Some(Self::gpt_4o_mini()) }
22        else if m.contains("gpt-4o") { Some(Self::gpt_4o()) }
23        else if m.contains("claude-3-5-sonnet") { Some(Self::claude_35_sonnet()) }
24        else if m.contains("claude-3-haiku") { Some(Self::claude_3_haiku()) }
25        else { None }
26    }
27}
28
29#[derive(Debug, Clone, Serialize, Deserialize)]
30pub struct CostEstimate { pub model: String, pub input_tokens: u32, pub output_tokens: u32, pub input_cost: f64, pub output_cost: f64, pub total_cost: f64, pub currency: String }
31
32impl CostEstimate {
33    pub fn format(&self) -> String { format!("{} {:.6}", self.currency, self.total_cost) }
34    pub fn format_detailed(&self) -> String { if self.total_cost < 0.01 { format!("{:.4}ยข", self.total_cost * 100.0) } else { format!("${:.4}", self.total_cost) } }
35}