diff --git a/src/fanbox/article/body.rs b/src/fanbox/article/body.rs index b2ae462..ab8ffd8 100644 --- a/src/fanbox/article/body.rs +++ b/src/fanbox/article/body.rs @@ -1,6 +1,7 @@ use super::super::check::CheckUnknown; use super::super::error::FanboxAPIError; use super::block::FanboxArticleBlock; +use super::image::FanboxArticleImageMap; use crate::fanbox_api::FanboxClientInternal; use json::JsonValue; use proc_macros::check_json_keys; @@ -29,6 +30,16 @@ impl FanboxArticleBody { } } + #[inline] + pub fn image_map(&self) -> Option { + let map = &self.data["imageMap"]; + if map.is_object() { + Some(FanboxArticleImageMap::new(map, Arc::clone(&self.client))) + } else { + None + } + } + #[inline] /// Create a new instance pub fn new(data: &JsonValue, client: Arc) -> Self { @@ -43,7 +54,7 @@ impl CheckUnknown for FanboxArticleBody { fn check_unknown(&self) -> Result<(), FanboxAPIError> { check_json_keys!( "blocks"+, - "imageMap": [], + "imageMap"+, "fileMap": [], "embedMap": [], "urlEmbedMap": [], @@ -56,6 +67,12 @@ impl CheckUnknown for FanboxArticleBody { } None => {} } + match self.image_map() { + Some(map) => { + map.check_unknown()?; + } + None => {} + } Ok(()) } } @@ -64,6 +81,7 @@ impl Debug for FanboxArticleBody { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("FanboxArticleBody") .field("blocks", &self.blocks()) + .field("image_map", &self.image_map()) .finish_non_exhaustive() } } diff --git a/src/fanbox/article/image.rs b/src/fanbox/article/image.rs new file mode 100644 index 0000000..9a06fcf --- /dev/null +++ b/src/fanbox/article/image.rs @@ -0,0 +1,130 @@ +use super::super::check::CheckUnknown; +use super::super::error::FanboxAPIError; +use crate::fanbox_api::FanboxClientInternal; +use json::JsonValue; +use proc_macros::check_json_keys; +use std::fmt::Debug; +use std::sync::Arc; + +pub struct FanboxArticleImage { + pub data: JsonValue, + client: Arc, +} + +impl FanboxArticleImage { + #[inline] + pub fn extension(&self) -> Option<&str> { + self.data["extension"].as_str() + } + + #[inline] + pub fn height(&self) -> Option<&str> { + self.data["height"].as_str() + } + + #[inline] + pub fn id(&self) -> Option<&str> { + self.data["id"].as_str() + } + + #[inline] + /// Create a new instance + pub fn new(data: &JsonValue, client: Arc) -> Self { + Self { + data: data.clone(), + client, + } + } + + #[inline] + pub fn original_url(&self) -> Option<&str> { + self.data["originalUrl"].as_str() + } + + #[inline] + pub fn thumbnail_url(&self) -> Option<&str> { + self.data["thumbnailUrl"].as_str() + } + + #[inline] + pub fn width(&self) -> Option { + self.data["width"].as_u64() + } +} + +impl CheckUnknown for FanboxArticleImage { + fn check_unknown(&self) -> Result<(), FanboxAPIError> { + check_json_keys!( + "extension"+, + "id"+, + "width"+, + "height"+, + "originalUrl"+, + "thumbnailUrl", + ); + Ok(()) + } +} + +impl Debug for FanboxArticleImage { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("FanboxArticleImage") + .field("id", &self.id()) + .field("extension", &self.extension()) + .field("height", &self.height()) + .field("original_url", &self.original_url()) + .field("thumbnail_url", &self.thumbnail_url()) + .field("width", &self.width()) + .finish_non_exhaustive() + } +} + +pub struct FanboxArticleImageMap { + pub data: JsonValue, + client: Arc, +} + +impl FanboxArticleImageMap { + #[inline] + /// Create a new instance + pub fn new(data: &JsonValue, client: Arc) -> Self { + Self { + data: data.clone(), + client, + } + } + + pub fn get_image + ?Sized>(&self, id: &S) -> Option { + let id = id.as_ref(); + let image = &self.data[id]; + if image.is_object() { + Some(FanboxArticleImage::new(image, Arc::clone(&self.client))) + } else { + None + } + } +} + +impl CheckUnknown for FanboxArticleImageMap { + fn check_unknown(&self) -> Result<(), FanboxAPIError> { + for (key, _) in self.data.entries() { + match self.get_image(key) { + Some(i) => { + i.check_unknown()?; + } + None => {} + } + } + Ok(()) + } +} + +impl Debug for FanboxArticleImageMap { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut s = f.debug_struct("FanboxArticleImageMap"); + for (key, _) in self.data.entries() { + s.field(key, &self.get_image(key)); + } + s.finish_non_exhaustive() + } +} diff --git a/src/fanbox/article/mod.rs b/src/fanbox/article/mod.rs index 17590e6..9f86765 100644 --- a/src/fanbox/article/mod.rs +++ b/src/fanbox/article/mod.rs @@ -1,2 +1,3 @@ pub mod block; pub mod body; +pub mod image;