1use std::fmt::Display;
4
5use serde::Deserialize;
6use time::OffsetDateTime;
7
8use crate::HackerNewsID;
9
10const ITEM_TYPE_COMMENT: &str = "comment";
11const ITEM_TYPE_JOB: &str = "job";
12const ITEM_TYPE_POLL: &str = "poll";
13const ITEM_TYPE_POLLOPT: &str = "pollopt";
14const ITEM_TYPE_STORY: &str = "story";
15
16#[derive(Debug, Eq, PartialEq, Clone, Copy)]
18pub enum HackerNewsItemType {
19 Comment,
21 Job,
23 Poll,
25 PollOpt,
27 Story,
29 Unknown,
31}
32
33impl Display for HackerNewsItemType {
34 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35 write!(f, "{:?}", self)
36 }
37}
38
39#[derive(Debug, Deserialize)]
41pub struct HackerNewsItem {
42 pub id: HackerNewsID,
44 pub deleted: Option<bool>,
46 #[serde(rename = "type")]
48 pub response_type: Option<String>,
49 pub by: Option<String>,
51 #[serde(with = "time::serde::timestamp", rename = "time")]
53 pub created_at: OffsetDateTime,
54 pub dead: Option<bool>,
56 pub parent: Option<HackerNewsID>,
58 pub poll: Option<HackerNewsID>,
60 pub kids: Option<Vec<HackerNewsID>>,
62 pub url: Option<String>,
64 pub score: Option<u32>,
66 pub title: Option<String>,
68 pub text: Option<String>,
70 pub parts: Option<Vec<HackerNewsID>>,
72 pub descendants: Option<u32>,
74}
75
76impl HackerNewsItem {
77 fn parse_item_type(&self, item_type: &str) -> HackerNewsItemType {
78 match item_type {
79 ITEM_TYPE_COMMENT => HackerNewsItemType::Comment,
80 ITEM_TYPE_JOB => HackerNewsItemType::Job,
81 ITEM_TYPE_POLL => HackerNewsItemType::Poll,
82 ITEM_TYPE_POLLOPT => HackerNewsItemType::PollOpt,
83 ITEM_TYPE_STORY => HackerNewsItemType::Story,
84 _ => HackerNewsItemType::Unknown,
85 }
86 }
87
88 fn is_item_type(&self, item_type: HackerNewsItemType) -> bool {
89 self.get_item_type() == item_type
90 }
91
92 pub fn get_item_type(&self) -> HackerNewsItemType {
94 match &self.response_type {
95 Some(item_type) => self.parse_item_type(&item_type.to_lowercase()),
96 None => HackerNewsItemType::Unknown,
97 }
98 }
99
100 pub fn is_comment(&self) -> bool {
102 self.is_item_type(HackerNewsItemType::Comment)
103 }
104
105 pub fn is_job(&self) -> bool {
107 self.is_item_type(HackerNewsItemType::Job)
108 }
109
110 pub fn is_poll(&self) -> bool {
112 self.is_item_type(HackerNewsItemType::Poll)
113 }
114
115 pub fn is_pollopt(&self) -> bool {
117 self.is_item_type(HackerNewsItemType::PollOpt)
118 }
119
120 pub fn is_story(&self) -> bool {
122 self.is_item_type(HackerNewsItemType::Story)
123 }
124}