1use std::time::Duration;
7
8use clap::ValueEnum;
9
10use crate::usage::VendorSnapshot;
11use crate::widget::cli::Cli;
12
13pub const HTTP_CLIENT_TIMEOUT: Duration = Duration::from_secs(30);
16
17#[derive(
19 Debug, Clone, Copy, ValueEnum, PartialEq, Eq, Hash, serde::Deserialize, serde::Serialize,
20)]
21#[serde(rename_all = "lowercase")]
22pub enum VendorId {
23 Anthropic,
24 Openai,
25 Zai,
26 Openrouter,
27}
28
29impl VendorId {
30 pub fn slug(self) -> &'static str {
31 match self {
32 VendorId::Anthropic => "anthropic",
33 VendorId::Openai => "openai",
34 VendorId::Zai => "zai",
35 VendorId::Openrouter => "openrouter",
36 }
37 }
38
39 pub fn all() -> &'static [VendorId] {
40 &[
41 VendorId::Anthropic,
42 VendorId::Openai,
43 VendorId::Zai,
44 VendorId::Openrouter,
45 ]
46 }
47}
48
49#[derive(Debug, Clone)]
52pub struct VendorOutcome {
53 pub snapshot: VendorSnapshot,
54 pub stale: bool,
55 pub last_error: Option<(u16, String)>,
56 pub cache_age: Option<std::time::Duration>,
57}
58
59#[derive(Debug, Clone)]
61pub struct RenderOpts {
62 pub format: Option<String>,
63 pub tooltip_format: Option<String>,
64 pub icon: Option<String>,
65 pub pace_tolerance: u32,
66 pub format_pace_color: bool,
67 pub tooltip_pace_pts: bool,
68}
69
70impl RenderOpts {
71 pub fn from_cli(cli: &Cli) -> Self {
72 Self {
73 format: cli.format.clone(),
74 tooltip_format: cli.tooltip_format.clone(),
75 icon: cli.icon.clone(),
76 pace_tolerance: cli.pace_tolerance,
77 format_pace_color: cli.format_pace_color,
78 tooltip_pace_pts: cli.tooltip_pace_pts,
79 }
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86
87 #[test]
88 fn vendor_id_slug_round_trip() {
89 for id in VendorId::all() {
90 assert_eq!(
91 id.slug(),
92 serde_json::to_value(id).unwrap().as_str().unwrap()
93 );
94 }
95 }
96}