wowlab_cli/commands/snapshot/
dump_assisted.rs1use 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}