From 928e32fc1279ec4dcfe1f3a42e87454cf7315d8d Mon Sep 17 00:00:00 2001 From: aiongg Date: Mon, 26 Oct 2026 18:56:55 +0000 Subject: [PATCH] refactor(doc): split review items out of lib.rs into review.rs --- crates/doc/src/lib.rs | 95 ++-------------------------------------- crates/doc/src/review.rs | 93 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 91 deletions(-) create mode 100644 crates/doc/src/review.rs diff --git a/crates/doc/src/lib.rs b/crates/doc/src/lib.rs index 6090ecacd..7f8a12e17 100644 --- a/crates/doc/src/lib.rs +++ b/crates/doc/src/lib.rs @@ -63,6 +63,10 @@ pub use section::SectionProps; pub use styles::{Style, StyleKind, StyleSheet}; pub use table::{Cell, Row, Table}; +mod review; + +pub use review::{AUTO_TEXT_GALLERY, BuildingBlock, Comment, QUICK_PARTS_GALLERY, Revision, RevisionKind}; + #[derive(Debug, thiserror::Error, Clone, PartialEq)] pub enum DocError { #[error("offset {0} is not a character boundary in the paragraph")] @@ -431,97 +435,6 @@ impl TextBody { /// Most boxes one chain of linked text boxes runs through (hostile files). pub const MAX_LINKED_BOXES: usize = 256; -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Default)] -#[serde(default, rename_all = "camelCase")] -pub struct Comment { - pub author: String, - pub initials: String, - /// ISO 8601. - pub date: String, - /// Reply to this comment id. - pub parent: Option, - pub resolved: bool, - /// `Document::parts` id of the comment text. - pub part: u32, - /// Word's durable id for the comment (`w16cid:durableId`, hex), kept across saves so Word - /// keeps tracking the same comment. `None` for comments made here: the writer assigns one. - #[serde(skip_serializing_if = "Option::is_none")] - pub durable_id: Option, - /// The comment's UTC timestamp: from the file (`w16cex:dateUtc`, where `date` is local time), - /// or the time WordCraft stamped the comment with. - #[serde(skip_serializing_if = "Option::is_none")] - pub date_utc: Option, -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] -#[serde(rename_all = "camelCase")] -pub enum RevisionKind { - #[default] - Insert, - Delete, - Format, -} - -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Default)] -#[serde(default)] -pub struct Revision { - pub kind: RevisionKind, - pub author: String, - pub date: String, - /// A move (ECMA-376 §17.13.5.21–28): the name linking the source (an `Delete` revision, - /// `w:moveFrom`) with the destination (an `Insert` revision, `w:moveTo`). `None` = a plain - /// insertion or deletion. - #[serde(skip_serializing_if = "Option::is_none")] - pub move_name: Option, -} - -impl Revision { - pub fn new(kind: RevisionKind, author: impl Into, date: impl Into) -> Revision { - Revision { kind, author: author.into(), date: date.into(), move_name: None } - } -} - -impl Document { - /// The move name of revision `idx`, when it is one end of a move. - pub fn move_name(&self, idx: Option) -> Option<&str> { - idx.and_then(|i| self.revisions.get(i as usize)).and_then(|r| r.move_name.as_deref()) - } -} - -/// A building block (Insert › Quick Parts, AutoText…) kept in the document's glossary -/// (ECMA-376 §17.12: `w:docPart`). -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Default)] -#[serde(default, rename_all = "camelCase")] -pub struct BuildingBlock { - /// The entry's name (`w:docPartPr/w:name`). - pub name: String, - /// Its gallery (`w:category/w:gallery`: `docParts` for Quick Parts, `autoTxt` for AutoText…). - pub gallery: String, - /// Its category within the gallery (`w:category/w:name`, e.g. "General"). - pub category: String, - #[serde(skip_serializing_if = "String::is_empty")] - pub description: String, - /// The entry's identity (`w:guid`), kept as read. - #[serde(skip_serializing_if = "String::is_empty")] - pub guid: String, - /// The paragraph style it's associated with (`w:style`), kept as read. - #[serde(skip_serializing_if = "String::is_empty")] - pub style: String, - /// Its types (`w:types/w:type`: `normal`, `bbPlcHdr` for a content control's placeholder…). - #[serde(skip_serializing_if = "Vec::is_empty")] - pub types: Vec, - /// How it's inserted (`w:behaviors/w:behavior`: `content`, `p`, `pg`). - #[serde(skip_serializing_if = "Vec::is_empty")] - pub behaviors: Vec, - /// The content (`w:docPartBody`). - pub blocks: Blocks, -} - -/// The gallery Quick Parts saves to (`w:gallery w:val="docParts"`). -pub const QUICK_PARTS_GALLERY: &str = "docParts"; -/// The AutoText gallery (`w:gallery w:val="autoTxt"`). -pub const AUTO_TEXT_GALLERY: &str = "autoTxt"; - /// A bibliography source. #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Default)] #[serde(default, rename_all = "camelCase")] diff --git a/crates/doc/src/review.rs b/crates/doc/src/review.rs new file mode 100644 index 000000000..47d9f7232 --- /dev/null +++ b/crates/doc/src/review.rs @@ -0,0 +1,93 @@ +use super::*; + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Default)] +#[serde(default, rename_all = "camelCase")] +pub struct Comment { + pub author: String, + pub initials: String, + /// ISO 8601. + pub date: String, + /// Reply to this comment id. + pub parent: Option, + pub resolved: bool, + /// `Document::parts` id of the comment text. + pub part: u32, + /// Word's durable id for the comment (`w16cid:durableId`, hex), kept across saves so Word + /// keeps tracking the same comment. `None` for comments made here: the writer assigns one. + #[serde(skip_serializing_if = "Option::is_none")] + pub durable_id: Option, + /// The comment's UTC timestamp: from the file (`w16cex:dateUtc`, where `date` is local time), + /// or the time WordCraft stamped the comment with. + #[serde(skip_serializing_if = "Option::is_none")] + pub date_utc: Option, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Default)] +#[serde(rename_all = "camelCase")] +pub enum RevisionKind { + #[default] + Insert, + Delete, + Format, +} + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Default)] +#[serde(default)] +pub struct Revision { + pub kind: RevisionKind, + pub author: String, + pub date: String, + /// A move (ECMA-376 §17.13.5.21–28): the name linking the source (an `Delete` revision, + /// `w:moveFrom`) with the destination (an `Insert` revision, `w:moveTo`). `None` = a plain + /// insertion or deletion. + #[serde(skip_serializing_if = "Option::is_none")] + pub move_name: Option, +} + +impl Revision { + pub fn new(kind: RevisionKind, author: impl Into, date: impl Into) -> Revision { + Revision { kind, author: author.into(), date: date.into(), move_name: None } + } +} + +impl Document { + /// The move name of revision `idx`, when it is one end of a move. + pub fn move_name(&self, idx: Option) -> Option<&str> { + idx.and_then(|i| self.revisions.get(i as usize)).and_then(|r| r.move_name.as_deref()) + } +} + +/// A building block (Insert › Quick Parts, AutoText…) kept in the document's glossary +/// (ECMA-376 §17.12: `w:docPart`). +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Default)] +#[serde(default, rename_all = "camelCase")] +pub struct BuildingBlock { + /// The entry's name (`w:docPartPr/w:name`). + pub name: String, + /// Its gallery (`w:category/w:gallery`: `docParts` for Quick Parts, `autoTxt` for AutoText…). + pub gallery: String, + /// Its category within the gallery (`w:category/w:name`, e.g. "General"). + pub category: String, + #[serde(skip_serializing_if = "String::is_empty")] + pub description: String, + /// The entry's identity (`w:guid`), kept as read. + #[serde(skip_serializing_if = "String::is_empty")] + pub guid: String, + /// The paragraph style it's associated with (`w:style`), kept as read. + #[serde(skip_serializing_if = "String::is_empty")] + pub style: String, + /// Its types (`w:types/w:type`: `normal`, `bbPlcHdr` for a content control's placeholder…). + #[serde(skip_serializing_if = "Vec::is_empty")] + pub types: Vec, + /// How it's inserted (`w:behaviors/w:behavior`: `content`, `p`, `pg`). + #[serde(skip_serializing_if = "Vec::is_empty")] + pub behaviors: Vec, + /// The content (`w:docPartBody`). + pub blocks: Blocks, +} + +/// The gallery Quick Parts saves to (`w:gallery w:val="docParts"`). +pub const QUICK_PARTS_GALLERY: &str = "docParts"; + +/// The AutoText gallery (`w:gallery w:val="autoTxt"`). +pub const AUTO_TEXT_GALLERY: &str = "autoTxt";