1use std::collections::BTreeMap;
2
3use anyhow::Result;
4use serde::de::DeserializeOwned;
5
6use abstutil::{basename, parent_path, Timer};
7
8use crate::{list_dir, maybe_read_binary, slurp_file};
9
10pub fn maybe_read_json<T: DeserializeOwned>(path: String, timer: &mut Timer) -> Result<T> {
11 if !path.ends_with(".json") && !path.ends_with(".geojson") {
12 bail!("read_json needs {} to end with .json or .geojson", path);
13 }
14
15 timer.start(format!("parse {}", path));
16 let result: Result<T> =
18 slurp_file(&path).and_then(|raw| serde_json::from_slice(&raw).map_err(|err| err.into()));
19 timer.stop(format!("parse {}", path));
20 result
21}
22
23pub fn read_json<T: DeserializeOwned>(path: String, timer: &mut Timer) -> T {
24 match maybe_read_json(path.clone(), timer) {
25 Ok(obj) => obj,
26 Err(err) => panic!("Couldn't read_json({}): {}", path, err),
27 }
28}
29
30pub fn read_binary<T: DeserializeOwned>(path: String, timer: &mut Timer) -> T {
31 match maybe_read_binary(path.clone(), timer) {
32 Ok(obj) => obj,
33 Err(err) => panic!("Couldn't read_binary({}): {}", path, err),
34 }
35}
36
37pub fn read_object<T: DeserializeOwned>(path: String, timer: &mut Timer) -> Result<T> {
39 if path.ends_with(".bin") {
40 maybe_read_binary(path, timer)
41 } else {
42 maybe_read_json(path, timer)
43 }
44}
45
46pub fn must_read_object<T: DeserializeOwned>(path: String, timer: &mut Timer) -> T {
48 match read_object(path.clone(), timer) {
49 Ok(obj) => obj,
50 Err(err) => panic!("Couldn't read_object({}): {}", path, err),
51 }
52}
53
54pub fn find_prev_file(orig: String) -> Option<String> {
56 let mut files = list_dir(parent_path(&orig));
57 files.reverse();
58 files.into_iter().find(|f| *f < orig)
59}
60
61pub fn find_next_file(orig: String) -> Option<String> {
62 let files = list_dir(parent_path(&orig));
63 files.into_iter().find(|f| *f > orig)
64}
65
66pub fn load_all_objects<T: DeserializeOwned>(dir: String) -> Vec<(String, T)> {
69 let mut timer = Timer::new(format!("load_all_objects from {}", dir));
70 let mut tree: BTreeMap<String, T> = BTreeMap::new();
71 for path in list_dir(dir) {
72 match read_object(path.clone(), &mut timer) {
73 Ok(obj) => {
74 tree.insert(basename(path), obj);
75 }
76 Err(err) => {
77 error!("Couldn't load {}: {}", path, err);
78 }
79 }
80 }
81 tree.into_iter().collect()
82}
83
84pub fn list_all_objects(dir: String) -> Vec<String> {
88 list_dir(dir)
89 .into_iter()
90 .map(basename)
91 .filter(|x| !x.starts_with("."))
92 .collect()
93}