1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
use chrono::{DateTime, Utc};

/// Structured data, deserialized from an API response.
#[derive(Clone, Debug, Default, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub struct Article {
    /// The name of the author.
    pub author: Option<String>,
    /// The main body content.
    #[serde(default)]
    pub content: String,
    /// The publication date.
    pub date_published: Option<DateTime<Utc>>,
    /// The dek.
    pub dek: Option<String>,
    /// The text direction of `content`.
    pub direction: TextDirection,
    /// A short description.
    #[serde(default)]
    pub excerpt: String,
    /// The url of the lead image.
    pub lead_image_url: Option<String>,
    /// The url of the next page.
    pub next_page_url: Option<String>,
    /// The number of pages included in `content`.
    #[serde(default = "default_page_field_value")]
    pub rendered_pages: u64,
    /// The title of the article.
    #[serde(default)]
    pub title: String,
    /// The total number of pages.
    #[serde(default = "default_page_field_value")]
    pub total_pages: u64,
    /// The original url.
    pub url: String,
    /// The total number of words.
    #[serde(default)]
    pub word_count: u64,
    /// Private field for backwards compatibility.
    #[serde(default, skip)]
    _ext: (),
}

/// Represents the text direction of parsed body content.
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum TextDirection {
    /// Left to right.
    Ltr,
    /// Right to left.
    Rtl,
}

impl TextDirection {
    /// Returns `true` if the direction is a [`Ltr`] value.
    ///
    /// # Example
    ///
    /// ```
    /// # extern crate mercury;
    /// #
    /// # use mercury::TextDirection;
    /// #
    /// # fn main() {
    /// let dir = TextDirection::Ltr;
    /// assert_eq!(dir.is_ltr(), true);
    ///
    /// let dir = TextDirection::Rtl;
    /// assert_eq!(dir.is_ltr(), false);
    /// # }
    /// ```
    ///
    /// [`Ltr`]: #variant.Ltr
    pub fn is_ltr(&self) -> bool {
        *self == TextDirection::Ltr
    }

    /// Returns `true` if the direction is a [`Rtl`] value.
    ///
    /// # Example
    ///
    /// ```
    /// # extern crate mercury;
    /// #
    /// # use mercury::TextDirection;
    /// #
    /// # fn main() {
    /// let dir = TextDirection::Ltr;
    /// assert_eq!(dir.is_rtl(), false);
    ///
    /// let dir = TextDirection::Rtl;
    /// assert_eq!(dir.is_rtl(), true);
    /// # }
    /// ```
    ///
    /// [`Rtl`]: #variant.Rtl
    pub fn is_rtl(&self) -> bool {
        *self == TextDirection::Rtl
    }
}

impl Default for TextDirection {
    fn default() -> TextDirection {
        TextDirection::Ltr
    }
}

/// Returns the default value for `rendered_pages` and `total_pages` if either
/// field is blank during deserialization.
fn default_page_field_value() -> u64 {
    1
}