cookie_store/serde/
json.rs

1//! De/serialization via the JSON format
2//! Requires feature `serde_json`
3
4use std::io::{BufRead, Write};
5
6use crate::cookie_store::{StoreResult, CookieStore};
7
8/// Load JSON-formatted cookies from `reader`, skipping any __expired__ cookies.
9/// __NB__: This function is not compatible with data produced by [CookieStore::save_json] or
10/// [CookieStore::save_incl_expired_and_nonpersistent_json].
11pub fn load<R: BufRead>(reader: R) -> StoreResult<CookieStore> {
12    super::load(reader, |cookies| serde_json::from_str(cookies))
13}
14
15/// Load JSON-formatted cookies from `reader`, loading both __expired__ and __unexpired__ cookies.
16/// __NB__: This function is not compatible with data produced by [CookieStore::save_json] or
17/// [CookieStore::save_incl_expired_and_nonpersistent_json].
18pub fn load_all<R: BufRead>(reader: R) -> StoreResult<CookieStore> {
19    super::load_all(reader, |cookies| serde_json::from_str(cookies))
20}
21
22/// Serialize any __unexpired__ and __persistent__ cookies in the store to JSON format and
23/// write them to `writer`.
24/// __NB__: This function does not produce data compatible with [CookieStore::load_json] or
25/// [CookieStore::load_json_all].
26pub fn save<W: Write>(cookie_store: &CookieStore, writer: &mut W) -> StoreResult<()> {
27    super::save(cookie_store, writer, ::serde_json::to_string_pretty)
28}
29
30/// Serialize all (including __expired__ and __non-persistent__) cookies in the store to JSON format and write them to `writer`.
31/// __NB__: This function does not produce data compatible with [CookieStore::load_json] or
32/// [CookieStore::load_json_all].
33pub fn save_incl_expired_and_nonpersistent<W: Write>(
34    cookie_store: &CookieStore,
35    writer: &mut W,
36) -> StoreResult<()> {
37    super::save_incl_expired_and_nonpersistent(cookie_store, writer, ::serde_json::to_string_pretty)
38}
39
40#[cfg(test)]
41mod tests {
42    use std::io::BufWriter;
43
44    use super::{ save_incl_expired_and_nonpersistent, save };
45
46    use super::{ load, load_all };
47
48    fn cookie() -> String {
49        r#"[
50  {
51    "raw_cookie": "2=two; SameSite=None; Secure; Path=/; Expires=Tue, 03 Aug 2100 00:38:37 GMT",
52    "path": [
53      "/",
54      true
55    ],
56    "domain": {
57      "HostOnly": "test.com"
58    },
59    "expires": {
60      "AtUtc": "2100-08-03T00:38:37Z"
61    }
62  }
63]
64"#
65            .to_string()
66    }
67
68    fn cookie_expired() -> String {
69        r#"[
70  {
71    "raw_cookie": "1=one; SameSite=None; Secure; Path=/; Expires=Thu, 03 Aug 2000 00:38:37 GMT",
72    "path": [
73      "/",
74      true
75    ],
76    "domain": {
77      "HostOnly": "test.com"
78    },
79    "expires": {
80      "AtUtc": "2000-08-03T00:38:37Z"
81    }
82  }
83]
84"#
85            .to_string()
86    }
87
88    #[test]
89    fn check_count() {
90        let cookie = cookie();
91
92        let cookie_store = load(Into::<&[u8]>::into(cookie.as_bytes())).unwrap();
93        assert_eq!(cookie_store.iter_any().map(|_| 1).sum::<i32>(), 1);
94        assert_eq!(cookie_store.iter_unexpired().map(|_| 1).sum::<i32>(), 1);
95
96        let cookie_store_all = load_all(Into::<&[u8]>::into(cookie.as_bytes())).unwrap();
97        assert_eq!(cookie_store_all.iter_any().map(|_| 1).sum::<i32>(), 1);
98        assert_eq!(cookie_store_all.iter_unexpired().map(|_| 1).sum::<i32>(), 1);
99
100        let mut writer = BufWriter::new(Vec::new());
101        save(&cookie_store, &mut writer).unwrap();
102        let string = String::from_utf8(writer.into_inner().unwrap()).unwrap();
103        assert_eq!(cookie, string);
104
105        let mut writer = BufWriter::new(Vec::new());
106        save_incl_expired_and_nonpersistent(&cookie_store, &mut writer).unwrap();
107        let string = String::from_utf8(writer.into_inner().unwrap()).unwrap();
108        assert_eq!(cookie, string);
109
110        let mut writer = BufWriter::new(Vec::new());
111        save(&cookie_store_all, &mut writer).unwrap();
112        let string = String::from_utf8(writer.into_inner().unwrap()).unwrap();
113        assert_eq!(cookie, string);
114
115        let mut writer = BufWriter::new(Vec::new());
116        save_incl_expired_and_nonpersistent(&cookie_store_all, &mut writer).unwrap();
117        let string = String::from_utf8(writer.into_inner().unwrap()).unwrap();
118        assert_eq!(cookie, string);
119    }
120
121    #[test]
122    fn check_count_expired() {
123        let cookie = cookie_expired();
124
125        let cookie_store = load(Into::<&[u8]>::into(cookie.as_bytes())).unwrap();
126        assert_eq!(cookie_store.iter_any().map(|_| 1).sum::<i32>(), 0);
127        assert_eq!(cookie_store.iter_unexpired().map(|_| 1).sum::<i32>(), 0);
128
129        let cookie_store_all = load_all(Into::<&[u8]>::into(cookie.as_bytes())).unwrap();
130        assert_eq!(cookie_store_all.iter_any().map(|_| 1).sum::<i32>(), 1);
131        assert_eq!(cookie_store_all.iter_unexpired().map(|_| 1).sum::<i32>(), 0);
132
133        let mut writer = BufWriter::new(Vec::new());
134        save(&cookie_store, &mut writer).unwrap();
135        let string = String::from_utf8(writer.into_inner().unwrap()).unwrap();
136        assert_eq!("[]\n", string);
137
138        let mut writer = BufWriter::new(Vec::new());
139        save_incl_expired_and_nonpersistent(&cookie_store, &mut writer).unwrap();
140        let string = String::from_utf8(writer.into_inner().unwrap()).unwrap();
141        assert_eq!("[]\n", string);
142
143        let mut writer = BufWriter::new(Vec::new());
144        save(&cookie_store_all, &mut writer).unwrap();
145        let string = String::from_utf8(writer.into_inner().unwrap()).unwrap();
146        assert_eq!("[]\n", string);
147
148        let mut writer = BufWriter::new(Vec::new());
149        save_incl_expired_and_nonpersistent(&cookie_store_all, &mut writer).unwrap();
150        let string = String::from_utf8(writer.into_inner().unwrap()).unwrap();
151        assert_eq!(cookie, string);
152    }
153}