seher/opencode_go/
types.rs1use chrono::{DateTime, Utc};
2
3const LIMIT_EPSILON: f64 = 1e-9;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum OpencodeGoUsageSource {
7 LocalDatabase,
8}
9
10#[derive(Debug, Clone, PartialEq)]
11pub struct OpencodeGoUsageWindow {
12 pub entry_type: &'static str,
13 pub spent_usd: f64,
14 pub limit_usd: f64,
15 pub resets_at: Option<DateTime<Utc>>,
16}
17
18impl OpencodeGoUsageWindow {
19 #[must_use]
22 pub fn is_limited(&self) -> bool {
23 self.limit_usd > 0.0 && self.spent_usd + LIMIT_EPSILON >= self.limit_usd
24 }
25
26 #[must_use]
27 pub fn utilization(&self) -> f64 {
28 if self.limit_usd <= 0.0 {
29 0.0
30 } else {
31 self.spent_usd / self.limit_usd * 100.0
32 }
33 }
34}
35
36#[derive(Debug, Clone, PartialEq)]
37pub struct OpencodeGoUsageSnapshot {
38 pub source: OpencodeGoUsageSource,
39 pub credentials_available: bool,
40 pub total_messages: usize,
41 pub windows: Vec<OpencodeGoUsageWindow>,
42}
43
44impl OpencodeGoUsageSnapshot {
45 #[must_use]
46 pub fn reset_time(&self) -> Option<DateTime<Utc>> {
47 self.windows
48 .iter()
49 .filter(|window| window.is_limited())
50 .filter_map(|window| window.resets_at)
51 .max()
52 }
53}