Skip to main content

easyofd_core/action/
bookmark_action.rs

1//! 书签动作。
2//!
3//! 对应 Java: org.ofdrw.core.action.actionType.Bookmark
4
5use super::CTDest;
6use super::OfdAction;
7
8/// 书签动作。
9///
10/// 定义一个书签,关联一个目标位置,对应 GB/T 33190 第 15 章的 Bookmark 动作。
11///
12/// 对应 Java: org.ofdrw.core.action.actionType.Bookmark
13#[derive(Debug, Clone)]
14pub struct Bookmark {
15    /// 书签名称。
16    ///
17    /// 对应 Java: Bookmark.name (String)
18    pub name: String,
19
20    /// 书签的目标位置。
21    ///
22    /// 对应 Java: Bookmark.dest (CT_Dest)
23    pub dest: CTDest,
24}
25
26impl Bookmark {
27    /// 创建一个新的书签动作。
28    ///
29    /// 对应 Java: new Bookmark(String name, CT_Dest dest)
30    #[must_use]
31    pub fn new(name: impl Into<String>, dest: CTDest) -> Self {
32        Self {
33            name: name.into(),
34            dest,
35        }
36    }
37}
38
39impl OfdAction for Bookmark {
40    fn to_xml_string(&self) -> String {
41        format!(
42            "<ofd:Bookmark Name=\"{}\">{}</ofd:Bookmark>",
43            self.name,
44            self.dest.to_xml_string()
45        )
46    }
47
48    fn clone_box(&self) -> Box<dyn OfdAction> {
49        Box::new(self.clone())
50    }
51}
52
53#[cfg(test)]
54mod tests {
55    use super::super::DestType;
56    use super::*;
57
58    #[test]
59    fn test_bookmark_new() {
60        let dest = CTDest::new(1);
61        let bm = Bookmark::new("Chapter 1", dest);
62        assert_eq!(bm.name, "Chapter 1");
63        assert_eq!(bm.dest.page, 1);
64    }
65
66    #[test]
67    fn test_bookmark_to_xml() {
68        let dest = CTDest::new(5).dest_type(DestType::XYZ).left(10.0).top(20.0);
69        let bm = Bookmark::new("Section 2", dest);
70        let xml = bm.to_xml_string();
71        assert!(xml.contains("Name=\"Section 2\""));
72        assert!(xml.contains("<ofd:Bookmark"));
73        assert!(xml.contains("PageID=\"5\""));
74        assert!(xml.contains("Type=\"XYZ\""));
75        assert!(xml.contains("</ofd:Bookmark>"));
76    }
77
78    #[test]
79    fn test_bookmark_clone_debug() {
80        let dest = CTDest::new(3);
81        let bm = Bookmark::new("test", dest);
82        let bm2 = bm.clone();
83        assert_eq!(bm2.name, "test");
84        let dbg = format!("{bm:?}");
85        assert!(dbg.contains("Bookmark"));
86    }
87}