use std::fmt::Display;
use serde::Deserialize;
use time::OffsetDateTime;
use crate::HackerNewsID;
const ITEM_TYPE_COMMENT: &str = "comment";
const ITEM_TYPE_JOB: &str = "job";
const ITEM_TYPE_POLL: &str = "poll";
const ITEM_TYPE_POLLOPT: &str = "pollopt";
const ITEM_TYPE_STORY: &str = "story";
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
pub enum HackerNewsItemType {
Comment,
Job,
Poll,
PollOpt,
Story,
Unknown,
}
impl Display for HackerNewsItemType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
#[derive(Debug, Deserialize)]
pub struct HackerNewsItem {
pub id: HackerNewsID,
pub deleted: Option<bool>,
#[serde(rename = "type")]
pub response_type: Option<String>,
pub by: Option<String>,
#[serde(with = "time::serde::timestamp", rename = "time")]
pub created_at: OffsetDateTime,
pub dead: Option<bool>,
pub parent: Option<HackerNewsID>,
pub poll: Option<HackerNewsID>,
pub kids: Option<Vec<HackerNewsID>>,
pub url: Option<String>,
pub score: Option<u32>,
pub title: Option<String>,
pub text: Option<String>,
pub parts: Option<Vec<HackerNewsID>>,
pub descendants: Option<u32>,
}
impl HackerNewsItem {
fn parse_item_type(&self, item_type: &str) -> HackerNewsItemType {
match item_type {
ITEM_TYPE_COMMENT => HackerNewsItemType::Comment,
ITEM_TYPE_JOB => HackerNewsItemType::Job,
ITEM_TYPE_POLL => HackerNewsItemType::Poll,
ITEM_TYPE_POLLOPT => HackerNewsItemType::PollOpt,
ITEM_TYPE_STORY => HackerNewsItemType::Story,
_ => HackerNewsItemType::Unknown,
}
}
fn is_item_type(&self, item_type: HackerNewsItemType) -> bool {
self.get_item_type() == item_type
}
pub fn get_item_type(&self) -> HackerNewsItemType {
match &self.response_type {
Some(item_type) => self.parse_item_type(&item_type.to_lowercase()),
None => HackerNewsItemType::Unknown,
}
}
pub fn is_comment(&self) -> bool {
self.is_item_type(HackerNewsItemType::Comment)
}
pub fn is_job(&self) -> bool {
self.is_item_type(HackerNewsItemType::Job)
}
pub fn is_poll(&self) -> bool {
self.is_item_type(HackerNewsItemType::Poll)
}
pub fn is_pollopt(&self) -> bool {
self.is_item_type(HackerNewsItemType::PollOpt)
}
pub fn is_story(&self) -> bool {
self.is_item_type(HackerNewsItemType::Story)
}
}