anthropic_tools/common/
usage.rs1use serde::{Deserialize, Serialize};
35
36#[derive(Debug, Clone, Default, Serialize, Deserialize)]
38pub struct Usage {
39 pub input_tokens: usize,
41
42 pub output_tokens: usize,
44
45 #[serde(skip_serializing_if = "Option::is_none")]
47 pub cache_creation_input_tokens: Option<usize>,
48
49 #[serde(skip_serializing_if = "Option::is_none")]
51 pub cache_read_input_tokens: Option<usize>,
52}
53
54impl Usage {
55 pub fn new(input_tokens: usize, output_tokens: usize) -> Self {
57 Self {
58 input_tokens,
59 output_tokens,
60 cache_creation_input_tokens: None,
61 cache_read_input_tokens: None,
62 }
63 }
64
65 pub fn total_tokens(&self) -> usize {
67 self.input_tokens + self.output_tokens
68 }
69
70 pub fn cached_tokens(&self) -> usize {
72 self.cache_creation_input_tokens.unwrap_or(0) + self.cache_read_input_tokens.unwrap_or(0)
73 }
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79
80 #[test]
81 fn test_usage_new() {
82 let usage = Usage::new(100, 50);
83 assert_eq!(usage.input_tokens, 100);
84 assert_eq!(usage.output_tokens, 50);
85 assert_eq!(usage.total_tokens(), 150);
86 }
87
88 #[test]
89 fn test_usage_deserialize() {
90 let json = r#"{
91 "input_tokens": 100,
92 "output_tokens": 50,
93 "cache_creation_input_tokens": 10,
94 "cache_read_input_tokens": 20
95 }"#;
96
97 let usage: Usage = serde_json::from_str(json).unwrap();
98 assert_eq!(usage.input_tokens, 100);
99 assert_eq!(usage.output_tokens, 50);
100 assert_eq!(usage.cache_creation_input_tokens, Some(10));
101 assert_eq!(usage.cache_read_input_tokens, Some(20));
102 assert_eq!(usage.cached_tokens(), 30);
103 }
104
105 #[test]
106 fn test_usage_serialize() {
107 let usage = Usage::new(100, 50);
108 let json = serde_json::to_string(&usage).unwrap();
109 assert!(json.contains("\"input_tokens\":100"));
110 assert!(json.contains("\"output_tokens\":50"));
111 assert!(!json.contains("cache_creation_input_tokens"));
113 assert!(!json.contains("cache_read_input_tokens"));
114 }
115}