#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct RelId(String);
impl RelId {
pub fn new(id: impl Into<String>) -> Self {
Self(id.into())
}
pub fn as_str(&self) -> &str {
&self.0
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct NoteId(i64);
impl NoteId {
pub fn new(id: i64) -> Self {
Self(id)
}
pub fn value(self) -> i64 {
self.0
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct BookmarkId(i64);
impl BookmarkId {
pub fn new(id: i64) -> Self {
Self(id)
}
pub fn value(self) -> i64 {
self.0
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct StyleId(String);
impl StyleId {
pub fn new(id: impl Into<String>) -> Self {
Self(id.into())
}
pub fn as_str(&self) -> &str {
&self.0
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct AbstractNumId(i64);
impl AbstractNumId {
pub fn new(id: i64) -> Self {
Self(id)
}
pub fn value(self) -> i64 {
self.0
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct NumId(i64);
impl NumId {
pub fn new(id: i64) -> Self {
Self(id)
}
pub fn value(self) -> i64 {
self.0
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct NumPicBulletId(i64);
impl NumPicBulletId {
pub fn new(id: i64) -> Self {
Self(id)
}
pub fn value(self) -> i64 {
self.0
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct VmlShapeId(String);
impl VmlShapeId {
pub fn new(id: impl Into<String>) -> Self {
Self(id.into())
}
pub fn as_str(&self) -> &str {
&self.0
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct RevisionSaveId(u32);
impl RevisionSaveId {
pub fn value(self) -> u32 {
self.0
}
pub fn from_hex(s: &str) -> Option<Self> {
u32::from_str_radix(s, 16).ok().map(Self)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub struct RevisionIds {
pub r: Option<RevisionSaveId>,
pub r_pr: Option<RevisionSaveId>,
pub del: Option<RevisionSaveId>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub struct ParagraphRevisionIds {
pub r: Option<RevisionSaveId>,
pub r_default: Option<RevisionSaveId>,
pub p: Option<RevisionSaveId>,
pub r_pr: Option<RevisionSaveId>,
pub del: Option<RevisionSaveId>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub struct TableRowRevisionIds {
pub r: Option<RevisionSaveId>,
pub r_pr: Option<RevisionSaveId>,
pub del: Option<RevisionSaveId>,
pub tr: Option<RevisionSaveId>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub struct SectionRevisionIds {
pub r: Option<RevisionSaveId>,
pub r_pr: Option<RevisionSaveId>,
pub sect: Option<RevisionSaveId>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn revision_save_id_parses_eight_digit_hex() {
assert_eq!(
RevisionSaveId::from_hex("00A2B3C4").unwrap().value(),
0x00A2_B3C4
);
assert_eq!(
RevisionSaveId::from_hex("FFFFFFFF").unwrap().value(),
0xFFFF_FFFF
);
}
#[test]
fn revision_save_id_rejects_non_hex() {
assert!(RevisionSaveId::from_hex("XYZ").is_none());
assert!(RevisionSaveId::from_hex("").is_none());
assert!(RevisionSaveId::from_hex("-1").is_none());
}
#[test]
fn revision_save_id_rejects_overflow() {
assert!(RevisionSaveId::from_hex("1FFFFFFFF").is_none());
}
#[test]
fn typed_id_accessors_round_trip() {
assert_eq!(RelId::new("rId7").as_str(), "rId7");
assert_eq!(NumId::new(3).value(), 3);
assert_eq!(StyleId::new("Heading1").as_str(), "Heading1");
assert_eq!(VmlShapeId::new("_x0000_t202").as_str(), "_x0000_t202");
}
}