concinnity_dev/authoring/
rm.rs1use crate::world::{WORLD_JSONL, known_names, patch_world_jsonl};
5use concinnity_cook::build_from_path;
6
7pub fn rm_at_path(world_path: &str, name: &str) -> std::io::Result<()> {
12 let mut removed = false;
13
14 patch_world_jsonl(world_path, |assets| {
15 if let Some(i) = assets
16 .iter()
17 .position(|a| a.get("name").and_then(|v| v.as_str()) == Some(name))
18 {
19 let asset = assets.remove(i);
20 tracing::info!(
21 "Removed '{}' (type: {})",
22 name,
23 asset.get("type").and_then(|v| v.as_str()).unwrap_or("?"),
24 );
25 removed = true;
26 }
27 })?;
28
29 if !removed {
30 let known = known_names(world_path).unwrap_or_default();
31 if known.is_empty() {
32 return Err(std::io::Error::new(
33 std::io::ErrorKind::InvalidInput,
34 format!(
35 "no asset named '{}' in {} (no assets declared)",
36 name, WORLD_JSONL
37 ),
38 ));
39 }
40 return Err(std::io::Error::new(
41 std::io::ErrorKind::InvalidInput,
42 format!(
43 "no asset named '{}' in {}\nKnown names: {}",
44 name,
45 WORLD_JSONL,
46 known.join(", ")
47 ),
48 ));
49 }
50
51 build_from_path(world_path, crate::cook_platform())
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
62 fn rm_of_a_missing_world_file_errors() {
63 let dir = tempfile::tempdir().unwrap();
64 let path = dir.path().join("missing.jsonl");
65 assert!(rm_at_path(path.to_str().unwrap(), "anything").is_err());
66 }
67
68 #[test]
69 fn rm_of_an_unknown_name_lists_the_known_names() {
70 let dir = tempfile::tempdir().unwrap();
71 let path = dir.path().join("world.jsonl");
72 std::fs::write(
73 &path,
74 concat!(
75 "{\"name\":\"log\",\"type\":\"Logger\",\"args\":{}}\n",
76 "{\"name\":\"log2\",\"type\":\"Logger\",\"args\":{}}\n",
77 ),
78 )
79 .unwrap();
80
81 let err = rm_at_path(path.to_str().unwrap(), "ghost").unwrap_err();
82 assert_eq!(err.kind(), std::io::ErrorKind::InvalidInput);
83 let msg = err.to_string();
84 assert!(msg.contains("no asset named 'ghost'"), "got: {msg}");
85 assert!(msg.contains("Known names: log, log2"), "got: {msg}");
86 let survived = std::fs::read_to_string(&path).unwrap();
88 assert!(survived.contains("\"log\""));
89 assert!(survived.contains("\"log2\""));
90 }
91
92 #[test]
93 fn rm_from_an_empty_world_reports_no_assets() {
94 let dir = tempfile::tempdir().unwrap();
95 let path = dir.path().join("world.jsonl");
96 std::fs::write(&path, "").unwrap();
97
98 let err = rm_at_path(path.to_str().unwrap(), "ghost").unwrap_err();
99 assert_eq!(err.kind(), std::io::ErrorKind::InvalidInput);
100 assert!(err.to_string().contains("no assets declared"), "got: {err}");
101 }
102}