mastodon_async/helpers/
json.rs1use std::{
2 fs::{File, OpenOptions},
3 io::{Read, Write},
4 path::Path,
5};
6
7use serde_json;
8
9use crate::{Data, Result};
10
11pub fn from_str(s: &str) -> Result<Data> {
13 Ok(serde_json::from_str(s)?)
14}
15
16pub fn from_slice(s: &[u8]) -> Result<Data> {
18 Ok(serde_json::from_slice(s)?)
19}
20
21pub fn from_reader<R: Read>(mut r: R) -> Result<Data> {
24 let mut buffer = Vec::new();
25 r.read_to_end(&mut buffer)?;
26 from_slice(&buffer)
27}
28
29pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Data> {
31 let path = path.as_ref();
32 let file = File::open(path)?;
33 from_reader(file)
34}
35
36pub fn to_string(data: &Data) -> Result<String> {
38 Ok(serde_json::to_string_pretty(data)?)
39}
40
41pub fn to_vec(data: &Data) -> Result<Vec<u8>> {
43 Ok(serde_json::to_vec(data)?)
44}
45
46pub fn to_writer<W: Write>(data: &Data, writer: W) -> Result<()> {
49 Ok(serde_json::to_writer(writer, data)?)
50}
51
52pub fn to_file<P: AsRef<Path>>(data: &Data, path: P) -> Result<()> {
58 let mut options = OpenOptions::new();
59 options.create(true).write(true).truncate(true);
60 to_file_with_options(data, path, options)?;
61 Ok(())
62}
63
64pub fn to_file_with_options<P: AsRef<Path>>(
66 data: &Data,
67 path: P,
68 options: OpenOptions,
69) -> Result<()> {
70 let path = path.as_ref();
71 let file = options.open(path)?;
72 to_writer(data, file)?;
73 Ok(())
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79 use std::{fs::OpenOptions, io::Cursor};
80 use tempfile::{tempdir, NamedTempFile};
81
82 const DOC: &str = indoc!(
83 r#"
84 {
85 "base": "https://example.com",
86 "client_id": "adbc01234",
87 "client_secret": "0987dcba",
88 "redirect": "urn:ietf:wg:oauth:2.0:oob",
89 "token": "fedc5678"
90 }
91 "#
92 );
93
94 #[test]
95 fn test_from_str() {
96 let desered = from_str(DOC).expect("Couldn't deserialize Data");
97 assert_eq!(
98 desered,
99 Data {
100 base: "https://example.com".into(),
101 client_id: "adbc01234".into(),
102 client_secret: "0987dcba".into(),
103 redirect: "urn:ietf:wg:oauth:2.0:oob".into(),
104 token: "fedc5678".into(),
105 }
106 );
107 }
108 #[test]
109 fn test_from_slice() {
110 let doc = DOC.as_bytes();
111 let desered = from_slice(doc).expect("Couldn't deserialize Data");
112 assert_eq!(
113 desered,
114 Data {
115 base: "https://example.com".into(),
116 client_id: "adbc01234".into(),
117 client_secret: "0987dcba".into(),
118 redirect: "urn:ietf:wg:oauth:2.0:oob".into(),
119 token: "fedc5678".into(),
120 }
121 );
122 }
123 #[test]
124 fn test_from_reader() {
125 let doc = DOC.as_bytes();
126 let doc = Cursor::new(doc);
127 let desered = from_reader(doc).expect("Couldn't deserialize Data");
128 assert_eq!(
129 desered,
130 Data {
131 base: "https://example.com".into(),
132 client_id: "adbc01234".into(),
133 client_secret: "0987dcba".into(),
134 redirect: "urn:ietf:wg:oauth:2.0:oob".into(),
135 token: "fedc5678".into(),
136 }
137 );
138 }
139 #[test]
140 fn test_from_file() {
141 let mut datafile = NamedTempFile::new().expect("Couldn't create tempfile");
142 write!(&mut datafile, "{}", DOC).expect("Couldn't write Data to file");
143 let desered = from_file(datafile.path()).expect("Couldn't deserialize Data");
144 assert_eq!(
145 desered,
146 Data {
147 base: "https://example.com".into(),
148 client_id: "adbc01234".into(),
149 client_secret: "0987dcba".into(),
150 redirect: "urn:ietf:wg:oauth:2.0:oob".into(),
151 token: "fedc5678".into(),
152 }
153 );
154 }
155 #[test]
156 fn test_to_string() {
157 let data = Data {
158 base: "https://example.com".into(),
159 client_id: "adbc01234".into(),
160 client_secret: "0987dcba".into(),
161 redirect: "urn:ietf:wg:oauth:2.0:oob".into(),
162 token: "fedc5678".into(),
163 };
164 let s = to_string(&data).expect("Couldn't serialize Data");
165 let desered = from_str(&s).expect("Couldn't deserialize Data");
166 assert_eq!(data, desered);
167 }
168 #[test]
169 fn test_to_vec() {
170 let data = Data {
171 base: "https://example.com".into(),
172 client_id: "adbc01234".into(),
173 client_secret: "0987dcba".into(),
174 redirect: "urn:ietf:wg:oauth:2.0:oob".into(),
175 token: "fedc5678".into(),
176 };
177 let v = to_vec(&data).expect("Couldn't write to vec");
178 let desered = from_slice(&v).expect("Couldn't deserialize data");
179 assert_eq!(data, desered);
180 }
181 #[test]
182 fn test_to_writer() {
183 let data = Data {
184 base: "https://example.com".into(),
185 client_id: "adbc01234".into(),
186 client_secret: "0987dcba".into(),
187 redirect: "urn:ietf:wg:oauth:2.0:oob".into(),
188 token: "fedc5678".into(),
189 };
190 let mut buffer = Vec::new();
191 to_writer(&data, &mut buffer).expect("Couldn't write to writer");
192 let reader = Cursor::new(buffer);
193 let desered = from_reader(reader).expect("Couldn't deserialize Data");
194 assert_eq!(data, desered);
195 }
196 #[test]
197 fn test_to_file() {
198 let data = Data {
199 base: "https://example.com".into(),
200 client_id: "adbc01234".into(),
201 client_secret: "0987dcba".into(),
202 redirect: "urn:ietf:wg:oauth:2.0:oob".into(),
203 token: "fedc5678".into(),
204 };
205 let tempdir = tempdir().expect("Couldn't create tempdir");
206 let filename = tempdir.path().join("mastodon-data.json");
207 to_file(&data, &filename).expect("Couldn't write to file");
208 let desered = from_file(&filename).expect("Couldn't deserialize Data");
209 assert_eq!(data, desered);
210 }
211 #[test]
212 fn test_to_file_with_options() {
213 let data = Data {
214 base: "https://example.com".into(),
215 client_id: "adbc01234".into(),
216 client_secret: "0987dcba".into(),
217 redirect: "urn:ietf:wg:oauth:2.0:oob".into(),
218 token: "fedc5678".into(),
219 };
220 let file = NamedTempFile::new().expect("Couldn't create tempfile");
221 let mut options = OpenOptions::new();
222 options.write(true).create(false).truncate(true);
223 to_file_with_options(&data, file.path(), options).expect("Couldn't write to file");
224 let desered = from_file(file.path()).expect("Couldn't deserialize Data");
225 assert_eq!(data, desered);
226 }
227}