pub trait ToXml {
fn to_xml(&self) -> String;
fn write_xml(&self, writer: &mut String) {
writer.push_str(&self.to_xml());
}
}
pub trait Positioned {
fn x(&self) -> u32;
fn y(&self) -> u32;
fn set_position(&mut self, x: u32, y: u32);
}
pub trait Sized {
fn width(&self) -> u32;
fn height(&self) -> u32;
fn set_size(&mut self, width: u32, height: u32);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_to_xml_trait_dispatch() {
use crate::generator::text::{Paragraph, Run, TextFrame};
let items: Vec<Box<dyn ToXml>> = vec![
Box::new(Run::new("hello")),
Box::new(Paragraph::with_text("world")),
Box::new(TextFrame::with_text("frame")),
];
for item in &items {
let xml = item.to_xml();
assert!(
!xml.is_empty(),
"ToXml dispatch should produce non-empty XML"
);
}
assert!(items[0].to_xml().contains("hello"));
assert!(items[1].to_xml().contains("world"));
assert!(items[2].to_xml().contains("frame"));
}
#[test]
fn test_positioned_trait_dispatch() {
use crate::generator::images::Image;
use crate::generator::shapes::{Shape, ShapeType};
fn move_element(elem: &mut dyn Positioned, x: u32, y: u32) {
elem.set_position(x, y);
}
let mut shape = Shape::new(ShapeType::Rectangle, 0, 0, 1000, 1000);
let mut image = Image::new("test.png", 500, 500, "PNG");
move_element(&mut shape, 100, 200);
move_element(&mut image, 300, 400);
assert_eq!(shape.x(), 100);
assert_eq!(shape.y(), 200);
assert_eq!(image.x(), 300);
assert_eq!(image.y(), 400);
}
#[test]
fn test_element_sized_trait_dispatch() {
use crate::generator::images::Image;
use crate::generator::shapes::{Shape, ShapeType};
fn resize(elem: &mut dyn Sized, w: u32, h: u32) {
elem.set_size(w, h);
}
let mut shape = Shape::new(ShapeType::Rectangle, 0, 0, 1000, 1000);
let mut image = Image::new("test.png", 500, 500, "PNG");
resize(&mut shape, 2000, 3000);
resize(&mut image, 4000, 5000);
assert_eq!(shape.width(), 2000);
assert_eq!(shape.height(), 3000);
assert_eq!(image.width(), 4000);
assert_eq!(image.height(), 5000);
}
}