use crate::{
tag::Tag as _,
tags::Svg,
xmlwriter::{Indent, Options as XmlOptions, XmlWriter}
};
use std::ops::{Deref, DerefMut};
pub struct Graphic(Svg);
impl Default for Graphic {
fn default() -> Self {
Self::new()
}
}
impl Graphic {
pub fn new() -> Self {
let mut svg = Svg::new();
svg.set_attr("xmlns".into(), "http://www.w3.org/2000/svg");
svg.set_attr("xmlns:xlink".into(), "http://www.w3.org/1999/xlink");
Self(svg)
}
fn write(&self, opts: XmlOptions, pretty: bool) -> String {
let mut writer = XmlWriter::new(opts);
self.0.write_to(&mut writer, pretty);
writer.end_document()
}
#[allow(clippy::inherent_to_string)]
pub fn to_string(&self) -> String {
let opts = XmlOptions {
use_single_quote: true,
indent: Indent::None,
attributes_indent: Indent::None
};
self.write(opts, false)
}
pub fn to_string_pretty(&self) -> String {
let opts = XmlOptions {
use_single_quote: true,
indent: Indent::Spaces(2),
attributes_indent: Indent::None
};
self.write(opts, true)
}
}
impl Deref for Graphic {
type Target = Svg;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for Graphic {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::tags::{TagWithPresentationAttributes, Text};
#[test]
fn empty_svg() {
let svg = Graphic::new();
let expected = "<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'/>";
assert_eq!(svg.to_string(), expected);
}
#[test]
fn hello_world() {
let mut svg = Graphic::new();
svg.set_view_box("0 0 200 50");
svg.push(
Text::new()
.with_x(100)
.with_y(25)
.with_text_anchor("middle")
.with_dominant_baseline("middle")
.append("Hello World!")
);
let expected = concat!(
"<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 200 50'>",
"<text x='100' y='25' text-anchor='middle' dominant-baseline='middle'>",
"Hello World!",
"</text>",
"</svg>"
);
assert_eq!(svg.to_string(), expected);
}
#[test]
#[cfg(feature = "raw")]
fn include_svg() {
let mut svg = Graphic::new();
svg.set_width(100);
svg.set_height(100);
svg.set_view_box("0 0 100 100");
svg.push(crate::RawXml::new_unchecked("<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='100' height='100' viewBox='0 0 100 100'><path d='M10,30a20,20,0,0,1,40,0a20,20,0,0,1,40,0q0,30,-40,60q-40,-30,-40,-60' fill='#A919FA' fill-opacity='0.5' stroke='#A919FA' stroke-width='3'/></svg>"));
let expected = concat!(
"<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='100' height='100' viewBox='0 0 100 100'>",
"<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='100' height='100' viewBox='0 0 100 100'><path d='M10,30a20,20,0,0,1,40,0a20,20,0,0,1,40,0q0,30,-40,60q-40,-30,-40,-60' fill='#A919FA' fill-opacity='0.5' stroke='#A919FA' stroke-width='3'/></svg>",
"</svg>"
);
assert_eq!(svg.to_string(), expected);
}
}