vis/src/render/svglib/svg.rs
2025-01-25 13:35:08 +01:00

90 lines
2.4 KiB
Rust

use crate::render::svglib::{att, att_to_string, Att, SvgElement, Value};
use std::fmt;
pub fn svg() -> Svg {
Svg::default()
}
#[derive(Default)]
pub struct Svg {
style: Option<String>,
elements: Vec<Box<dyn SvgElement>>,
atts: Vec<Att>,
}
impl Svg {
pub fn style(&mut self, style: &str) {
self.style = Some(style.to_string());
}
pub fn add(&mut self, child: impl SvgElement + 'static) {
self.elements.push(Box::new(child));
}
pub fn width<V: Into<Value>>(&mut self, width: V) {
self.atts.push(att("width", width.into().to_string()));
}
pub fn height<V: Into<Value>>(&mut self, height: V) {
self.atts.push(att("height", height.into().to_string()));
}
pub fn viewbox<V: Into<Value>>(&mut self, viewbox: V) {
self.atts.push(att("viewBox", viewbox));
}
pub fn preserveaspectratio<V: Into<Value>>(&mut self, preserveaspectratio: V) {
self.atts
.push(att("preserveAspectRatio", preserveaspectratio));
}
pub fn transform<V: Into<Value>>(&mut self, transform: V) {
self.atts.push(att("transform", transform));
}
}
impl fmt::Display for Svg {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
r#"<svg xmlns="http://www.w3.org/2000/svg"{}>{}"#,
self.atts.iter().map(att_to_string).collect::<String>(),
self.style
.as_ref()
.map(|s| format!("<style>{}</style>", s))
.unwrap_or("".to_string())
)?;
for e in &self.elements {
write!(f, "{}", e.to_string().as_str())?;
}
write!(f, "</svg>")
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::render::svglib::rect::rect;
#[test]
fn style() {
let mut svg = svg();
svg.style(".id { background-color: red; }");
assert_eq!(
r#"<svg xmlns="http://www.w3.org/2000/svg"><style>.id { background-color: red; }</style></svg>"#,
svg.to_string()
)
}
#[test]
fn add_rect() {
let mut svg = svg();
svg.preserveaspectratio("none");
svg.add(rect().x(0).y(0).width(10).height(10));
assert_eq!(
r#"<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none"><rect x="0" y="0" width="10" height="10" /></svg>"#,
svg.to_string()
)
}
}