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() {
121            Some(value)
122        } else {
123            None
124        }
125    }
126}
127
128impl CacheControl {
129    #[must_use]
130    pub(crate) fn merge(self, other: &CacheControl) -> CacheControl {
131        CacheControl {
132            public: self.public && other.public,
133            max_age: match (self.max_age, other.max_age) {
134                (-1, _) => -1,
135                (_, -1) => -1,
136                (a, 0) => a,
137                (0, b) => b,
138                (a, b) => a.min(b),
139            },
140        }
141    }
142}
143
144#[cfg(test)]
145mod tests {
146    use super::*;
147
148    #[test]
149    fn to_value() {
150        assert_eq!(
151            CacheControl {
152                public: true,
153                max_age: 0,
154            }
155            .value(),
156            None
157        );
158
159        assert_eq!(
160            CacheControl {
161                public: false,
162                max_age: 0,
163            }
164            .value(),
165            Some("private".to_string())
166        );
167
168        assert_eq!(
169            CacheControl {
170                public: false,
171                max_age: 10,
172            }
173            .value(),
174            Some("max-age=10, private".to_string())
175        );
176
177        assert_eq!(
178            CacheControl {
179                public: true,
180                max_age: 10,
181            }
182            .value(),
183            Some("max-age=10".to_string())
184        );
185
186        assert_eq!(
187            CacheControl {
188                public: true,
189                max_age: -1,
190            }
191            .value(),
192            Some("no-cache".to_string())
193        );
194
195        assert_eq!(
196            CacheControl {
197                public: false,
198                max_age: -1,
199            }
200            .value(),
201            Some("no-cache, private".to_string())
202        );
203    }
204}