easyofd_core/action/
ct_dest.rs1use std::fmt::Write;
6
7use super::DestType;
8
9#[derive(Debug, Clone, PartialEq)]
15pub struct CTDest {
16 pub page: u32,
20
21 pub dest_type: DestType,
25
26 pub left: Option<f64>,
31
32 pub top: Option<f64>,
37
38 pub zoom: Option<f64>,
43}
44
45impl CTDest {
46 #[must_use]
50 pub fn new(page: u32) -> Self {
51 Self {
52 page,
53 dest_type: DestType::Fit,
54 left: None,
55 top: None,
56 zoom: None,
57 }
58 }
59
60 #[must_use]
64 pub fn dest_type(mut self, dest_type: DestType) -> Self {
65 self.dest_type = dest_type;
66 self
67 }
68
69 #[must_use]
73 pub fn left(mut self, left: f64) -> Self {
74 self.left = Some(left);
75 self
76 }
77
78 #[must_use]
82 pub fn top(mut self, top: f64) -> Self {
83 self.top = Some(top);
84 self
85 }
86
87 #[must_use]
91 pub fn zoom(mut self, zoom: f64) -> Self {
92 self.zoom = Some(zoom);
93 self
94 }
95
96 #[must_use]
100 pub fn to_xml_string(&self) -> String {
101 let mut attrs = format!("PageID=\"{}\" Type=\"{}\"", self.page, self.dest_type);
102
103 if let Some(left) = self.left {
104 let _ = write!(attrs, " Left=\"{left}\"");
105 }
106 if let Some(top) = self.top {
107 let _ = write!(attrs, " Top=\"{top}\"");
108 }
109 if let Some(zoom) = self.zoom {
110 let _ = write!(attrs, " Zoom=\"{zoom}\"");
111 }
112
113 format!("<ofd:Dest {attrs}/>")
114 }
115}
116
117#[cfg(test)]
118mod tests {
119 use super::*;
120
121 #[test]
122 fn test_ct_dest_new() {
123 let dest = CTDest::new(3);
124 assert_eq!(dest.page, 3);
125 assert_eq!(dest.dest_type, DestType::Fit);
126 assert!(dest.left.is_none());
127 assert!(dest.top.is_none());
128 assert!(dest.zoom.is_none());
129 }
130
131 #[test]
132 fn test_ct_dest_builder() {
133 let dest = CTDest::new(1)
134 .dest_type(DestType::XYZ)
135 .left(10.0)
136 .top(20.0)
137 .zoom(1.5);
138 assert_eq!(dest.page, 1);
139 assert_eq!(dest.dest_type, DestType::XYZ);
140 assert_eq!(dest.left, Some(10.0));
141 assert_eq!(dest.top, Some(20.0));
142 assert_eq!(dest.zoom, Some(1.5));
143 }
144
145 #[test]
146 fn test_ct_dest_to_xml_fit() {
147 let dest = CTDest::new(5);
148 let xml = dest.to_xml_string();
149 assert!(xml.contains("PageID=\"5\""));
150 assert!(xml.contains("Type=\"Fit\""));
151 assert!(!xml.contains("Left"));
152 }
153
154 #[test]
155 fn test_ct_dest_to_xml_xyz() {
156 let dest = CTDest::new(2)
157 .dest_type(DestType::XYZ)
158 .left(10.5)
159 .top(20.5)
160 .zoom(2.0);
161 let xml = dest.to_xml_string();
162 assert!(xml.contains("PageID=\"2\""));
163 assert!(xml.contains("Type=\"XYZ\""));
164 assert!(xml.contains("Left=\"10.5\""));
165 assert!(xml.contains("Top=\"20.5\""));
166 assert!(xml.contains("Zoom=\"2\""));
167 }
168
169 #[test]
170 fn test_ct_dest_clone_debug() {
171 let dest = CTDest::new(1).dest_type(DestType::FitH).left(5.0);
172 let dest2 = dest.clone();
173 assert_eq!(dest2.page, 1);
174 assert_eq!(dest2.dest_type, DestType::FitH);
175 let dbg = format!("{dest:?}");
176 assert!(dbg.contains("CTDest"));
177 }
178}