1use std::time::Duration;
2
3use chrono::{DateTime, Utc};
4
5#[derive(Debug, Clone, Copy)]
7pub struct RenderFreshness {
8 age: u64,
10 max_age: Option<u64>,
12 timestamp: DateTime<Utc>,
14}
15
16impl RenderFreshness {
17 pub(crate) fn new(age: u64, max_age: u64, timestamp: DateTime<Utc>) -> Self {
19 Self {
20 age,
21 max_age: Some(max_age),
22 timestamp,
23 }
24 }
25
26 pub(crate) fn new_age(age: u64, timestamp: DateTime<Utc>) -> Self {
28 Self {
29 age,
30 max_age: None,
31 timestamp,
32 }
33 }
34
35 pub(crate) fn created_at(timestamp: DateTime<Utc>, max_age: Option<Duration>) -> Self {
37 Self {
38 age: timestamp
39 .signed_duration_since(Utc::now())
40 .num_seconds()
41 .unsigned_abs(),
42 max_age: max_age.map(|d| d.as_secs()),
43 timestamp,
44 }
45 }
46
47 pub fn now(max_age: Option<Duration>) -> Self {
49 Self {
50 age: 0,
51 max_age: max_age.map(|d| d.as_secs()),
52 timestamp: Utc::now(),
53 }
54 }
55
56 pub fn age(&self) -> u64 {
58 self.age
59 }
60
61 pub fn max_age(&self) -> Option<u64> {
63 self.max_age
64 }
65
66 pub fn timestamp(&self) -> DateTime<Utc> {
68 self.timestamp
69 }
70
71 pub fn write(&self, headers: &mut http::HeaderMap<http::HeaderValue>) {
73 let age = self.age();
74 headers.insert(http::header::AGE, age.into());
75 if let Some(max_age) = self.max_age() {
76 headers.insert(
77 http::header::CACHE_CONTROL,
78 http::HeaderValue::from_str(&format!("max-age={}", max_age)).unwrap(),
79 );
80 }
81 }
82}