Skip to main content

wowlab_cli/commands/snapshot/
dump_assisted.rs

1use anyhow::Result;
2use wowlab_common::output;
3use wowlab_fs::{
4    atomic, directory,
5    path::{Path, PathBuf},
6};
7use wowlab_parsers::{DbcData, transform_assisted_rotation, transform_assisted_rotations};
8use wowlab_types::data::AssistedRotationFlat;
9
10use super::DumpAssistedArgs;
11
12pub(super) fn run_dump_assisted(args: &DumpAssistedArgs) -> Result<()> {
13    let dbc = DbcData::load_all(&args.data_dir)?;
14
15    if let Some(spec_id) = args.spec_id {
16        let rotation =
17            transform_assisted_rotation(&dbc, spec_id).unwrap_or_else(|| AssistedRotationFlat {
18                spec_id,
19                actions: Vec::new(),
20            });
21
22        if let Some(out_dir) = args.out_dir.as_ref() {
23            write_rotation_file(out_dir, &rotation)?;
24
25            return Ok(());
26        }
27
28        output::json(&rotation);
29
30        return Ok(());
31    }
32
33    let rotations = transform_assisted_rotations(&dbc);
34
35    if let Some(out_dir) = args.out_dir.as_ref() {
36        write_rotation_files(out_dir, &rotations)?;
37
38        return Ok(());
39    }
40
41    output::json(&rotations);
42
43    Ok(())
44}
45
46fn write_rotation_files(out_dir: &Path, rotations: &[AssistedRotationFlat]) -> Result<()> {
47    directory::ensure(out_dir)?;
48
49    for rotation in rotations {
50        write_rotation_file(out_dir, rotation)?;
51    }
52
53    let index_path = out_dir.join("index.json");
54    let spec_ids: Vec<i32> = rotations.iter().map(|r| r.spec_id).collect();
55    let index_json = serde_json::to_string_pretty(&spec_ids)?;
56
57    atomic::replace(&index_path, index_json)?;
58
59    println!(
60        "Wrote {} assisted rota files to {}",
61        rotations.len(),
62        out_dir.display()
63    );
64
65    Ok(())
66}
67
68fn write_rotation_file(out_dir: &Path, rotation: &AssistedRotationFlat) -> Result<PathBuf> {
69    directory::ensure(out_dir)?;
70
71    let file_path = out_dir.join(format!("spec_{}.json", rotation.spec_id));
72    let json = serde_json::to_string_pretty(rotation)?;
73
74    atomic::replace(&file_path, json)?;
75
76    println!("{}", file_path.display());
77
78    Ok(file_path)
79}
80
81#[cfg(test)]
82mod tests {
83    use googletest::prelude::*;
84    use wowlab_fs::{directory, file, temporary::Directory};
85
86    use super::{AssistedRotationFlat, write_rotation_files};
87
88    #[gtest]
89    fn assisted_rotation_dump_preserves_json_bytes_and_index() -> Result<()> {
90        let output = Directory::new().or_fail()?;
91        let rotations = [AssistedRotationFlat {
92            spec_id: 42,
93            actions: Vec::new(),
94        }];
95
96        write_rotation_files(output.path(), &rotations).or_fail()?;
97
98        verify_that!(
99            file::read_text(&output.path().join("spec_42.json")).or_fail()?,
100            eq("{\n  \"spec_id\": 42,\n  \"actions\": []\n}")
101        )?;
102        verify_that!(
103            file::read_text(&output.path().join("index.json")).or_fail()?,
104            eq("[\n  42\n]")
105        )?;
106
107        verify_that!(directory::entries(output.path()).or_fail()?, len(eq(2)))
108    }
109}