use crate::import::{Roster, RosterUnit};
pub fn title_case_id(id: Option<&str>) -> Option<String> {
let id = id?;
if id.is_empty() {
return Some(String::new());
}
let parts: Vec<String> = id
.split('-')
.map(|seg| {
if seg.is_empty() {
String::new()
} else {
let mut chars = seg.chars();
let first = chars.next().unwrap().to_ascii_uppercase();
let rest: String = chars.collect();
let mut out = String::with_capacity(seg.len());
out.push(first);
out.push_str(&rest);
out
}
})
.collect();
Some(parts.join(" "))
}
pub fn displayed_unit_points(u: &RosterUnit) -> Option<u64> {
let base = u.points?;
Some(base + u.enhancement_points.unwrap_or(0))
}
pub fn total_army_points(roster: &Roster) -> u64 {
let mut total = 0u64;
for u in &roster.units {
total += u.points.unwrap_or(0);
total += u.enhancement_points.unwrap_or(0);
}
total
}
pub fn char_slot_assignment(units: &[RosterUnit]) -> Vec<Option<u32>> {
let mut result = Vec::with_capacity(units.len());
let mut next: u32 = 1;
for u in units {
let is_char = u.is_warlord || u.enhancement.is_some() || u.leader_attachment.is_some();
if is_char {
result.push(Some(next));
next += 1;
} else {
result.push(None);
}
}
result
}
pub fn pretty_json<T: serde::Serialize>(value: &T) -> String {
let mut buf = Vec::with_capacity(1024);
let formatter = serde_json::ser::PrettyFormatter::with_indent(b" ");
let mut ser = serde_json::Serializer::with_formatter(&mut buf, formatter);
value.serialize(&mut ser).expect("Roster serializes");
buf.push(b'\n');
String::from_utf8(buf).expect("UTF-8")
}