boosty_rs/request.rs
1extern crate reqwest;
2
3use crate::types::Post;
4use reqwest::Response;
5use serde_json::Value;
6
7use crate::auth::Auth;
8
9/// Boosty API URL
10pub const API_URL: &str = "https://api.boosty.to";
11
12/// Sends a request to Boosty API, returns reqwest Response wrapped in Result
13///
14/// # Arguments
15///
16/// * `method` - A string that holds API method, for example blog/blog_name/post
17///
18/// # Examples
19///
20/// ```ignore
21/// let body = request("blog/boosty/post").await?;
22/// let text = body.text().await?;
23/// println!("{:?}", text);
24/// ```
25async fn request(method: String, auth: Option<Auth>) -> Result<Response, reqwest::Error> {
26 let url = format!("{}/v1/{}", API_URL, method); // Will result in something like
27 // https://api.boosty.to/v1/blog/boosty/post/
28 // Trailing slash is required only for
29 // fetching all posts, otherwise 404
30 // will be returned.
31 let client = reqwest::Client::new();
32 if auth.is_some() {
33 Ok(
34 client
35 .get(url)
36 .headers(auth.unwrap().headers)
37 .send()
38 .await?)
39 } else {
40 Ok(
41 client
42 .get(url)
43 .send()
44 .await?)
45 }
46}
47
48/// Fetches all posts from blog, retuns a vector of Post wrapped in Result
49///
50/// # Arguments
51///
52/// * `blog_name` - Name of a blog to get posts
53/// * `limit` - Count of posts to return (Boosty default when no provided in request is 100)
54/// * `auth` - Optional argument for authorization in API
55///
56/// # Examples
57/// ```
58/// #[tokio::main]
59/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
60/// let posts = boosty_rs::request::fetch_posts("crptmem".to_string(), 300, None).await?;
61/// println!("{:?}", posts);
62/// Ok(())
63/// }
64/// ```
65pub async fn fetch_posts(blog_name: String, limit: i64, auth: Option<Auth>) -> Result<Vec<Post>, serde_json::Error> {
66 let url = format!("blog/{}/post/?limit={}", blog_name, limit);
67 let json: Value = request(url.clone(), auth).await.unwrap().json().await.unwrap();
68 let posts: Result<Vec<Post>, serde_json::Error> = serde_json::from_value(json["data"].clone());
69 posts
70}
71
72/// Fetches all posts from blog but do not parse, returns a serde Value
73///
74/// # Arguments
75///
76/// * `blog_name` - Name of a blog to get posts
77/// * `limit` - Count of posts to return (Boosty default when no provided in request is 100)
78/// * `auth` - Optional argument for authorization in API
79///
80/// # Examples
81/// ```
82/// #[tokio::main]
83/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
84/// let posts = boosty_rs::request::fetch_posts_raw("crptmem".to_string(), 300, None).await?;
85/// println!("{:?}", posts);
86/// Ok(())
87/// }
88/// ```
89pub async fn fetch_posts_raw(blog_name: String, limit: i64, auth: Option<Auth>) -> Result<Value, serde_json::Error> {
90 let url = format!("blog/{}/post/?limit={}", blog_name, limit);
91 let json: Value = request(url.clone(), auth).await.unwrap().json().await.unwrap();
92 Ok(json)
93}
94
95/// Fetch a certain post from blog, retuns Post wrapped in Result
96///
97/// # Arguments
98///
99/// * `blog_name` - Name of a blog to get posts
100/// * `post_id` - ID of a post in blog
101///
102/// # Examples
103/// ```
104/// #[tokio::main]
105/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
106/// let post = boosty_rs::request::fetch_post("boosty".to_string(), "c9fb8a19-c45e-4602-9942-087c3af28c1b".to_string(), None).await?;
107/// println!("{:?}", post);
108/// Ok(())
109/// }
110/// ```
111pub async fn fetch_post(blog_name: String, post_id: String, auth: Option<Auth>) -> Result<Post, serde_json::Error> {
112 let url = format!("blog/{}/post/{}", blog_name, post_id);
113 let post: Post = request(url, auth).await.unwrap().json().await.unwrap();
114 Ok(post)
115}