use crate::serde_helpers::double_option;
#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct HubCalloutBoxTextBlock {
pub id: String,
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "double_option"
)]
pub parent_id: Option<Option<String>>,
pub r#type: HubCalloutBoxTextBlockType,
pub fragment: String,
}
#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct HubDividerBlock {
pub id: String,
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "double_option"
)]
pub parent_id: Option<Option<String>>,
pub r#type: HubDividerBlockType,
}
#[derive(Clone, Debug, PartialEq)]
pub enum HubDocumentBlockEntry {
Paragraph(HubParagraphTextBlock),
SectionTitle(HubSectionTitleTextBlock),
CalloutBox(HubCalloutBoxTextBlock),
ItemList(HubItemListBlock),
Divider(HubDividerBlock),
Unknown(serde_json::Value),
}
impl Default for HubDocumentBlockEntry {
fn default() -> Self {
Self::Unknown(Default::default())
}
}
impl serde::Serialize for HubDocumentBlockEntry {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
match self {
Self::Paragraph(inner) => inner.serialize(serializer),
Self::SectionTitle(inner) => inner.serialize(serializer),
Self::CalloutBox(inner) => inner.serialize(serializer),
Self::ItemList(inner) => inner.serialize(serializer),
Self::Divider(inner) => inner.serialize(serializer),
Self::Unknown(inner) => inner.serialize(serializer),
}
}
}
impl<'de> serde::Deserialize<'de> for HubDocumentBlockEntry {
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let value = serde_json::Value::deserialize(deserializer)?;
let tag = value
.get("type")
.and_then(serde_json::Value::as_str)
.map(str::to_owned);
match tag.as_deref() {
Some("paragraph") => Ok(Self::Paragraph(
serde_json::from_value(value).map_err(serde::de::Error::custom)?,
)),
Some("section_title") => Ok(Self::SectionTitle(
serde_json::from_value(value).map_err(serde::de::Error::custom)?,
)),
Some("callout_box") => Ok(Self::CalloutBox(
serde_json::from_value(value).map_err(serde::de::Error::custom)?,
)),
Some("item_list") => Ok(Self::ItemList(
serde_json::from_value(value).map_err(serde::de::Error::custom)?,
)),
Some("divider") => Ok(Self::Divider(
serde_json::from_value(value).map_err(serde::de::Error::custom)?,
)),
_ => Ok(Self::Unknown(value)),
}
}
}
#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct HubDocumentBlocks {
pub entries: Vec<HubDocumentBlockEntry>,
pub r#type: HubDocumentBlocksType,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub limit: Option<i64>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "double_option"
)]
pub next_marker: Option<Option<String>>,
}
#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct HubDocumentPage {
pub id: String,
pub r#type: String,
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "double_option"
)]
pub parent_id: Option<Option<String>>,
pub title_fragment: String,
}
#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct HubDocumentPages {
pub entries: Vec<HubDocumentPage>,
pub r#type: HubDocumentPagesType,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub limit: Option<i64>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "double_option"
)]
pub next_marker: Option<Option<String>>,
}
#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct HubItemListBlock {
pub id: String,
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "double_option"
)]
pub parent_id: Option<Option<String>>,
pub r#type: HubItemListBlockType,
}
#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct HubParagraphTextBlock {
pub id: String,
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "double_option"
)]
pub parent_id: Option<Option<String>>,
pub r#type: HubParagraphTextBlockType,
pub fragment: String,
}
#[derive(Clone, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct HubSectionTitleTextBlock {
pub id: String,
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "double_option"
)]
pub parent_id: Option<Option<String>>,
pub r#type: HubSectionTitleTextBlockType,
pub fragment: String,
}
#[derive(Clone, Debug, Default, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
#[serde(transparent)]
pub struct HubCalloutBoxTextBlockType(pub String);
impl HubCalloutBoxTextBlockType {
pub const CALLOUT_BOX: &'static str = "callout_box";
}
#[derive(Clone, Debug, Default, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
#[serde(transparent)]
pub struct HubDividerBlockType(pub String);
impl HubDividerBlockType {
pub const DIVIDER: &'static str = "divider";
}
#[derive(Clone, Debug, Default, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
#[serde(transparent)]
pub struct HubDocumentBlocksType(pub String);
impl HubDocumentBlocksType {
pub const DOCUMENT_BLOCKS: &'static str = "document_blocks";
}
#[derive(Clone, Debug, Default, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
#[serde(transparent)]
pub struct HubDocumentPagesType(pub String);
impl HubDocumentPagesType {
pub const DOCUMENT_PAGES: &'static str = "document_pages";
}
#[derive(Clone, Debug, Default, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
#[serde(transparent)]
pub struct HubItemListBlockType(pub String);
impl HubItemListBlockType {
pub const ITEM_LIST: &'static str = "item_list";
}
#[derive(Clone, Debug, Default, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
#[serde(transparent)]
pub struct HubParagraphTextBlockType(pub String);
impl HubParagraphTextBlockType {
pub const PARAGRAPH: &'static str = "paragraph";
}
#[derive(Clone, Debug, Default, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
#[serde(transparent)]
pub struct HubSectionTitleTextBlockType(pub String);
impl HubSectionTitleTextBlockType {
pub const SECTION_TITLE: &'static str = "section_title";
}