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 merged_resource = match Codec::merge_resources(&codec.resources, conflict_strategy) {
63 Ok(resource) => resource,
64 Err(e) => {
65 println!("❌ Error merging resources");
66 eprintln!("Error: {}", e);
67 std::process::exit(1);
68 }
69 };
70
71 println!("Writing merged output...");
73 if let Err(e) = Codec::write_resource_to_file(&merged_resource, &output) {
74 println!("❌ Error writing output file");
75 eprintln!("Error writing to {}: {}", output, e);
76 std::process::exit(1);
77 }
78
79 println!(
80 "✅ Successfully merged {} files into {}",
81 inputs.len(),
82 output
83 );
84}
85
86fn try_custom_format_merge(
88 input: &str,
89 _lang: Option<String>,
90 codec: &mut Codec,
91) -> Result<(), String> {
92 crate::validation::validate_custom_format_file(input)?;
94
95 let file_content = std::fs::read_to_string(input)
97 .map_err(|e| format!("Error reading file {}: {}", input, e))?;
98
99 crate::formats::validate_custom_format_content(input, &file_content)?;
101
102 let resources =
104 custom_format_to_resource(input.to_string(), parse_custom_format("json-language-map")?)?;
105
106 for resource in resources {
108 codec.add_resource(resource);
109 }
110
111 Ok(())
112}