use super::UiState;
const PRICES: &str = "prices";
impl UiState {
pub fn prices(&self) -> crate::spend::Prices {
match self.world.root.get(PRICES) {
Some(value) => crate::spend::Prices::from_json(value),
None => crate::spend::Prices::default(),
}
}
}
#[cfg(test)]
mod tests {
use crate::budgets::BudgetSpend;
use crate::ui_state::UiState;
use tempfile::tempdir;
fn opened(doc: &str) -> UiState {
let dir = tempdir().unwrap();
let path = dir.path().join("ui.json");
std::fs::write(&path, doc).unwrap();
UiState::open(path)
}
#[test]
fn absent_table_is_empty() {
assert!(opened(r#"{"v":1}"#).prices().is_empty());
}
#[test]
fn wrong_shape_is_empty() {
assert!(opened(r#"{"v":1,"prices":"nope"}"#).prices().is_empty());
}
#[test]
fn reads_rates_for_a_model() {
let prices = opened(
r#"{"v":1,"prices":{"opus":{"input":15,"output":75,
"cache_read":1.5,"cache_write":18.75}}}"#,
)
.prices();
let price = prices.of(Some("opus")).unwrap();
assert_eq!(price.input, 15_000_000);
assert_eq!(price.cache_write, 18_750_000);
assert_eq!(
price.cost(BudgetSpend {
input_tokens: 1_000_000,
..BudgetSpend::default()
}),
15_000_000
);
}
}