#[derive(Debug, Clone)]
pub struct Bookmark {
pub name: String,
pub page: u32,
pub y_offset: Option<f64>,
}
impl Bookmark {
#[must_use]
pub fn new(name: impl Into<String>, page: u32) -> Self {
Self {
name: name.into(),
page,
y_offset: None,
}
}
#[must_use]
pub fn with_y_offset(mut self, y_offset: f64) -> Self {
self.y_offset = Some(y_offset);
self
}
#[must_use]
pub fn to_xml_string(&self) -> String {
let mut attrs = format!("Name=\"{}\" Page=\"{}\"", self.name, self.page);
if let Some(y) = self.y_offset {
use std::fmt::Write;
let _ = write!(attrs, " YOffset=\"{y}\"");
}
format!("<Bookmark {attrs}/>")
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_bookmark_new() {
let b = Bookmark::new("Introduction", 1);
assert_eq!(b.name, "Introduction");
assert_eq!(b.page, 1);
assert!(b.y_offset.is_none());
}
#[test]
fn test_bookmark_with_y_offset_and_xml() {
let b = Bookmark::new("Chapter 1", 3).with_y_offset(120.5);
let xml = b.to_xml_string();
assert!(xml.contains("Name=\"Chapter 1\""));
assert!(xml.contains("Page=\"3\""));
assert!(xml.contains("YOffset=\"120.5\""));
}
}