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