summaryrefslogtreecommitdiff
path: root/src/diagrams.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/diagrams.rs')
-rw-r--r--src/diagrams.rs40
1 files changed, 33 insertions, 7 deletions
diff --git a/src/diagrams.rs b/src/diagrams.rs
index 6e0b875..a62553f 100644
--- a/src/diagrams.rs
+++ b/src/diagrams.rs
@@ -59,6 +59,32 @@ lazy_static! {
static ref JAVA_PATH: Mutex<PathBuf> = Mutex::new(env!("BUILTIN_JAVA_PATH").into());
}
+/// An SVG image.
+///
+/// SVG images are vector images, but we only need to treat them as
+/// opaque blobs of bytes, so we don't try to represent them in any
+/// other way.
+pub struct Svg {
+ data: Vec<u8>,
+}
+
+impl Svg {
+ fn new(data: Vec<u8>) -> Self {
+ Self { data }
+ }
+
+ /// Return slice of the bytes of the image.
+ pub fn data(&self) -> &[u8] {
+ &self.data
+ }
+
+ /// Number of bytes in the binary representation of the image.
+ #[allow(clippy::len_without_is_empty)] // is-empty doesn't make sense
+ pub fn len(&self) -> usize {
+ self.data.len()
+ }
+}
+
/// A code block with markup for a diagram.
///
/// The code block will be converted to an SVG image using an external
@@ -71,7 +97,7 @@ lazy_static! {
/// for the trait.
pub trait DiagramMarkup {
/// Convert the markup into an SVG.
- fn as_svg(&self) -> Result<Vec<u8>, SubplotError>;
+ fn as_svg(&self) -> Result<Svg, SubplotError>;
}
/// A code block with pikchr markup.
@@ -98,12 +124,12 @@ impl PikchrMarkup {
}
impl DiagramMarkup for PikchrMarkup {
- fn as_svg(&self) -> Result<Vec<u8>, SubplotError> {
+ fn as_svg(&self) -> Result<Svg, SubplotError> {
let mut flags = pikchr::PikchrFlags::default();
flags.generate_plain_errors();
let image = pikchr::Pikchr::render(&self.markup, self.class.as_deref(), flags)
.map_err(SubplotError::PikchrRenderError)?;
- Ok(image.as_bytes().to_vec())
+ Ok(Svg::new(image.as_bytes().to_vec()))
}
}
@@ -129,7 +155,7 @@ impl DotMarkup {
}
impl DiagramMarkup for DotMarkup {
- fn as_svg(&self) -> Result<Vec<u8>, SubplotError> {
+ fn as_svg(&self) -> Result<Svg, SubplotError> {
let path = DOT_PATH.lock().unwrap().clone();
let mut child = Command::new(&path)
.arg("-Tsvg")
@@ -146,7 +172,7 @@ impl DiagramMarkup for DotMarkup {
.wait_with_output()
.map_err(SubplotError::WaitForChild)?;
if output.status.success() {
- Ok(output.stdout)
+ Ok(Svg::new(output.stdout))
} else {
Err(SubplotError::child_failed("dot", &output))
}
@@ -196,7 +222,7 @@ impl PlantumlMarkup {
}
impl DiagramMarkup for PlantumlMarkup {
- fn as_svg(&self) -> Result<Vec<u8>, SubplotError> {
+ fn as_svg(&self) -> Result<Svg, SubplotError> {
let path = JAVA_PATH.lock().unwrap().clone();
let mut cmd = Command::new(&path);
cmd.arg("-Djava.awt.headless=true")
@@ -225,7 +251,7 @@ impl DiagramMarkup for PlantumlMarkup {
.wait_with_output()
.map_err(SubplotError::WaitForChild)?;
if output.status.success() {
- Ok(output.stdout)
+ Ok(Svg::new(output.stdout))
} else {
Err(SubplotError::child_failed("plantuml", &output))
}