concinnity_world/world/
find.rs1pub const WORLD_JSONL: &str = "world.jsonl";
3pub fn find_world_jsonl(name: Option<&str>) -> std::io::Result<String> {
11 let worlds_dir = crate::paths::worlds_dir();
12
13 if let Some(n) = name {
14 let path = worlds_dir
15 .as_deref()
16 .map(|d| d.join(format!("{}.jsonl", n)));
17 if let Some(path) = &path
18 && path.exists()
19 {
20 return Ok(path.to_string_lossy().into_owned());
21 }
22 return Err(named_world_not_found(n, path.as_deref()));
23 }
24
25 if let Some(worlds_dir) = worlds_dir.filter(|d| d.is_dir()) {
27 let mut best: Option<(std::time::SystemTime, std::path::PathBuf)> = None;
28 if let Ok(entries) = std::fs::read_dir(&worlds_dir) {
29 for entry in entries.flatten() {
30 let path = entry.path();
31 if path.extension().and_then(|e| e.to_str()) != Some("jsonl") {
32 continue;
33 }
34 if let Ok(meta) = std::fs::metadata(&path) {
35 let mtime = meta.modified().unwrap_or(std::time::UNIX_EPOCH);
36 if best.as_ref().map(|(t, _)| mtime > *t).unwrap_or(true) {
37 best = Some((mtime, path));
38 }
39 }
40 }
41 }
42 if let Some((_, path)) = best {
43 return Ok(path.to_string_lossy().into_owned());
44 }
45 }
46
47 let mut dir = std::env::current_dir()?;
49 loop {
50 let candidate = dir.join(WORLD_JSONL);
51 if candidate.exists() {
52 return Ok(candidate.to_string_lossy().into_owned());
53 }
54 match dir.parent() {
55 Some(parent) => dir = parent.to_path_buf(),
56 None => {
57 return Err(std::io::Error::new(
58 std::io::ErrorKind::NotFound,
59 format!(
60 "no world found: run `cn fetch-world` or create `{}`",
61 WORLD_JSONL,
62 ),
63 ));
64 }
65 }
66 }
67}
68
69fn named_world_not_found(name: &str, path: Option<&std::path::Path>) -> std::io::Error {
73 let message = match path {
74 Some(p) => format!("world '{}' not found at {}", name, p.display()),
75 None => format!("world '{}' not found: no project state directory", name),
76 };
77 std::io::Error::new(std::io::ErrorKind::NotFound, message)
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83
84 #[test]
89 fn a_missing_named_world_names_the_file_it_looked_for() {
90 let path = std::path::Path::new("/proj/worlds/cn_test_no_such_world.jsonl");
91 let err = named_world_not_found("cn_test_no_such_world", Some(path));
92 assert_eq!(err.kind(), std::io::ErrorKind::NotFound);
93 let msg = err.to_string();
94 assert!(msg.contains("cn_test_no_such_world"), "message was: {msg}");
95 assert!(msg.contains(".jsonl"), "message was: {msg}");
96 }
97
98 #[test]
101 fn a_named_world_without_a_state_root_says_so() {
102 let err = named_world_not_found("main", None);
103 assert_eq!(err.kind(), std::io::ErrorKind::NotFound);
104 let msg = err.to_string();
105 assert!(msg.contains("main"), "message was: {msg}");
106 assert!(
107 msg.contains("no project state directory"),
108 "message was: {msg}"
109 );
110 }
111
112 #[test]
114 fn missing_named_world_is_a_not_found_error() {
115 let err = find_world_jsonl(Some("cn_test_no_such_world")).unwrap_err();
116 assert_eq!(err.kind(), std::io::ErrorKind::NotFound);
117 assert!(err.to_string().contains("cn_test_no_such_world"));
118 }
119}