memstead_schema/
meta_schema.rs1use std::path::Path;
14
15pub const META_SCHEMA_MANIFEST: &str = include_str!("../generated/schema-manifest.schema.json");
17
18pub const META_SCHEMA_TYPE_DEFINITION: &str =
20 include_str!("../generated/type-definition.schema.json");
21
22pub const META_SCHEMA_DIR: &str = "meta-schemas";
24
25pub const META_SCHEMA_MANIFEST_FILE: &str = "schema-manifest.schema.json";
27pub const META_SCHEMA_TYPE_DEFINITION_FILE: &str = "type-definition.schema.json";
29
30pub fn publish_meta_schemas(workspace_root: &Path) -> std::io::Result<()> {
37 let dir = workspace_root.join(".memstead").join(META_SCHEMA_DIR);
38 write_if_changed(&dir.join(META_SCHEMA_MANIFEST_FILE), META_SCHEMA_MANIFEST)?;
39 write_if_changed(
40 &dir.join(META_SCHEMA_TYPE_DEFINITION_FILE),
41 META_SCHEMA_TYPE_DEFINITION,
42 )?;
43 Ok(())
44}
45
46fn write_if_changed(path: &Path, contents: &str) -> std::io::Result<()> {
47 if let Ok(existing) = std::fs::read_to_string(path)
48 && existing == contents
49 {
50 return Ok(());
51 }
52 if let Some(parent) = path.parent() {
53 std::fs::create_dir_all(parent)?;
54 }
55 std::fs::write(path, contents)
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 #[test]
63 fn embedded_meta_schemas_are_valid_json_objects() {
64 let manifest: serde_json::Value = serde_json::from_str(META_SCHEMA_MANIFEST).unwrap();
65 assert!(
66 manifest.get("properties").is_some(),
67 "manifest meta-schema has properties"
68 );
69 let type_def: serde_json::Value =
70 serde_json::from_str(META_SCHEMA_TYPE_DEFINITION).unwrap();
71 assert!(
72 type_def.get("properties").is_some(),
73 "type meta-schema has properties"
74 );
75 }
76
77 #[test]
78 fn publish_writes_both_and_is_idempotent() {
79 let tmp = tempfile::tempdir().unwrap();
80 publish_meta_schemas(tmp.path()).unwrap();
81 let mdir = tmp.path().join(".memstead").join("meta-schemas");
82 assert_eq!(
83 std::fs::read_to_string(mdir.join(META_SCHEMA_MANIFEST_FILE)).unwrap(),
84 META_SCHEMA_MANIFEST,
85 );
86 assert!(mdir.join(META_SCHEMA_TYPE_DEFINITION_FILE).is_file());
87 publish_meta_schemas(tmp.path()).unwrap();
89 assert_eq!(
90 std::fs::read_to_string(mdir.join(META_SCHEMA_MANIFEST_FILE)).unwrap(),
91 META_SCHEMA_MANIFEST,
92 );
93 }
94}