use serde::{Deserializer, de::Visitor};
pub fn deserialize_buffer<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Vec<u8>, D::Error> {
struct FileVisitor;
impl<'de> Visitor<'de> for FileVisitor {
type Value = Vec<u8>;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a valid path")
}
fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
std::fs::read(v).map_err(|e| E::custom(e))
}
fn visit_borrowed_str<E: serde::de::Error>(self, v: &'de str) -> Result<Self::Value, E> {
std::fs::read(v).map_err(|e| E::custom(e))
}
fn visit_string<E: serde::de::Error>(self, v: String) -> Result<Self::Value, E> {
std::fs::read(v).map_err(|e| E::custom(e))
}
}
Ok(deserializer.deserialize_str(FileVisitor)?)
}
pub fn deserialize_svg<'de, D: Deserializer<'de>>(deserializer: D) -> Result<usvg::Tree, D::Error> {
struct SvgVisitor;
impl<'de> Visitor<'de> for SvgVisitor {
type Value = usvg::Tree;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a valid svg")
}
fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
usvg::Tree::from_str(v, &Default::default()).map_err(|e| E::custom(e))
}
fn visit_borrowed_str<E: serde::de::Error>(self, v: &'de str) -> Result<Self::Value, E> {
usvg::Tree::from_str(v, &Default::default()).map_err(|e| E::custom(e))
}
fn visit_string<E: serde::de::Error>(self, v: String) -> Result<Self::Value, E> {
usvg::Tree::from_str(&v, &Default::default()).map_err(|e| E::custom(e))
}
}
Ok(deserializer.deserialize_str(SvgVisitor)?)
}
pub fn deserialize_svg_from_path<'de, D: Deserializer<'de>>(
deserializer: D,
) -> Result<usvg::Tree, D::Error> {
struct SvgVisitor;
impl<'de> Visitor<'de> for SvgVisitor {
type Value = usvg::Tree;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a valid svg")
}
fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
let data = std::fs::read(v).map_err(|e| E::custom(e))?;
usvg::Tree::from_data(&data, &Default::default()).map_err(|e| E::custom(e))
}
fn visit_borrowed_str<E: serde::de::Error>(self, v: &'de str) -> Result<Self::Value, E> {
let data = std::fs::read(v).map_err(|e| E::custom(e))?;
usvg::Tree::from_data(&data, &Default::default()).map_err(|e| E::custom(e))
}
fn visit_string<E: serde::de::Error>(self, v: String) -> Result<Self::Value, E> {
let data = std::fs::read(v).map_err(|e| E::custom(e))?;
usvg::Tree::from_data(&data, &Default::default()).map_err(|e| E::custom(e))
}
}
Ok(deserializer.deserialize_str(SvgVisitor)?)
}
#[derive(Clone)]
pub enum Image {
Svg(usvg::Tree),
Pixel(image::DynamicImage),
}
pub fn deserialize_image<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Image, D::Error> {
struct ImageVisitor;
fn visit<E: serde::de::Error>(path: impl AsRef<std::path::Path>) -> Result<Image, E> {
if path.as_ref().extension().map_or(false, |e| e == "svg") {
Ok(Image::Svg({
let data = std::fs::read(path).map_err(|e| E::custom(e))?;
usvg::Tree::from_data(&data, &Default::default()).map_err(|e| E::custom(e))?
}))
} else {
Ok(Image::Pixel(image::open(path).map_err(E::custom)?))
}
}
impl<'de> Visitor<'de> for ImageVisitor {
type Value = Image;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a valid image")
}
fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
visit(v)
}
fn visit_borrowed_str<E: serde::de::Error>(self, v: &'de str) -> Result<Self::Value, E> {
visit(v)
}
fn visit_string<E: serde::de::Error>(self, v: String) -> Result<Self::Value, E> {
visit(v)
}
}
Ok(deserializer.deserialize_str(ImageVisitor)?)
}