mangadex_api_schema_rust/v5/statistics/
manga.rs

1//! Manga statistics from a response body.
2
3use std::collections::HashMap;
4
5use mangadex_api_types::ResultType;
6use serde::Deserialize;
7use uuid::Uuid;
8
9use crate::FromResponse;
10
11use super::Comments;
12
13#[derive(Clone, Debug, Deserialize)]
14#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
15#[serde(rename_all = "camelCase")]
16#[cfg_attr(feature = "non_exhaustive", non_exhaustive)]
17#[cfg_attr(feature = "specta", derive(specta::Type))]
18pub struct MangaStatisticsObject {
19    #[serde(default)]
20    pub result: ResultType,
21    /// JSON object of `MangaId-StatisticsObject`.
22    pub statistics: HashMap<Uuid, MangaStatistics>,
23}
24
25#[derive(Clone, Debug, Deserialize, Copy)]
26#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
27#[cfg_attr(feature = "specta", derive(specta::Type))]
28pub struct MangaStatistics {
29    pub rating: MangaRating,
30    /// Number of users following the Manga.
31    // The API documentation has placed this within the `rating` object as of MangaDex API 5.4.9 but
32    // the actual response has this field at this level.
33    pub follows: u32,
34    pub comments: Option<Comments>,
35}
36
37#[derive(Clone, Debug, Deserialize, Copy)]
38#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
39#[cfg_attr(feature = "specta", derive(specta::Type))]
40pub struct MangaRating {
41    /// Average rating of distributed votes.
42    ///
43    /// Ratings values with no votes are not included in the calculation.
44    ///
45    /// Will be `None` if no ratings calculations have been done.
46    #[serde(default)]
47    pub average: Option<f32>,
48    #[serde(default)]
49    pub bayesian: Option<f32>,
50    /// Ordered distribution of ratings from 1 to 10.
51    ///
52    /// Array indices correspond to the rating value.
53    ///
54    /// Each element corresponds to the number of users that have given that rating.
55    #[serde(default)]
56    #[cfg_attr(feature = "specta", specta(type = HashMap<String, u32>))]
57    pub distribution: RatingsDistribution,
58}
59
60/// Distribution of ratings from 1 to 10.
61///
62/// Because Rust identifies may not begin with a number, the fields are prefixed with an arbitrary
63/// "r" to denote "rating".
64#[derive(Clone, Debug, Deserialize, Default, Copy)]
65#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
66pub struct RatingsDistribution {
67    #[serde(rename = "1")]
68    pub r1: u32,
69    #[serde(rename = "2")]
70    pub r2: u32,
71    #[serde(rename = "3")]
72    pub r3: u32,
73    #[serde(rename = "4")]
74    pub r4: u32,
75    #[serde(rename = "5")]
76    pub r5: u32,
77    #[serde(rename = "6")]
78    pub r6: u32,
79    #[serde(rename = "7")]
80    pub r7: u32,
81    #[serde(rename = "8")]
82    pub r8: u32,
83    #[serde(rename = "9")]
84    pub r9: u32,
85    #[serde(rename = "10")]
86    pub r10: u32,
87}
88
89impl FromResponse for MangaStatisticsObject {
90    type Response = Self;
91
92    fn from_response(value: Self::Response) -> Self {
93        value
94    }
95}