1use crate::formats::parse_custom_format;
2use crate::transformers::custom_format_to_resource;
3
4use langcodec::Codec;
5
6#[derive(Debug, Clone, PartialEq, clap::ValueEnum)]
8pub enum ConflictStrategy {
9 First,
11 Last,
13 Skip,
15}
16
17pub fn run_merge_command(
19 inputs: Vec<String>,
20 output: String,
21 strategy: ConflictStrategy,
22 lang: Option<String>,
23) {
24 if inputs.is_empty() {
25 eprintln!("Error: At least one input file is required.");
26 std::process::exit(1);
27 }
28
29 let mut codec = Codec::new();
31 for (i, input) in inputs.iter().enumerate() {
32 println!("Reading file {}/{}: {}", i + 1, inputs.len(), input);
33
34 if let Ok(()) = codec.read_file_by_extension(input, lang.clone()) {
36 continue;
37 }
38
39 if input.ends_with(".json") || input.ends_with(".yaml") || input.ends_with(".yml") {
41 if let Ok(()) = try_custom_format_merge(input, lang.clone(), &mut codec) {
42 continue;
43 }
44 }
45
46 println!("❌ Error reading input file");
48 eprintln!("Error reading {}: unsupported format", input);
49 std::process::exit(1);
50 }
51
52 println!("Merging resources...");
56 let conflict_strategy = match strategy {
57 ConflictStrategy::First => langcodec::types::ConflictStrategy::First,
58 ConflictStrategy::Last => langcodec::types::ConflictStrategy::Last,
59 ConflictStrategy::Skip => langcodec::types::ConflictStrategy::Skip,
60 };
61
62 let merge_count = codec.merge_resources(&conflict_strategy);
63 println!("Merged {} language groups", merge_count);
64
65 println!("Writing merged output...");
67 codec.resources.iter().for_each(|resource| {
68 if let Err(e) = Codec::write_resource_to_file(resource, &output) {
69 println!("❌ Error writing output file");
70 eprintln!("Error writing to {}: {}", output, e);
71 std::process::exit(1);
72 }
73 });
74
75 println!(
76 "✅ Successfully merged {} files into {}",
77 inputs.len(),
78 output
79 );
80}
81
82fn try_custom_format_merge(
84 input: &str,
85 _lang: Option<String>,
86 codec: &mut Codec,
87) -> Result<(), String> {
88 crate::validation::validate_custom_format_file(input)?;
90
91 let file_content = std::fs::read_to_string(input)
93 .map_err(|e| format!("Error reading file {}: {}", input, e))?;
94
95 crate::formats::validate_custom_format_content(input, &file_content)?;
97
98 let resources =
100 custom_format_to_resource(input.to_string(), parse_custom_format("json-language-map")?)?;
101
102 for resource in resources {
104 codec.add_resource(resource);
105 }
106
107 Ok(())
108}