anthropic_async/types/
common.rs1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
8#[serde(rename_all = "snake_case")]
9pub enum CacheTtl {
10 #[serde(rename = "5m")]
12 FiveMinutes,
13 #[serde(rename = "1h")]
15 OneHour,
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
23pub struct CacheControl {
24 #[serde(rename = "type")]
26 pub kind: String,
27 #[serde(skip_serializing_if = "Option::is_none")]
29 pub ttl: Option<CacheTtl>,
30}
31
32impl CacheControl {
33 #[must_use]
35 pub fn ephemeral_5m() -> Self {
36 Self {
37 kind: "ephemeral".into(),
38 ttl: Some(CacheTtl::FiveMinutes),
39 }
40 }
41
42 #[must_use]
44 pub fn ephemeral_1h() -> Self {
45 Self {
46 kind: "ephemeral".into(),
47 ttl: Some(CacheTtl::OneHour),
48 }
49 }
50
51 #[must_use]
53 pub fn ephemeral() -> Self {
54 Self {
55 kind: "ephemeral".into(),
56 ttl: None,
57 }
58 }
59}
60
61#[must_use]
63pub fn validate_mixed_ttl_order(block_ttls: impl IntoIterator<Item = CacheTtl>) -> bool {
64 let mut seen_5m = false;
65 for ttl in block_ttls {
66 match ttl {
67 CacheTtl::OneHour if seen_5m => return false, CacheTtl::FiveMinutes => seen_5m = true,
69 CacheTtl::OneHour => {}
70 }
71 }
72 true
73}
74
75#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
79pub struct Metadata {
80 #[serde(skip_serializing_if = "Option::is_none")]
82 pub user_id: Option<String>,
83}
84
85#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
89pub struct Usage {
90 pub input_tokens: Option<u64>,
92 pub output_tokens: Option<u64>,
94 pub cache_creation_input_tokens: Option<u64>,
96 pub cache_read_input_tokens: Option<u64>,
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn ttl_ser_de() {
106 let s = serde_json::to_string(&CacheTtl::FiveMinutes).unwrap();
107 assert_eq!(s, r#""5m""#);
108 let t: CacheTtl = serde_json::from_str(r#""1h""#).unwrap();
109 assert_eq!(t, CacheTtl::OneHour);
110 }
111
112 #[test]
113 fn cache_control_ser() {
114 let cc = CacheControl::ephemeral_5m();
115 let s = serde_json::to_string(&cc).unwrap();
116 assert!(s.contains(r#""type":"ephemeral""#));
117 assert!(s.contains(r#""ttl":"5m""#));
118 }
119
120 #[test]
121 fn ordering_valid() {
122 assert!(validate_mixed_ttl_order([
123 CacheTtl::OneHour,
124 CacheTtl::FiveMinutes
125 ]));
126 assert!(validate_mixed_ttl_order([CacheTtl::FiveMinutes]));
127 assert!(validate_mixed_ttl_order([CacheTtl::OneHour]));
128 assert!(!validate_mixed_ttl_order([
129 CacheTtl::FiveMinutes,
130 CacheTtl::OneHour
131 ]));
132 }
133}