headless_lms_server/programs/seed/builder/
json_source.rs1use anyhow::{Context, Result};
2use serde_json::Value;
3use std::fs;
4use std::path::PathBuf;
5
6#[derive(Clone, Debug)]
10pub enum JsonSource {
11 Inline(Value),
13 File(PathBuf),
15}
16
17impl JsonSource {
18 pub fn load(&self) -> Result<Value> {
19 match self {
20 JsonSource::Inline(v) => Ok(v.clone()),
21 JsonSource::File(p) => {
22 let s =
23 fs::read_to_string(p).with_context(|| format!("Reading {}", p.display()))?;
24 Ok(serde_json::from_str(&s).context("Parsing JSON file")?)
25 }
26 }
27 }
28}
29
30#[macro_export]
32macro_rules! asset_json {
33 ($path:literal) => {{
34 let _s: &str = include_str!($path);
35 $crate::programs::seed::builder::JsonSource::Inline(
36 serde_json::from_str(_s).expect(concat!("Invalid JSON in asset: ", $path)),
37 )
38 }};
39}
40
41#[cfg(test)]
42mod tests {
43 use super::*;
44 use serde_json::json;
45 use std::io::Write;
46 use tempfile::NamedTempFile;
47
48 #[test]
49 fn inline_loads() {
50 let v = json!({"a":1});
51 let src = JsonSource::Inline(v.clone());
52 let out = src.load().unwrap();
53 assert_eq!(out, v);
54 }
55
56 #[test]
57 fn file_loads() {
58 let mut tmp = NamedTempFile::new().unwrap();
59 write!(tmp, "{{\"k\":\"v\"}}").unwrap();
60 let src = JsonSource::File(tmp.path().to_path_buf());
61 let out = src.load().unwrap();
62 assert_eq!(out["k"], "v");
63 }
64
65 #[test]
66 fn file_bad_json() {
67 let mut tmp = NamedTempFile::new().unwrap();
68 write!(tmp, "not-json").unwrap();
69 let src = JsonSource::File(tmp.path().to_path_buf());
70 assert!(src.load().is_err());
71 }
72
73 #[test]
74 fn json_file_ok_and_bad() {
75 let mut f = tempfile::NamedTempFile::new().unwrap();
76 write!(f, r#"{{"ok":true}}"#).unwrap();
77
78 let src_ok = JsonSource::File(f.path().to_path_buf());
79 let v = src_ok.load().unwrap();
80 assert_eq!(v["ok"], true);
81
82 let mut f2 = tempfile::NamedTempFile::new().unwrap();
83 write!(f2, "nope").unwrap();
84 let src_bad = JsonSource::File(f2.path().to_path_buf());
85 assert!(src_bad.load().is_err());
86 }
87}