pub mod at_home_server;
pub mod auth_tokens;
pub mod author;
pub mod chapter;
pub mod check_token_response;
pub mod check_username_available;
pub mod cover;
pub mod custom_list;
pub mod error;
pub mod is_following_response;
pub mod legacy_id_mapping;
pub mod login_response;
pub mod manga;
pub mod manga_aggregate;
pub mod manga_links;
pub mod manga_read_markers;
pub mod manga_reading_status;
pub mod manga_reading_statuses;
pub mod manga_relation;
pub mod ratings;
pub mod refresh_token_response;
pub mod report;
pub mod scanlation_group;
pub mod statistics;
pub mod tag;
pub mod upload_session;
pub mod upload_session_file;
pub mod user;
pub mod user_report;
pub mod user_settings;
mod exports_types;
pub use self::exports_types::*;
use std::collections::HashMap;
use mangadex_api_types as types;
use serde::Deserialize;
use uuid::Uuid;
use types::{Language, MangaRelation, RelationshipType, ResponseType, ResultType};
pub(crate) use crate::ApiObject;
#[derive(Debug, Deserialize, Clone)]
#[allow(clippy::large_enum_variant)]
#[serde(untagged)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[cfg_attr(feature = "specta", derive(specta::Type))]
pub enum RelatedAttributes {
Manga(MangaAttributes),
Chapter(ChapterAttributes),
CoverArt(CoverAttributes),
Author(AuthorAttributes),
ScanlationGroup(ScanlationGroupAttributes),
Tag(TagAttributes),
User(UserAttributes),
CustomList(CustomListAttributes),
}
#[derive(Debug, Deserialize, Clone)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[cfg_attr(feature = "specta", derive(specta::Type))]
pub struct Relationship {
pub id: Uuid,
#[serde(rename = "type")]
pub type_: RelationshipType,
#[serde(skip_serializing_if = "Option::is_none")]
pub related: Option<MangaRelation>,
#[serde(skip_serializing_if = "Option::is_none")]
pub attributes: Option<RelatedAttributes>,
}
#[derive(Debug, Deserialize, Clone)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[cfg_attr(feature = "specta", derive(specta::Type))]
pub struct Results<T> {
#[serde(default)]
pub result: ResultType,
pub response: ResponseType,
pub data: Vec<T>,
pub limit: u32,
pub offset: u32,
pub total: u32,
}
pub type LocalizedString = HashMap<Language, String>;
pub(crate) mod localizedstring_array_or_map {
use std::collections::HashMap;
use serde::de::{Deserialize, Deserializer, MapAccess, SeqAccess, Visitor};
#[cfg(feature = "serialize")]
use serde::ser::{Serialize, Serializer};
use super::LocalizedString;
pub fn deserialize<'de, D>(deserializer: D) -> Result<LocalizedString, D::Error>
where
D: Deserializer<'de>,
{
struct V;
impl<'de> Visitor<'de> for V {
type Value = LocalizedString;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("array or object")
}
fn visit_seq<A>(self, mut _seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
Ok(HashMap::new())
}
fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let de = serde::de::value::MapAccessDeserializer::new(map);
let helper = LocalizedString::deserialize(de)?;
Ok(helper)
}
}
deserializer.deserialize_any(V)
}
#[cfg(feature = "serialize")]
pub fn serialize<S>(to_use : &LocalizedString ,serializer : S) -> Result<S::Ok, S::Error>
where
S : Serializer
{
to_use.serialize(serializer)
}
}
pub(crate) mod volume_aggregate_array_or_map {
use std::collections::BTreeMap;
#[cfg(feature = "serialize")]
use serde::Serialize;
#[cfg(feature = "serialize")]
use std::collections::HashMap;
use serde::de::{Deserializer, MapAccess, SeqAccess, Visitor};
#[cfg(feature = "serialize")]
use serde::ser::Serializer;
use super::manga_aggregate::VolumeAggregate;
type VolumeAggregateCollection = Vec<VolumeAggregate>;
const PAD_WIDTH: usize = 5;
pub fn deserialize<'de, D>(deserializer: D) -> Result<VolumeAggregateCollection, D::Error>
where
D: Deserializer<'de>,
{
struct V;
impl<'de> Visitor<'de> for V {
type Value = VolumeAggregateCollection;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("array or object")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut volumes = Vec::new();
while let Some(volume) = seq.next_element::<VolumeAggregate>()? {
volumes.push(volume);
}
Ok(volumes)
}
fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
where
M: MapAccess<'de>,
{
let mut sorting_map = BTreeMap::new();
while let Some((volume_number, volume)) =
map.next_entry::<String, VolumeAggregate>()?
{
let volume_number = if volume_number.contains('.') {
match volume_number.parse::<f64>() {
Ok(_) => {
let (i, f) = volume_number.split_once('.').unwrap();
let i = i.parse::<i32>().unwrap();
format!("{i:0PAD_WIDTH$}.{f}")
}
Err(_) => volume_number,
}
} else {
match volume_number.parse::<i32>() {
Ok(n) => format!("{n:0PAD_WIDTH$}"),
Err(_) => volume_number,
}
};
sorting_map.insert(volume_number, volume);
}
Ok(sorting_map.values().cloned().collect())
}
}
deserializer.deserialize_any(V)
}
#[cfg(feature = "serialize")]
#[allow(dead_code)]
pub fn serialize<S>(to_use : &VolumeAggregateCollection, serializer : S) -> Result<S::Ok, S::Error>
where
S : Serializer
{
use super::manga_aggregate::VolumeAggregateSer;
let mut volumes : HashMap<String, VolumeAggregateSer> = HashMap::new();
for volume in to_use{
volumes.insert(volume.volume.clone(), Into::into(volume.clone()));
}
volumes.serialize(serializer)
}
}
pub(crate) mod chapter_aggregate_array_or_map {
use std::collections::BTreeMap;
#[cfg(feature = "serialize")]
use serde::Serialize;
#[cfg(feature = "serialize")]
use serde::ser::Serializer;
use serde::de::{Deserializer, MapAccess, SeqAccess, Visitor};
use super::manga_aggregate::ChapterAggregate;
const PAD_WIDTH: usize = 5;
type ChapterAggregateCollection = Vec<ChapterAggregate>;
pub fn deserialize<'de, D>(deserializer: D) -> Result<ChapterAggregateCollection, D::Error>
where
D: Deserializer<'de>,
{
struct V;
impl<'de> Visitor<'de> for V {
type Value = ChapterAggregateCollection;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("array or object")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut chapters = Vec::new();
while let Some(chapter) = seq.next_element::<ChapterAggregate>()? {
chapters.push(chapter);
}
Ok(chapters)
}
fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
where
M: MapAccess<'de>,
{
let mut sorting_map = BTreeMap::new();
while let Some((chapter_number, chapter)) =
map.next_entry::<String, ChapterAggregate>()?
{
let chapter_number = if chapter_number.contains('.') {
match chapter_number.parse::<f64>() {
Ok(_) => {
let (i, f) = chapter_number.split_once('.').unwrap();
let i = i.parse::<i32>().unwrap();
format!("{i:0PAD_WIDTH$}.{f}")
}
Err(_) => chapter_number,
}
} else {
match chapter_number.parse::<i32>() {
Ok(n) => format!("{n:0PAD_WIDTH$}"),
Err(_) => chapter_number,
}
};
sorting_map.insert(chapter_number, chapter);
}
Ok(sorting_map.values().cloned().collect())
}
}
deserializer.deserialize_any(V)
}
#[cfg(feature = "serialize")]
pub fn serialize<S>(to_use : &ChapterAggregateCollection, serializer : S) -> Result<S::Ok, S::Error>
where
S : Serializer
{
use std::collections::HashMap;
let mut chapters : HashMap<String, ChapterAggregate> = HashMap::new();
for chapter in to_use {
chapters.insert(chapter.chapter.clone(), chapter.clone());
}
chapters.serialize(serializer)
}
}
pub(crate) mod manga_links_array_or_struct {
#[cfg(feature = "serialize")]
use serde::Serialize;
use serde::de::{Deserialize, Deserializer, MapAccess, SeqAccess, Visitor};
#[cfg(feature = "serialize")]
use serde::ser::Serializer;
use crate::v5::MangaLinks;
pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<MangaLinks>, D::Error>
where
D: Deserializer<'de>,
{
struct OptionMangaLinksVisitor;
impl<'de> Visitor<'de> for OptionMangaLinksVisitor {
type Value = Option<MangaLinks>;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("some or none")
}
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(None)
}
fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
let manga_links = d.deserialize_any(MangaLinksVisitor)?;
let manga_links = if manga_links.has_no_links() {
None
} else {
Some(manga_links)
};
Ok(manga_links)
}
fn visit_unit<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(None)
}
}
struct MangaLinksVisitor;
impl<'de> Visitor<'de> for MangaLinksVisitor {
type Value = MangaLinks;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("array or map")
}
fn visit_seq<A>(self, mut _seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
Ok(Self::Value::default())
}
fn visit_map<M>(self, map: M) -> Result<Self::Value, M::Error>
where
M: MapAccess<'de>,
{
Deserialize::deserialize(serde::de::value::MapAccessDeserializer::new(map))
}
}
deserializer.deserialize_option(OptionMangaLinksVisitor)
}
#[cfg(feature = "serialize")]
pub fn serialize<S>(to_use : &Option<MangaLinks>, serializer : S) -> Result<S::Ok, S::Error>
where
S : Serializer
{
match to_use {
None => {
serializer.serialize_none()
},
Some(data) => {
data.serialize(serializer)
}
}
}
}
pub(crate) mod language_array_or_skip_null {
use mangadex_api_types::Language;
#[cfg(feature = "serialize")]
use serde::Serialize;
use serde::de::{Deserializer, SeqAccess, Visitor};
#[cfg(feature = "serialize")]
use serde::ser::Serializer;
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<Language>, D::Error>
where
D: Deserializer<'de>,
{
struct V;
impl<'de> Visitor<'de> for V {
type Value = Vec<Language>;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a sequence of languages")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut languages = Vec::new();
while let Some(language) = seq.next_element::<Option<Language>>()? {
if let Some(language) = language {
languages.push(language);
}
}
Ok(languages)
}
}
deserializer.deserialize_seq(V)
}
#[cfg(feature = "serialize")]
pub fn serialize<S>(to_use: &Vec<Language>, serializer : S) -> Result<S::Ok, S::Error>
where
S : Serializer
{
to_use.serialize(serializer)
}
}