async_graphql/registry/
cache_control.rs

1/// Cache control value
2///
3/// # Examples
4///
5/// ```rust
6/// use async_graphql::*;
7///
8/// struct Query;
9///
10/// #[Object(cache_control(max_age = 60))]
11/// impl Query {
12///     #[graphql(cache_control(max_age = 30))]
13///     async fn value1(&self) -> i32 {
14///         0
15///     }
16///
17///     #[graphql(cache_control(private))]
18///     async fn value2(&self) -> i32 {
19///         0
20///     }
21///
22///     #[graphql(cache_control(no_cache))]
23///     async fn value3(&self) -> i32 {
24///         0
25///     }
26/// }
27///
28/// # tokio::runtime::Runtime::new().unwrap().block_on(async {
29/// let schema = Schema::new(Query, EmptyMutation, EmptySubscription);
30/// assert_eq!(
31///     schema
32///         .execute("{ value1 }")
33///         .await
34///         .into_result()
35///         .unwrap()
36///         .cache_control,
37///     CacheControl {
38///         public: true,
39///         max_age: 30
40///     }
41/// );
42///
43/// assert_eq!(
44///     schema
45///         .execute("{ value2 }")
46///         .await
47///         .into_result()
48///         .unwrap()
49///         .cache_control,
50///     CacheControl {
51///         public: false,
52///         max_age: 60
53///     }
54/// );
55///
56/// assert_eq!(
57///     schema
58///         .execute("{ value1 value2 }")
59///         .await
60///         .into_result()
61///         .unwrap()
62///         .cache_control,
63///     CacheControl {
64///         public: false,
65///         max_age: 30
66///     }
67/// );
68///
69/// assert_eq!(
70///     schema
71///         .execute("{ value1 value2 value3 }")
72///         .await
73///         .into_result()
74///         .unwrap()
75///         .cache_control,
76///     CacheControl {
77///         public: false,
78///         max_age: -1
79///     }
80/// );
81/// # });
82/// ```
83#[derive(Clone, Copy, PartialEq, Eq, Debug)]
84pub struct CacheControl {
85    /// Scope is public, default is true.
86    pub public: bool,
87
88    /// Cache max age, `-1` represent `no-cache`, default is 0.
89    pub max_age: i32,
90}
91
92impl Default for CacheControl {
93    fn default() -> Self {
94        Self {
95            public: true,
96            max_age: 0,
97        }
98    }
99}
100
101impl CacheControl {
102    /// Get 'Cache-Control' header value.
103    #[must_use]
104    pub fn value(&self) -> Option<String> {
105        let mut value = if self.max_age > 0 {
106            format!("max-age={}", self.max_age)
107        } else if self.max_age == -1 {
108            "no-cache".to_string()
109        } else {
110            String::new()
111        };
112
113        if !self.public {
114            if !value.is_empty() {
115                value += ", ";
116            }
117            value += "private";
118        }
119
120        if !value.is_empty() { Some(value) } else { None }
121    }
122}
123
124impl CacheControl {
125    #[must_use]
126    pub(crate) fn merge(self, other: &CacheControl) -> CacheControl {
127        CacheControl {
128            public: self.public && other.public,
129            max_age: match (self.max_age, other.max_age) {
130                (-1, _) => -1,
131                (_, -1) => -1,
132                (a, 0) => a,
133                (0, b) => b,
134                (a, b) => a.min(b),
135            },
136        }
137    }
138}
139
140#[cfg(test)]
141mod tests {
142    use super::*;
143
144    #[test]
145    fn to_value() {
146        assert_eq!(
147            CacheControl {
148                public: true,
149                max_age: 0,
150            }
151            .value(),
152            None
153        );
154
155        assert_eq!(
156            CacheControl {
157                public: false,
158                max_age: 0,
159            }
160            .value(),
161            Some("private".to_string())
162        );
163
164        assert_eq!(
165            CacheControl {
166                public: false,
167                max_age: 10,
168            }
169            .value(),
170            Some("max-age=10, private".to_string())
171        );
172
173        assert_eq!(
174            CacheControl {
175                public: true,
176                max_age: 10,
177            }
178            .value(),
179            Some("max-age=10".to_string())
180        );
181
182        assert_eq!(
183            CacheControl {
184                public: true,
185                max_age: -1,
186            }
187            .value(),
188            Some("no-cache".to_string())
189        );
190
191        assert_eq!(
192            CacheControl {
193                public: false,
194                max_age: -1,
195            }
196            .value(),
197            Some("no-cache, private".to_string())
198        );
199    }
200}