use csv::{Reader, StringRecord};
use serde_json::{to_string_pretty, Map, Value};
use std::collections::HashMap;
use std::{fs::File, io::Write};
use crate::translations::{FormatTranslation, LangData, Translations};
const DUPE_KEY_NOTICE: &str = "translation keys overwritten during conversion.\n";
pub fn generate_json(
reader: &mut Reader<File>,
headings: &StringRecord,
rows: usize,
) -> Result<(), std::io::Error> {
let mut dictionary: HashMap<&str, Map<String, Value>> = HashMap::with_capacity(rows);
let mut times_overwritten = 0;
for (idx, item) in reader.deserialize().enumerate() {
let record: Translations = item?;
let mut overwrote_data = false;
for heading in headings.iter() {
if heading != "id" && heading != "TextDomain" && !heading.trim().is_empty() {
let kv = record.format_lang(heading);
if let Some(lang_map) = dictionary.get_mut(heading) {
let value = match kv.1 {
LangData::Float(v) => format!("{v}"),
LangData::Integer(v) => format!("{v}"),
LangData::String(v) => v.to_owned(),
};
let old_val = lang_map.insert(kv.0.into(), value.into());
if let Some(_val) = old_val {
if !overwrote_data {
println!(
"Warning: key \"{}\" overwritten by record {} (line {}).",
kv.0,
idx + 1,
idx + 1
);
overwrote_data = true;
times_overwritten += 1;
}
};
} else {
dictionary.insert(heading, Map::with_capacity(rows));
let value = match kv.1 {
LangData::Float(v) => format!("{v}"),
LangData::Integer(v) => format!("{v}"),
LangData::String(v) => v.to_owned(),
};
dictionary
.get_mut(heading)
.expect("Unexpected error after creating map")
.insert(kv.0.into(), value.into());
}
}
}
}
println!("\n{times_overwritten} {DUPE_KEY_NOTICE}");
for lang in dictionary.keys() {
let filename = format!("{lang}.json");
let mut file = File::create(filename)?;
if let Some(json) = dictionary.get(lang) {
writeln!(
file,
"{}",
to_string_pretty(json).expect("Error writing {lang}.json.")
)?;
}
println!("{lang}.json written to current directory.");
}
Ok(())
}
pub fn generate_json_fast(
reader: &mut Reader<File>,
headings: &StringRecord,
rows: usize,
) -> Result<(), std::io::Error> {
let mut dictionary: HashMap<&str, Map<String, Value>> = HashMap::with_capacity(rows);
let mut times_overwritten = 0;
let mut record = StringRecord::new();
let mut idx = 0;
while reader.read_record(&mut record)? {
let mut overwrote_data = false;
idx += 1;
for (column_idx, heading) in headings.iter().enumerate() {
if column_idx != 0 && heading != "TextDomain" && !heading.trim().is_empty() {
let value = match &record.get(column_idx) {
Some(head) => head,
None => "",
};
if let Some(lang_map) = dictionary.get_mut(heading) {
let old_val = lang_map.insert(record[0].into(), value.into());
if let Some(_val) = old_val {
if !overwrote_data {
println!(
"Warning: key \"{}\" overwritten by record {} (line {}).",
&record[0], idx, idx
);
overwrote_data = true;
times_overwritten += 1;
}
};
} else {
dictionary.insert(heading, Map::with_capacity(rows));
let value = match &record.get(column_idx) {
Some(head) => head,
None => "",
};
dictionary
.get_mut(heading)
.expect("Unexpected error after creating map")
.insert(record[0].into(), value.into());
}
}
}
}
println!("\n{times_overwritten} {DUPE_KEY_NOTICE}");
for lang in dictionary.keys() {
let filename = format!("{lang}.json");
let mut file = File::create(filename)?;
if let Some(json) = dictionary.get(lang) {
writeln!(
file,
"{}",
to_string_pretty(json).expect("Error writing {lang}.json.")
)?;
}
println!("{lang}.json written to current directory.");
}
Ok(())
}