use super::parsed_width::ParsedWidth;
#[must_use]
pub fn parse_width(width: &str) -> Option<ParsedWidth> {
let trimmed = width.trim();
if trimmed.is_empty() {
return None;
}
if trimmed.eq_ignore_ascii_case("auto") {
return Some(ParsedWidth {
value: 0,
width_type: docx_rs::WidthType::Auto,
});
}
if let Some(pct_str) = trimmed.strip_suffix('%') {
if let Ok(pct) = pct_str.trim().parse::<f64>() {
return Some(ParsedWidth {
value: (pct * 50.0).round() as usize,
width_type: docx_rs::WidthType::Pct,
});
}
return None;
}
if let Some(cm_str) = trimmed.strip_suffix("cm") {
if let Ok(cm) = cm_str.trim().parse::<f64>() {
return Some(ParsedWidth {
value: (cm * 567.0).round() as usize,
width_type: docx_rs::WidthType::Dxa,
});
}
return None;
}
if let Some(px_str) = trimmed.strip_suffix("px") {
if let Ok(px) = px_str.trim().parse::<f64>() {
return Some(ParsedWidth {
value: (px * 15.0).round() as usize,
width_type: docx_rs::WidthType::Dxa,
});
}
return None;
}
if let Ok(twips) = trimmed.parse::<f64>() {
return Some(ParsedWidth {
value: twips.round() as usize,
width_type: docx_rs::WidthType::Dxa,
});
}
None
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn width_cm() {
let w = parse_width("2cm").unwrap();
assert_eq!(w.value, 1134);
assert_eq!(w.width_type, docx_rs::WidthType::Dxa);
}
#[test]
fn width_cm_decimal() {
let w = parse_width("1.5cm").unwrap();
assert_eq!(w.value, 851); assert_eq!(w.width_type, docx_rs::WidthType::Dxa);
}
#[test]
fn width_px() {
let w = parse_width("80px").unwrap();
assert_eq!(w.value, 1200); assert_eq!(w.width_type, docx_rs::WidthType::Dxa);
}
#[test]
fn width_pct() {
let w = parse_width("50%").unwrap();
assert_eq!(w.value, 2500); assert_eq!(w.width_type, docx_rs::WidthType::Pct);
}
#[test]
fn width_pct_decimal() {
let w = parse_width("33.33%").unwrap();
assert_eq!(w.value, 1667); assert_eq!(w.width_type, docx_rs::WidthType::Pct);
}
#[test]
fn width_auto() {
let w = parse_width("auto").unwrap();
assert_eq!(w.value, 0);
assert_eq!(w.width_type, docx_rs::WidthType::Auto);
}
#[test]
fn width_auto_case_insensitive() {
let w = parse_width("Auto").unwrap();
assert_eq!(w.width_type, docx_rs::WidthType::Auto);
}
#[test]
fn width_empty_returns_none() {
assert!(parse_width("").is_none());
assert!(parse_width(" ").is_none());
}
#[test]
fn width_garbage_returns_none() {
assert!(parse_width("xyz").is_none());
}
#[test]
fn width_whitespace_trimmed() {
let w = parse_width(" 2cm ").unwrap();
assert_eq!(w.value, 1134);
}
#[test]
fn width_bare_number_as_twips() {
let w = parse_width("1134").unwrap();
assert_eq!(w.value, 1134);
assert_eq!(w.width_type, docx_rs::WidthType::Dxa);
}
}