#![allow(dead_code)]
use serde::{Deserialize, Serialize};
use super::deser_i32_or_u32;
#[derive(Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename = "head")]
pub struct HxHead {
#[serde(rename = "@version", default)]
pub version: String,
#[serde(rename = "@secCnt", default)]
pub sec_cnt: u32,
#[serde(
rename(serialize = "hh:beginNum", deserialize = "beginNum"),
default,
skip_serializing_if = "Option::is_none"
)]
pub begin_num: Option<HxBeginNum>,
#[serde(
rename(serialize = "hh:refList", deserialize = "refList"),
default,
skip_serializing_if = "Option::is_none"
)]
pub ref_list: Option<HxRefList>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, Copy)]
pub struct HxBeginNum {
#[serde(rename = "@page", default = "one")]
pub page: u32,
#[serde(rename = "@footnote", default = "one")]
pub footnote: u32,
#[serde(rename = "@endnote", default = "one")]
pub endnote: u32,
#[serde(rename = "@pic", default = "one")]
pub pic: u32,
#[serde(rename = "@tbl", default = "one")]
pub tbl: u32,
#[serde(rename = "@equation", default = "one")]
pub equation: u32,
}
fn one() -> u32 {
1
}
fn default_hwpunit() -> String {
"HWPUNIT".to_string()
}
#[derive(Debug, Serialize, Deserialize, Default, PartialEq)]
pub struct HxRefList {
#[serde(
rename(serialize = "hh:fontfaces", deserialize = "fontfaces"),
default,
skip_serializing_if = "Option::is_none"
)]
pub fontfaces: Option<HxFontFaces>,
#[serde(
rename(serialize = "hh:borderFills", deserialize = "borderFills"),
default,
skip_serializing_if = "Option::is_none"
)]
pub border_fills: Option<HxBorderFills>,
#[serde(
rename(serialize = "hh:charProperties", deserialize = "charProperties"),
default,
skip_serializing_if = "Option::is_none"
)]
pub char_properties: Option<HxCharProperties>,
#[serde(
rename(serialize = "hh:tabProperties", deserialize = "tabProperties"),
default,
skip_serializing_if = "Option::is_none"
)]
pub tab_properties: Option<HxTabProperties>,
#[serde(
rename(serialize = "hh:numberings", deserialize = "numberings"),
default,
skip_serializing_if = "Option::is_none"
)]
pub numberings: Option<HxNumberings>,
#[serde(
rename(serialize = "hh:bullets", deserialize = "bullets"),
default,
skip_serializing_if = "Option::is_none"
)]
pub bullets: Option<HxBullets>,
#[serde(
rename(serialize = "hh:paraProperties", deserialize = "paraProperties"),
default,
skip_serializing_if = "Option::is_none"
)]
pub para_properties: Option<HxParaProperties>,
#[serde(
rename(serialize = "hh:styles", deserialize = "styles"),
default,
skip_serializing_if = "Option::is_none"
)]
pub styles: Option<HxStyles>,
}
#[derive(Debug, Serialize, Deserialize, Default, PartialEq)]
pub struct HxFontFaces {
#[serde(rename = "@itemCnt", default)]
pub item_cnt: u32,
#[serde(
rename(serialize = "hh:fontface", deserialize = "fontface"),
default,
skip_serializing_if = "Vec::is_empty"
)]
pub groups: Vec<HxFontFaceGroup>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct HxFontFaceGroup {
#[serde(rename = "@lang", default)]
pub lang: String,
#[serde(rename = "@fontCnt", default)]
pub font_cnt: u32,
#[serde(
rename(serialize = "hh:font", deserialize = "font"),
default,
skip_serializing_if = "Vec::is_empty"
)]
pub fonts: Vec<HxFont>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct HxFont {
#[serde(rename = "@id")]
pub id: u32,
#[serde(rename = "@face", default)]
pub face: String,
#[serde(rename = "@type", default)]
pub font_type: String,
#[serde(rename = "@isEmbedded", default)]
pub is_embedded: u32,
#[serde(
rename(serialize = "hh:typeInfo", deserialize = "typeInfo"),
default,
skip_serializing_if = "Option::is_none"
)]
pub type_info: Option<HxTypeInfo>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct HxTypeInfo {
#[serde(rename = "@familyType", default)]
pub family_type: String,
#[serde(rename = "@weight", default)]
pub weight: u32,
#[serde(rename = "@proportion", default)]
pub proportion: u32,
#[serde(rename = "@contrast", default)]
pub contrast: u32,
#[serde(rename = "@strokeVariation", default)]
pub stroke_variation: u32,
#[serde(rename = "@armStyle", default)]
pub arm_style: u32,
#[serde(rename = "@letterform", default)]
pub letterform: u32,
#[serde(rename = "@midline", default)]
pub midline: u32,
#[serde(rename = "@xHeight", default)]
pub x_height: u32,
}
#[derive(Debug, Serialize, Deserialize, Default, PartialEq)]
pub struct HxCharProperties {
#[serde(rename = "@itemCnt", default)]
pub item_cnt: u32,
#[serde(
rename(serialize = "hh:charPr", deserialize = "charPr"),
default,
skip_serializing_if = "Vec::is_empty"
)]
pub items: Vec<HxCharPr>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct HxCharPr {
#[serde(rename = "@id")]
pub id: u32,
#[serde(rename = "@height", default)]
pub height: u32,
#[serde(rename = "@textColor", default)]
pub text_color: String,
#[serde(rename = "@shadeColor", default)]
pub shade_color: String,
#[serde(rename = "@useFontSpace", default)]
pub use_font_space: u32,
#[serde(rename = "@useKerning", default)]
pub use_kerning: u32,
#[serde(rename = "@symMark", default)]
pub sym_mark: String,
#[serde(rename = "@borderFillIDRef", default)]
pub border_fill_id_ref: u32,
#[serde(
rename(serialize = "hh:fontRef", deserialize = "fontRef"),
default,
skip_serializing_if = "Option::is_none"
)]
pub font_ref: Option<HxFontRef>,
#[serde(
rename(serialize = "hh:ratio", deserialize = "ratio"),
default,
skip_serializing_if = "Option::is_none"
)]
pub ratio: Option<HxLangValues>,
#[serde(
rename(serialize = "hh:spacing", deserialize = "spacing"),
default,
skip_serializing_if = "Option::is_none"
)]
pub spacing: Option<HxLangValues>,
#[serde(
rename(serialize = "hh:relSz", deserialize = "relSz"),
default,
skip_serializing_if = "Option::is_none"
)]
pub rel_sz: Option<HxLangValues>,
#[serde(
rename(serialize = "hh:offset", deserialize = "offset"),
default,
skip_serializing_if = "Option::is_none"
)]
pub offset: Option<HxLangValues>,
#[serde(
rename(serialize = "hh:bold", deserialize = "bold"),
default,
skip_serializing_if = "Option::is_none"
)]
pub bold: Option<HxPresence>,
#[serde(
rename(serialize = "hh:italic", deserialize = "italic"),
default,
skip_serializing_if = "Option::is_none"
)]
pub italic: Option<HxPresence>,
#[serde(
rename(serialize = "hh:underline", deserialize = "underline"),
default,
skip_serializing_if = "Option::is_none"
)]
pub underline: Option<HxUnderline>,
#[serde(
rename(serialize = "hh:strikeout", deserialize = "strikeout"),
default,
skip_serializing_if = "Option::is_none"
)]
pub strikeout: Option<HxStrikeout>,
#[serde(
rename(serialize = "hh:outline", deserialize = "outline"),
default,
skip_serializing_if = "Option::is_none"
)]
pub outline: Option<HxOutline>,
#[serde(
rename(serialize = "hh:emboss", deserialize = "emboss"),
default,
skip_serializing_if = "Option::is_none"
)]
pub emboss: Option<HxPresence>,
#[serde(
rename(serialize = "hh:engrave", deserialize = "engrave"),
default,
skip_serializing_if = "Option::is_none"
)]
pub engrave: Option<HxPresence>,
#[serde(
rename(serialize = "hh:supscript", deserialize = "supscript"),
default,
skip_serializing_if = "Option::is_none"
)]
pub supscript: Option<HxPresence>,
#[serde(
rename(serialize = "hh:subscript", deserialize = "subscript"),
default,
skip_serializing_if = "Option::is_none"
)]
pub subscript: Option<HxPresence>,
#[serde(
rename(serialize = "hh:shadow", deserialize = "shadow"),
default,
skip_serializing_if = "Option::is_none"
)]
pub shadow: Option<HxShadow>,
}
#[derive(Debug, Serialize, Deserialize, Default, PartialEq)]
pub struct HxFontRef {
#[serde(rename = "@hangul", default)]
pub hangul: u32,
#[serde(rename = "@latin", default)]
pub latin: u32,
#[serde(rename = "@hanja", default)]
pub hanja: u32,
#[serde(rename = "@japanese", default)]
pub japanese: u32,
#[serde(rename = "@other", default)]
pub other: u32,
#[serde(rename = "@symbol", default)]
pub symbol: u32,
#[serde(rename = "@user", default)]
pub user: u32,
}
#[derive(Debug, Serialize, Deserialize, Default, PartialEq)]
pub struct HxLangValues {
#[serde(rename = "@hangul", default, deserialize_with = "deser_i32_or_u32")]
pub hangul: i32,
#[serde(rename = "@latin", default, deserialize_with = "deser_i32_or_u32")]
pub latin: i32,
#[serde(rename = "@hanja", default, deserialize_with = "deser_i32_or_u32")]
pub hanja: i32,
#[serde(rename = "@japanese", default, deserialize_with = "deser_i32_or_u32")]
pub japanese: i32,
#[serde(rename = "@other", default, deserialize_with = "deser_i32_or_u32")]
pub other: i32,
#[serde(rename = "@symbol", default, deserialize_with = "deser_i32_or_u32")]
pub symbol: i32,
#[serde(rename = "@user", default, deserialize_with = "deser_i32_or_u32")]
pub user: i32,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct HxPresence;
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct HxUnderline {
#[serde(rename = "@type", default)]
pub underline_type: String,
#[serde(rename = "@shape", default)]
pub shape: String,
#[serde(rename = "@color", default)]
pub color: String,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct HxStrikeout {
#[serde(rename = "@shape", default)]
pub shape: String,
#[serde(rename = "@color", default)]
pub color: String,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct HxOutline {
#[serde(rename = "@type", default)]
pub outline_type: String,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct HxShadow {
#[serde(rename = "@type", default)]
pub shadow_type: String,
#[serde(rename = "@color", default)]
pub color: String,
#[serde(rename = "@offsetX", default, deserialize_with = "deser_i32_or_u32")]
pub offset_x: i32,
#[serde(rename = "@offsetY", default, deserialize_with = "deser_i32_or_u32")]
pub offset_y: i32,
}
#[derive(Debug, Serialize, Deserialize, Default, PartialEq)]
pub struct HxParaProperties {
#[serde(rename = "@itemCnt", default)]
pub item_cnt: u32,
#[serde(
rename(serialize = "hh:paraPr", deserialize = "paraPr"),
default,
skip_serializing_if = "Vec::is_empty"
)]
pub items: Vec<HxParaPr>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct HxParaPr {
#[serde(rename = "@id")]
pub id: u32,
#[serde(rename = "@tabPrIDRef", default)]
pub tab_pr_id_ref: u32,
#[serde(rename = "@condense", default)]
pub condense: u32,
#[serde(rename = "@fontLineHeight", default)]
pub font_line_height: u32,
#[serde(rename = "@snapToGrid", default, skip_serializing_if = "Option::is_none")]
pub snap_to_grid: Option<u32>,
#[serde(rename = "@suppressLineNumbers", default)]
pub suppress_line_numbers: u32,
#[serde(rename = "@checked", default)]
pub checked: u32,
#[serde(
rename(serialize = "hh:align", deserialize = "align"),
default,
skip_serializing_if = "Option::is_none"
)]
pub align: Option<HxAlign>,
#[serde(
rename(serialize = "hh:heading", deserialize = "heading"),
default,
skip_serializing_if = "Option::is_none"
)]
pub heading: Option<HxHeading>,
#[serde(
rename(serialize = "hh:breakSetting", deserialize = "breakSetting"),
default,
skip_serializing_if = "Option::is_none"
)]
pub break_setting: Option<HxBreakSetting>,
#[serde(
rename(serialize = "hh:autoSpacing", deserialize = "autoSpacing"),
default,
skip_serializing_if = "Option::is_none"
)]
pub auto_spacing: Option<HxAutoSpacing>,
#[serde(
rename(serialize = "hp:switch", deserialize = "switch"),
default,
skip_serializing_if = "Vec::is_empty"
)]
pub switches: Vec<HxSwitch>,
#[serde(
rename(serialize = "hh:border", deserialize = "border"),
default,
skip_serializing_if = "Option::is_none"
)]
pub border: Option<HxBorder>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct HxAlign {
#[serde(rename = "@horizontal", default)]
pub horizontal: String,
#[serde(rename = "@vertical", default)]
pub vertical: String,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct HxHeading {
#[serde(rename = "@type", default)]
pub heading_type: String,
#[serde(rename = "@idRef", default)]
pub id_ref: u32,
#[serde(rename = "@level", default)]
pub level: u32,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct HxBreakSetting {
#[serde(rename = "@breakLatinWord", default)]
pub break_latin_word: String,
#[serde(rename = "@breakNonLatinWord", default)]
pub break_non_latin_word: String,
#[serde(rename = "@widowOrphan", default)]
pub widow_orphan: u32,
#[serde(rename = "@keepWithNext", default)]
pub keep_with_next: u32,
#[serde(rename = "@keepLines", default)]
pub keep_lines: u32,
#[serde(rename = "@pageBreakBefore", default)]
pub page_break_before: u32,
#[serde(rename = "@lineWrap", default, skip_serializing_if = "String::is_empty")]
pub line_wrap: String,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct HxAutoSpacing {
#[serde(rename = "@eAsianEng", default)]
pub e_asian_eng: u32,
#[serde(rename = "@eAsianNum", default)]
pub e_asian_num: u32,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct HxBorder {
#[serde(rename = "@borderFillIDRef", default)]
pub border_fill_id_ref: u32,
#[serde(rename = "@offsetLeft", default, deserialize_with = "deser_i32_or_u32")]
pub offset_left: i32,
#[serde(rename = "@offsetRight", default, deserialize_with = "deser_i32_or_u32")]
pub offset_right: i32,
#[serde(rename = "@offsetTop", default, deserialize_with = "deser_i32_or_u32")]
pub offset_top: i32,
#[serde(rename = "@offsetBottom", default, deserialize_with = "deser_i32_or_u32")]
pub offset_bottom: i32,
#[serde(rename = "@connect", default)]
pub connect: u32,
#[serde(rename = "@ignoreMargin", default)]
pub ignore_margin: u32,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct HxSwitch {
#[serde(
rename(serialize = "hp:case", deserialize = "case"),
default,
skip_serializing_if = "Option::is_none"
)]
pub case: Option<HxSwitchCase>,
#[serde(
rename(serialize = "hp:default", deserialize = "default"),
default,
skip_serializing_if = "Option::is_none"
)]
pub default: Option<HxSwitchDefault>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct HxSwitchCase {
#[serde(
rename(serialize = "@hp:required-namespace", deserialize = "@required-namespace"),
default
)]
pub required_namespace: String,
#[serde(
rename(serialize = "hh:margin", deserialize = "margin"),
default,
skip_serializing_if = "Option::is_none"
)]
pub margin: Option<HxMargin>,
#[serde(
rename(serialize = "hh:lineSpacing", deserialize = "lineSpacing"),
default,
skip_serializing_if = "Option::is_none"
)]
pub line_spacing: Option<HxLineSpacing>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct HxSwitchDefault {
#[serde(
rename(serialize = "hh:margin", deserialize = "margin"),
default,
skip_serializing_if = "Option::is_none"
)]
pub margin: Option<HxMargin>,
#[serde(
rename(serialize = "hh:lineSpacing", deserialize = "lineSpacing"),
default,
skip_serializing_if = "Option::is_none"
)]
pub line_spacing: Option<HxLineSpacing>,
}
#[derive(Debug, Serialize, Deserialize, Default, PartialEq)]
pub struct HxMargin {
#[serde(
rename(serialize = "hc:intent", deserialize = "intent"),
default,
skip_serializing_if = "Option::is_none"
)]
pub indent: Option<HxUnitValue>,
#[serde(
rename(serialize = "hc:left", deserialize = "left"),
default,
skip_serializing_if = "Option::is_none"
)]
pub left: Option<HxUnitValue>,
#[serde(
rename(serialize = "hc:right", deserialize = "right"),
default,
skip_serializing_if = "Option::is_none"
)]
pub right: Option<HxUnitValue>,
#[serde(
rename(serialize = "hc:prev", deserialize = "prev"),
default,
skip_serializing_if = "Option::is_none"
)]
pub prev: Option<HxUnitValue>,
#[serde(
rename(serialize = "hc:next", deserialize = "next"),
default,
skip_serializing_if = "Option::is_none"
)]
pub next: Option<HxUnitValue>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct HxUnitValue {
#[serde(rename = "@value", default, deserialize_with = "deser_i32_or_u32")]
pub value: i32,
#[serde(rename = "@unit", default)]
pub unit: String,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct HxLineSpacing {
#[serde(rename = "@type", default)]
pub spacing_type: String,
#[serde(rename = "@value", default)]
pub value: u32,
#[serde(rename = "@unit", default)]
pub unit: String,
}
#[derive(Debug, Serialize, Deserialize, Default, PartialEq)]
pub struct HxStyles {
#[serde(rename = "@itemCnt", default)]
pub item_cnt: u32,
#[serde(
rename(serialize = "hh:style", deserialize = "style"),
default,
skip_serializing_if = "Vec::is_empty"
)]
pub items: Vec<HxStyle>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct HxStyle {
#[serde(rename = "@id")]
pub id: u32,
#[serde(rename = "@type", default)]
pub style_type: String,
#[serde(rename = "@name", default)]
pub name: String,
#[serde(rename = "@engName", default)]
pub eng_name: String,
#[serde(rename = "@paraPrIDRef", default)]
pub para_pr_id_ref: u32,
#[serde(rename = "@charPrIDRef", default)]
pub char_pr_id_ref: u32,
#[serde(rename = "@nextStyleIDRef", default)]
pub next_style_id_ref: u32,
#[serde(rename = "@langID", default)]
pub lang_id: u32,
#[serde(rename = "@lockForm", default)]
pub lock_form: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
pub struct HxBorderFills {
#[serde(rename = "@itemCnt")]
pub item_cnt: u32,
#[serde(
rename(serialize = "hh:borderFill", deserialize = "borderFill"),
default,
skip_serializing_if = "Vec::is_empty"
)]
pub items: Vec<HxBorderFill>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct HxBorderFill {
#[serde(rename = "@id")]
pub id: u32,
#[serde(rename = "@threeD", default)]
pub three_d: u32,
#[serde(rename = "@shadow", default)]
pub shadow: u32,
#[serde(rename = "@centerLine", default)]
pub center_line: String,
#[serde(rename = "@breakCellSeparateLine", default)]
pub break_cell_separate_line: u32,
#[serde(rename(serialize = "hh:slash", deserialize = "slash"))]
pub slash: HxDiagonalBorder,
#[serde(rename(serialize = "hh:backSlash", deserialize = "backSlash"))]
pub back_slash: HxDiagonalBorder,
#[serde(rename(serialize = "hh:leftBorder", deserialize = "leftBorder"))]
pub left_border: HxBorderLine,
#[serde(rename(serialize = "hh:rightBorder", deserialize = "rightBorder"))]
pub right_border: HxBorderLine,
#[serde(rename(serialize = "hh:topBorder", deserialize = "topBorder"))]
pub top_border: HxBorderLine,
#[serde(rename(serialize = "hh:bottomBorder", deserialize = "bottomBorder"))]
pub bottom_border: HxBorderLine,
#[serde(
rename(serialize = "hh:diagonal", deserialize = "diagonal"),
default,
skip_serializing_if = "Option::is_none"
)]
pub diagonal: Option<HxBorderLine>,
#[serde(
rename(serialize = "hc:fillBrush", deserialize = "fillBrush"),
default,
skip_serializing_if = "Option::is_none"
)]
pub fill_brush: Option<HxFillBrush>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct HxDiagonalBorder {
#[serde(rename = "@type", default)]
pub border_type: String,
#[serde(rename = "@Crooked", default)]
pub crooked: String,
#[serde(rename = "@isCounter", default)]
pub is_counter: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct HxBorderLine {
#[serde(rename = "@type", default)]
pub border_type: String,
#[serde(rename = "@width", default)]
pub width: String,
#[serde(rename = "@color", default)]
pub color: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct HxFillBrush {
#[serde(
rename(serialize = "hc:winBrush", deserialize = "winBrush"),
default,
skip_serializing_if = "Option::is_none"
)]
pub win_brush: Option<HxWinBrush>,
#[serde(
rename(serialize = "hc:gradation", deserialize = "gradation"),
default,
skip_serializing_if = "Option::is_none"
)]
pub gradation: Option<HxGradation>,
#[serde(
rename(serialize = "hc:imgBrush", deserialize = "imgBrush"),
default,
skip_serializing_if = "Option::is_none"
)]
pub img_brush: Option<HxImgBrush>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct HxWinBrush {
#[serde(rename = "@faceColor", default)]
pub face_color: String,
#[serde(rename = "@hatchColor", default)]
pub hatch_color: String,
#[serde(rename = "@hatchStyle", default, skip_serializing_if = "Option::is_none")]
pub hatch_style: Option<String>,
#[serde(rename = "@alpha", default)]
pub alpha: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct HxGradation {
#[serde(rename = "@type", default)]
pub gradation_type: String,
#[serde(rename = "@angle", default, deserialize_with = "deser_i32_or_u32")]
pub angle: i32,
#[serde(rename = "@centerX", default, deserialize_with = "deser_i32_or_u32")]
pub center_x: i32,
#[serde(rename = "@centerY", default, deserialize_with = "deser_i32_or_u32")]
pub center_y: i32,
#[serde(rename = "@step", default, deserialize_with = "deser_i32_or_u32")]
pub step: i32,
#[serde(rename = "@colorNum", default, deserialize_with = "deser_i32_or_u32")]
pub color_num: i32,
#[serde(rename = "@stepCenter", default, deserialize_with = "deser_i32_or_u32")]
pub step_center: i32,
#[serde(rename = "@alpha", default, deserialize_with = "deser_i32_or_u32")]
pub alpha: i32,
#[serde(rename(serialize = "hc:color", deserialize = "color"), default)]
pub colors: Vec<HxGradColor>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct HxImgBrush {
#[serde(rename = "@mode", default)]
pub mode: String,
#[serde(
rename(serialize = "hc:img", deserialize = "img"),
default,
skip_serializing_if = "Option::is_none"
)]
pub img: Option<HxImg>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct HxGradColor {
#[serde(rename = "@value", default)]
pub value: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct HxImg {
#[serde(rename = "@binaryItemIDRef", default)]
pub binary_item_id_ref: String,
#[serde(rename = "@bright", default, deserialize_with = "deser_i32_or_u32")]
pub bright: i32,
#[serde(rename = "@contrast", default, deserialize_with = "deser_i32_or_u32")]
pub contrast: i32,
#[serde(rename = "@effect", default)]
pub effect: String,
#[serde(rename = "@alpha", default, deserialize_with = "deser_i32_or_u32")]
pub alpha: i32,
}
#[derive(Debug, Serialize, Deserialize, Default, PartialEq)]
pub struct HxNumberings {
#[serde(rename = "@itemCnt", default)]
pub item_cnt: u32,
#[serde(rename(serialize = "hh:numbering", deserialize = "numbering"), default)]
pub items: Vec<HxNumbering>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct HxNumbering {
#[serde(rename = "@id")]
pub id: u32,
#[serde(rename = "@start", default)]
pub start: u32,
#[serde(rename(serialize = "hh:paraHead", deserialize = "paraHead"), default)]
pub para_heads: Vec<HxParaHead>,
}
#[derive(Debug, Serialize, Deserialize, Default, PartialEq)]
pub struct HxBullets {
#[serde(rename = "@itemCnt", default)]
pub item_cnt: u32,
#[serde(rename(serialize = "hh:bullet", deserialize = "bullet"), default)]
pub items: Vec<HxBullet>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct HxBullet {
#[serde(rename = "@id")]
pub id: u32,
#[serde(rename = "@char", default)]
pub bullet_char: String,
#[serde(rename = "@checkedChar", default, skip_serializing_if = "Option::is_none")]
pub checked_char: Option<String>,
#[serde(rename = "@useImage", default)]
pub use_image: u32,
#[serde(rename(serialize = "hh:paraHead", deserialize = "paraHead"), default)]
pub para_heads: Vec<HxBulletParaHead>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct HxBulletParaHead {
#[serde(rename = "@level", default)]
pub level: u32,
#[serde(rename = "@align", default)]
pub align: String,
#[serde(rename = "@useInstWidth", default)]
pub use_inst_width: u32,
#[serde(rename = "@autoIndent", default)]
pub auto_indent: u32,
#[serde(rename = "@widthAdjust", default)]
pub width_adjust: u32,
#[serde(rename = "@textOffsetType", default)]
pub text_offset_type: String,
#[serde(rename = "@textOffset", default)]
pub text_offset: u32,
#[serde(rename = "@numFormat", default)]
pub num_format: String,
#[serde(rename = "@charPrIDRef", default)]
pub char_pr_id_ref: u32,
#[serde(rename = "@checkable", default)]
pub checkable: u32,
#[serde(rename = "$text", default, skip_serializing_if = "String::is_empty")]
pub text: String,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct HxParaHead {
#[serde(rename = "@start", default)]
pub start: u32,
#[serde(rename = "@level", default)]
pub level: u32,
#[serde(rename = "@align", default)]
pub align: String,
#[serde(rename = "@useInstWidth", default)]
pub use_inst_width: u32,
#[serde(rename = "@autoIndent", default)]
pub auto_indent: u32,
#[serde(rename = "@widthAdjust", default)]
pub width_adjust: u32,
#[serde(rename = "@textOffsetType", default)]
pub text_offset_type: String,
#[serde(rename = "@textOffset", default)]
pub text_offset: u32,
#[serde(rename = "@numFormat", default)]
pub num_format: String,
#[serde(rename = "@charPrIDRef", default)]
pub char_pr_id_ref: u32,
#[serde(rename = "@checkable", default)]
pub checkable: u32,
#[serde(rename = "$text", default)]
pub text: String,
}
#[derive(Debug, Serialize, Deserialize, Default, PartialEq)]
pub struct HxTabProperties {
#[serde(rename = "@itemCnt", default)]
pub item_cnt: u32,
#[serde(rename(serialize = "hh:tabPr", deserialize = "tabPr"), default)]
pub items: Vec<HxTabPr>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct HxTabPr {
#[serde(rename = "@id")]
pub id: u32,
#[serde(rename = "@autoTabLeft", default)]
pub auto_tab_left: u32,
#[serde(rename = "@autoTabRight", default)]
pub auto_tab_right: u32,
#[serde(rename(serialize = "hh:tabItem", deserialize = "tabItem"), default)]
pub items: Vec<HxTabItem>,
#[serde(rename(serialize = "hp:switch", deserialize = "switch"), default)]
pub switches: Vec<HxTabSwitch>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct HxTabItem {
#[serde(rename = "@pos")]
pub pos: u32,
#[serde(rename = "@type", default)]
pub tab_type: String,
#[serde(rename = "@leader", default)]
pub leader: String,
#[serde(rename = "@unit", default = "default_hwpunit")]
pub unit: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct HxTabSwitch {
#[serde(
rename(serialize = "hp:case", deserialize = "case"),
default,
skip_serializing_if = "Option::is_none"
)]
pub case: Option<HxTabSwitchCase>,
#[serde(
rename(serialize = "hp:default", deserialize = "default"),
default,
skip_serializing_if = "Option::is_none"
)]
pub default: Option<HxTabSwitchDefault>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct HxTabSwitchCase {
#[serde(
rename(serialize = "@hp:required-namespace", deserialize = "@required-namespace"),
default
)]
pub required_namespace: String,
#[serde(rename(serialize = "hh:tabItem", deserialize = "tabItem"), default)]
pub items: Vec<HxTabItem>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct HxTabSwitchDefault {
#[serde(rename(serialize = "hh:tabItem", deserialize = "tabItem"), default)]
pub items: Vec<HxTabItem>,
}
#[cfg(test)]
mod tests {
use super::*;
fn parse_head(xml: &str) -> HxHead {
quick_xml::de::from_str(xml).expect("failed to parse HxHead")
}
#[test]
fn parse_minimal_head() {
let xml = r#"<hh:head version="1.4" secCnt="1"></hh:head>"#;
let head = parse_head(xml);
assert_eq!(head.version, "1.4");
assert_eq!(head.sec_cnt, 1);
assert!(head.ref_list.is_none());
}
#[test]
fn parse_fontfaces() {
let xml = r#"
<hh:head version="1.4" secCnt="1">
<hh:refList>
<hh:fontfaces itemCnt="1">
<hh:fontface lang="HANGUL" fontCnt="1">
<hh:font id="0" face="함초롬돋움" type="TTF" isEmbedded="0"/>
</hh:fontface>
</hh:fontfaces>
</hh:refList>
</hh:head>"#;
let head = parse_head(xml);
let ff = head.ref_list.unwrap().fontfaces.unwrap();
assert_eq!(ff.groups.len(), 1);
assert_eq!(ff.groups[0].lang, "HANGUL");
assert_eq!(ff.groups[0].fonts[0].face, "함초롬돋움");
}
#[test]
fn parse_char_pr_basic() {
let xml = r##"
<hh:head version="1.4" secCnt="1">
<hh:refList>
<hh:charProperties itemCnt="1">
<hh:charPr id="0" height="1000" textColor="#000000" shadeColor="none"
useFontSpace="0" useKerning="0" symMark="NONE" borderFillIDRef="2">
<hh:fontRef hangul="1" latin="1" hanja="1" japanese="1" other="1" symbol="1" user="1"/>
<hh:underline type="NONE" shape="SOLID" color="#000000"/>
<hh:strikeout shape="NONE" color="#000000"/>
<hh:outline type="NONE"/>
<hh:shadow type="NONE" color="#B2B2B2" offsetX="10" offsetY="10"/>
</hh:charPr>
</hh:charProperties>
</hh:refList>
</hh:head>"##;
let head = parse_head(xml);
let cp = &head.ref_list.unwrap().char_properties.unwrap().items[0];
assert_eq!(cp.id, 0);
assert_eq!(cp.height, 1000);
assert_eq!(cp.text_color, "#000000");
assert_eq!(cp.shade_color, "none");
let fr = cp.font_ref.as_ref().unwrap();
assert_eq!(fr.hangul, 1);
assert_eq!(fr.latin, 1);
assert!(cp.bold.is_none());
assert!(cp.italic.is_none());
}
#[test]
fn parse_char_pr_with_italic() {
let xml = r##"
<hh:head version="1.4" secCnt="1">
<hh:refList>
<hh:charProperties itemCnt="1">
<hh:charPr id="7" height="1000" textColor="#FF0000" shadeColor="none"
useFontSpace="0" useKerning="0" symMark="NONE" borderFillIDRef="2">
<hh:fontRef hangul="1" latin="1" hanja="1" japanese="1" other="1" symbol="1" user="1"/>
<hh:italic/>
<hh:underline type="NONE" shape="SOLID" color="#000000"/>
<hh:strikeout shape="NONE" color="#000000"/>
<hh:outline type="NONE"/>
<hh:shadow type="NONE" color="#B2B2B2" offsetX="10" offsetY="10"/>
</hh:charPr>
</hh:charProperties>
</hh:refList>
</hh:head>"##;
let head = parse_head(xml);
let cp = &head.ref_list.unwrap().char_properties.unwrap().items[0];
assert_eq!(cp.id, 7);
assert_eq!(cp.text_color, "#FF0000");
assert!(cp.italic.is_some(), "italic should be present");
assert!(cp.bold.is_none());
}
#[test]
fn parse_para_pr_with_switch() {
let xml = r#"
<hh:head version="1.4" secCnt="1">
<hh:refList>
<hh:paraProperties itemCnt="1">
<hh:paraPr id="0" tabPrIDRef="0" condense="0">
<hh:align horizontal="LEFT" vertical="BASELINE"/>
<hp:switch>
<hp:case hp:required-namespace="http://www.hancom.co.kr/hwpml/2016/HwpUnitChar">
<hh:margin>
<hc:intent value="0" unit="HWPUNIT"/>
<hc:left value="0" unit="HWPUNIT"/>
<hc:right value="0" unit="HWPUNIT"/>
<hc:prev value="0" unit="HWPUNIT"/>
<hc:next value="0" unit="HWPUNIT"/>
</hh:margin>
<hh:lineSpacing type="PERCENT" value="130" unit="HWPUNIT"/>
</hp:case>
<hp:default>
<hh:margin>
<hc:intent value="0" unit="HWPUNIT"/>
<hc:left value="0" unit="HWPUNIT"/>
<hc:right value="0" unit="HWPUNIT"/>
<hc:prev value="0" unit="HWPUNIT"/>
<hc:next value="0" unit="HWPUNIT"/>
</hh:margin>
<hh:lineSpacing type="PERCENT" value="130" unit="HWPUNIT"/>
</hp:default>
</hp:switch>
</hh:paraPr>
</hh:paraProperties>
</hh:refList>
</hh:head>"#;
let head = parse_head(xml);
let pp = &head.ref_list.unwrap().para_properties.unwrap().items[0];
assert_eq!(pp.id, 0);
let align = pp.align.as_ref().unwrap();
assert_eq!(align.horizontal, "LEFT");
let sw = pp.switches.first().unwrap();
let def = sw.default.as_ref().unwrap();
let margin = def.margin.as_ref().unwrap();
assert_eq!(margin.left.as_ref().unwrap().value, 0);
let ls = def.line_spacing.as_ref().unwrap();
assert_eq!(ls.spacing_type, "PERCENT");
assert_eq!(ls.value, 130);
}
#[test]
fn parse_para_pr_with_non_zero_margin() {
let xml = r#"
<hh:head version="1.4" secCnt="1">
<hh:refList>
<hh:paraProperties itemCnt="1">
<hh:paraPr id="4" tabPrIDRef="1" condense="20">
<hh:align horizontal="JUSTIFY" vertical="BASELINE"/>
<hp:switch>
<hp:default>
<hh:margin>
<hc:intent value="0" unit="HWPUNIT"/>
<hc:left value="14000" unit="HWPUNIT"/>
<hc:right value="0" unit="HWPUNIT"/>
<hc:prev value="0" unit="HWPUNIT"/>
<hc:next value="0" unit="HWPUNIT"/>
</hh:margin>
<hh:lineSpacing type="PERCENT" value="160" unit="HWPUNIT"/>
</hp:default>
</hp:switch>
</hh:paraPr>
</hh:paraProperties>
</hh:refList>
</hh:head>"#;
let head = parse_head(xml);
let pp = &head.ref_list.unwrap().para_properties.unwrap().items[0];
let def = pp.switches.first().unwrap().default.as_ref().unwrap();
let margin = def.margin.as_ref().unwrap();
assert_eq!(margin.left.as_ref().unwrap().value, 14000);
assert_eq!(def.line_spacing.as_ref().unwrap().value, 160);
}
#[test]
fn parse_styles() {
let xml = r#"
<hh:head version="1.4" secCnt="1">
<hh:refList>
<hh:styles itemCnt="2">
<hh:style id="0" type="PARA" name="바탕글" engName="Normal"
paraPrIDRef="3" charPrIDRef="0" nextStyleIDRef="0" langID="1042"/>
<hh:style id="1" type="PARA" name="본문" engName="Body"
paraPrIDRef="11" charPrIDRef="0" nextStyleIDRef="1" langID="1042"/>
</hh:styles>
</hh:refList>
</hh:head>"#;
let head = parse_head(xml);
let styles = head.ref_list.unwrap().styles.unwrap();
assert_eq!(styles.items.len(), 2);
assert_eq!(styles.items[0].name, "바탕글");
assert_eq!(styles.items[0].eng_name, "Normal");
assert_eq!(styles.items[0].para_pr_id_ref, 3);
assert_eq!(styles.items[0].char_pr_id_ref, 0);
assert_eq!(styles.items[1].name, "본문");
}
#[test]
fn parse_tab_pr_with_switch_items() {
let xml = r#"
<hh:head version="1.4" secCnt="1">
<hh:refList>
<hh:tabProperties itemCnt="4">
<hh:tabPr id="3" autoTabLeft="0" autoTabRight="0">
<hp:switch>
<hp:case hp:required-namespace="http://www.hancom.co.kr/hwpml/2016/HwpUnitChar">
<hh:tabItem pos="15000" type="LEFT" leader="DASH" unit="HWPUNIT"/>
</hp:case>
<hp:default>
<hh:tabItem pos="30000" type="LEFT" leader="DASH"/>
</hp:default>
</hp:switch>
</hh:tabPr>
</hh:tabProperties>
</hh:refList>
</hh:head>"#;
let head = parse_head(xml);
let tab_pr = &head.ref_list.unwrap().tab_properties.unwrap().items[0];
assert_eq!(tab_pr.id, 3);
assert!(tab_pr.items.is_empty());
assert_eq!(tab_pr.switches.len(), 1);
let switch = &tab_pr.switches[0];
let case = switch.case.as_ref().unwrap();
assert_eq!(case.required_namespace, "http://www.hancom.co.kr/hwpml/2016/HwpUnitChar");
assert_eq!(case.items[0].pos, 15000);
assert_eq!(case.items[0].unit, "HWPUNIT");
let default = switch.default.as_ref().unwrap();
assert_eq!(default.items[0].pos, 30000);
assert_eq!(default.items[0].unit, "HWPUNIT");
}
#[test]
fn empty_ref_list_no_panic() {
let xml = r#"<hh:head version="1.4" secCnt="1"><hh:refList/></hh:head>"#;
let head = parse_head(xml);
let rl = head.ref_list.unwrap();
assert!(rl.fontfaces.is_none());
assert!(rl.char_properties.is_none());
assert!(rl.para_properties.is_none());
assert!(rl.styles.is_none());
}
#[test]
fn unknown_elements_are_silently_skipped() {
let xml = r#"
<hh:head version="1.4" secCnt="1">
<hh:refList>
<hh:borderFills itemCnt="0"/>
<hh:tabProperties itemCnt="0"/>
<hh:numberings itemCnt="0"/>
<hh:charProperties itemCnt="0"/>
<hh:paraProperties itemCnt="0"/>
</hh:refList>
<hh:compatibleDocument targetProgram="HWP201X"/>
<hh:docOption/>
<hh:trackchageConfig flags="56"/>
</hh:head>"#;
let head = parse_head(xml);
assert!(head.ref_list.is_some());
}
#[test]
fn font_ref_defaults_to_zero() {
let fr = HxFontRef::default();
assert_eq!(fr.hangul, 0);
assert_eq!(fr.latin, 0);
assert_eq!(fr.user, 0);
}
}