use crate::schema::helpers::slottable_object::SlottableObject;
use super::file_asset::FileAsset;
use serde::de::Deserializer;
use serde::{Deserialize, Serialize, Serializer};
#[derive(Deserialize, Serialize, Debug, Clone, PartialEq)]
pub struct Image {
#[serde(flatten)]
pub file_asset: FileAsset,
#[serde(flatten)]
pub slottable_object: SlottableObject,
#[serde(rename = "w")]
#[serde(skip_serializing_if = "Option::is_none")]
pub width: Option<f64>,
#[serde(rename = "h")]
#[serde(skip_serializing_if = "Option::is_none")]
pub height: Option<f64>,
#[serde(
rename = "t",
deserialize_with = "seq_from_str",
serialize_with = "seq_to_str",
default
)]
#[serde(skip_serializing_if = "Option::is_none")]
pub sequence: Option<bool>,
}
pub fn seq_from_str<'de, D>(deserializer: D) -> Result<Option<bool>, D::Error>
where
D: Deserializer<'de>,
{
let v = String::deserialize(deserializer)?;
if v == *"seq" {
Ok(Some(true))
} else {
Ok(None)
}
}
pub fn seq_to_str<S>(v: &Option<bool>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match v {
Some(true) => Serializer::serialize_str(serializer, "seq"),
Some(false) => Serializer::serialize_str(serializer, ""),
None => unimplemented!("serializer should skip if none"),
}
}
#[cfg(test)]
mod tests {
use super::Image;
use crate::schema::{
assets::{asset::Asset, file_asset::FileAsset},
helpers::{
int_boolean::BoolInt, slottable_object::SlottableObject, visual_object::VisualObject,
},
};
use serde_json::json;
use std::sync::LazyLock;
static JSON: LazyLock<serde_json::Value> = LazyLock::new(|| {
json!(
{
"id": "my image",
"h": 512,
"w": 512,
"e": 1,
"p": "data:image/png;base64,..."
}
)
});
static IMAGE: LazyLock<Image> = LazyLock::new(|| Image {
slottable_object: SlottableObject::default(),
file_asset: FileAsset {
asset: Asset {
id: "my image".to_string(),
visual_object: VisualObject {
name: None,
match_name: None,
},
},
dir: None,
file_name: "data:image/png;base64,...".to_string(),
embedded: Some(BoolInt::True),
},
height: Some(512.0),
width: Some(512.0),
sequence: None,
});
#[test]
fn test_deserialize() {
let actual = serde_json::from_value(JSON.to_owned());
match actual {
Ok(actual) => assert_eq!(*IMAGE, actual),
Err(e) => panic!("{e}"),
}
}
#[test]
fn test_can_serialize() {
serde_json::to_value(&*IMAGE).unwrap();
}
}