hn_api/
lib.rs

1//! A simple synchronous Hacker News API (v0) client library based on reqwest
2//! and serde.
3//!
4//! The library currently implements no caching. It simply exposes endpoints as
5//! methods.
6//!
7//! Furthermore, there is no realtime functionality. If you need that, you
8//! should probably use a firebase client crate and subscribe to the live
9//! endpoints directly.
10//!
11//! API Docs: <https://github.com/HackerNews/API>
12//!
13//! ## Usage
14//!
15//! ```rust
16//! use hn_api::HnClient;
17//!
18//! // Initialize HTTP client
19//! let api = HnClient::init()
20//!     .expect("Could not initialize HN client");
21//!
22//! // Fetch latest item
23//! let latest_item_id = api.get_max_item_id()
24//!     .expect("Could not fetch latest item id");
25//! let item = api.get_item(latest_item_id)
26//!     .expect("Could not fetch item");
27//!
28//! println!("Latest item: {:?}", item);
29//! ```
30//!
31//! For an example, see `examples/top.rs`.
32
33#![deny(missing_docs)]
34
35use std::time::Duration;
36
37use reqwest::{self, Client};
38
39pub mod types;
40
41static API_BASE_URL: &str = "https://hacker-news.firebaseio.com/v0";
42
43/// The API client.
44pub struct HnClient {
45    client: Client,
46}
47
48impl HnClient {
49
50    /// Create a new `HnClient` instance.
51    pub fn init() -> reqwest::Result<Self> {
52        let client = reqwest::Client::builder()
53            .timeout(Duration::from_secs(10))
54            .build()?;
55        Ok(Self { client })
56    }
57
58    /// Return the item with the specified id.
59    ///
60    /// May return `None` if item id is invalid.
61    pub fn get_item(&self, id: u32) -> reqwest::Result<Option<types::Item>> {
62        self.client.get(&format!("{}/item/{}.json", API_BASE_URL, id)).send()?.json()
63    }
64
65    /// Return the user with the specified username.
66    ///
67    /// May return `None` if username is invalid.
68    pub fn get_user(&self, username: &str) -> reqwest::Result<Option<types::User>> {
69        self.client.get(&format!("{}/user/{}.json", API_BASE_URL, username)).send()?.json()
70    }
71
72    /// Return the id of the newest item.
73    ///
74    /// To get the 10 latest items, you can decrement the id 10 times.
75    pub fn get_max_item_id(&self) -> reqwest::Result<u32> {
76        self.client.get(&format!("{}/maxitem.json", API_BASE_URL)).send()?.json()
77    }
78
79    /// Return a list of top story item ids.
80    pub fn get_top_stories(&self) -> reqwest::Result<Vec<u32>> {
81        self.client.get(&format!("{}/topstories.json", API_BASE_URL)).send()?.json()
82    }
83
84    /// Return a list of new story item ids.
85    pub fn get_new_stories(&self) -> reqwest::Result<Vec<u32>> {
86        self.client.get(&format!("{}/newstories.json", API_BASE_URL)).send()?.json()
87    }
88
89    /// Return a list of best story item ids.
90    pub fn get_best_stories(&self) -> reqwest::Result<Vec<u32>> {
91        self.client.get(&format!("{}/beststories.json", API_BASE_URL)).send()?.json()
92    }
93
94    /// Return up to 200 latest Ask HN story item ids.
95    pub fn get_ask_stories(&self) -> reqwest::Result<Vec<u32>> {
96        self.client.get(&format!("{}/askstories.json", API_BASE_URL)).send()?.json()
97    }
98
99    /// Return up to 200 latest Show HN story item ids.
100    pub fn get_show_stories(&self) -> reqwest::Result<Vec<u32>> {
101        self.client.get(&format!("{}/showstories.json", API_BASE_URL)).send()?.json()
102    }
103
104    /// Return up to 200 latest Job story item ids.
105    pub fn get_job_stories(&self) -> reqwest::Result<Vec<u32>> {
106        self.client.get(&format!("{}/jobstories.json", API_BASE_URL)).send()?.json()
107    }
108
109    /// Return a list of items and users that have been updated recently.
110    pub fn get_updates(&self) -> reqwest::Result<types::Updates> {
111        self.client.get(&format!("{}/updates.json", API_BASE_URL)).send()?.json()
112    }
113
114}