use serde::Deserialize;
use crate::docx::model::dimension::{Dimension, ThousandthPercent};
use crate::docx::model::TableMeasure;
#[derive(Clone, Copy, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
enum StTblWidthType {
Auto,
Dxa,
Nil,
Pct,
}
#[derive(Clone, Copy, Debug, Deserialize)]
pub(crate) struct TableMeasureXml {
#[serde(rename = "@w", default)]
w: Option<i64>,
#[serde(rename = "@type", default = "default_type")]
ty: StTblWidthType,
}
fn default_type() -> StTblWidthType {
StTblWidthType::Auto
}
impl From<TableMeasureXml> for TableMeasure {
fn from(x: TableMeasureXml) -> Self {
match x.ty {
StTblWidthType::Auto => Self::Auto,
StTblWidthType::Nil => Self::Nil,
StTblWidthType::Dxa => Self::Twips(Dimension::new(x.w.unwrap_or(0))),
StTblWidthType::Pct => Self::Pct(Dimension::<ThousandthPercent>::new(x.w.unwrap_or(0))),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
fn parse(xml: &str) -> TableMeasure {
let x: TableMeasureXml = quick_xml::de::from_str(xml).unwrap();
x.into()
}
#[test]
fn dxa_twips() {
match parse(r#"<tblW w="5000" type="dxa"/>"#) {
TableMeasure::Twips(d) => assert_eq!(d.raw(), 5000),
other => panic!("expected Twips, got {other:?}"),
}
}
#[test]
fn pct_thousandth_percent() {
match parse(r#"<tblW w="2500" type="pct"/>"#) {
TableMeasure::Pct(d) => assert_eq!(d.raw(), 2500),
other => panic!("expected Pct, got {other:?}"),
}
}
#[test]
fn auto_and_nil() {
assert!(matches!(
parse(r#"<tblW w="0" type="auto"/>"#),
TableMeasure::Auto
));
assert!(matches!(
parse(r#"<tblW w="0" type="nil"/>"#),
TableMeasure::Nil
));
}
#[test]
fn missing_type_defaults_to_auto() {
assert!(matches!(parse(r#"<tblW/>"#), TableMeasure::Auto));
}
}