hacker_rs/
stories.rs

1//! Stories listed on the Hacker News homepage and all associated data.
2
3use time::OffsetDateTime;
4
5use crate::{
6    errors::HackerNewsClientError,
7    items::{HackerNewsItem, HackerNewsItemType},
8    HackerNewsID,
9};
10
11/// Represents a Hacker News story and all associated data to it including author, text, and child comments.
12#[derive(Debug)]
13pub struct HackerNewsStory {
14    /// The item's unique id.
15    pub id: HackerNewsID,
16    /// The total comment count.
17    pub number_of_comments: u32,
18    /// A list of associated child comment IDs.
19    pub comments: Vec<HackerNewsID>,
20    /// The story's total number of upvotes.
21    pub score: u32,
22    /// Creation date of the story.
23    pub created_at: OffsetDateTime,
24    /// Title of the story.
25    pub title: String,
26    /// URL of the story.
27    pub url: String,
28    /// Username of the story poster.
29    pub by: String,
30}
31
32impl TryFrom<HackerNewsItem> for HackerNewsStory {
33    type Error = HackerNewsClientError;
34
35    fn try_from(item: HackerNewsItem) -> Result<Self, Self::Error> {
36        if item.get_item_type() != HackerNewsItemType::Story {
37            return Err(HackerNewsClientError::InvalidTypeMapping(
38                item.get_item_type(),
39            ));
40        }
41
42        Ok(Self {
43            id: item.id,
44            number_of_comments: item.descendants.unwrap_or(0),
45            comments: item.kids.unwrap_or_default(),
46            score: item.score.unwrap_or(0),
47            created_at: item.created_at,
48            title: item.title.unwrap_or_default(),
49            url: item.url.unwrap_or_default(),
50            by: item.by.unwrap_or_default(),
51        })
52    }
53}