Initial commit with barely working stuff

This commit is contained in:
Uttarayan Mondal
2021-03-15 01:22:48 +05:30
commit 80d1bfa591
6 changed files with 180 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
/target
Cargo.lock
rust.json
+14
View File
@@ -0,0 +1,14 @@
[package]
name = "rapr"
version = "0.1.0"
authors = ["Uttarayan Mondal <uttarayan21@gmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
reqwest = "0.11.*"
chrono = "0.4.*"
json = "0.12.*"
tokio = { version = "1.3.*", features = ["full"] }
+7
View File
@@ -0,0 +1,7 @@
# rapr-rs
Reddit api wrapper in rust.
Not usable currently.
Currently doing this to learn rust.
View File
+17
View File
@@ -0,0 +1,17 @@
mod rapr;
pub use crate::rapr::RaprClient;
#[cfg(test)]
mod tests {
#[tokio::test]
async fn subreddit() {
use crate::rapr::RaprClient;
let client = RaprClient::new();
let mut sub = RaprClient::subreddit("rust");
client.fetch(10, &mut sub).await.unwrap();
println!("{:#?}", sub.posts.len());
client.fetch(5, &mut sub).await.unwrap();
println!("{:#?}", sub.posts.len());
println!("{:#?}", sub.pinned_posts());
}
}
+139
View File
@@ -0,0 +1,139 @@
extern crate json;
extern crate reqwest;
extern crate tokio;
use chrono::{DateTime, Local};
use std::fmt;
#[derive(Debug)]
pub enum Error {
JsonParseError,
HttpGetError,
}
#[derive(Clone)]
pub struct RaPost {
id: String,
datetime: DateTime<Local>,
title: String,
text: Option<String>,
json: json::JsonValue,
pinned: bool,
}
impl fmt::Debug for RaPost {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RaPost")
.field("id", &self.id)
.field("datetime", &self.datetime)
.field("title", &self.title)
.field("text", &self.text)
.finish()
}
}
impl RaPost {
pub fn new(id: &str, title: &str, json: &json::JsonValue, pinned: bool) -> Self {
Self {
id: id.to_string(),
title: title.to_string(),
datetime: Local::now(), // Temp
text: Some(String::from("")),
json: json.clone(),
pinned,
}
}
pub fn parse(post: &json::JsonValue) -> Result<RaPost, json::Error> {
Ok(RaPost::new(
json::stringify(post["name"].clone()).as_str(),
json::stringify(post["title"].clone()).as_str(),
post,
post["pinned"].as_bool().unwrap(),
))
}
}
#[derive(Debug)]
pub struct RaSub {
pub name: String,
pub posts: Vec<RaPost>,
after: Option<String>,
}
impl RaSub {
pub fn pinned_posts(&self) -> Option<Vec<RaPost>> {
let mut pinned_posts: Vec<RaPost> = Vec::new();
for post in &self.posts {
if post.pinned {
pinned_posts.push(post.clone());
}
}
if pinned_posts.is_empty() {
return None;
} else {
return Some(pinned_posts);
}
}
}
#[derive(Debug)]
pub struct RaprClient {
oauth: Option<String>,
rwclient: reqwest::Client,
}
impl RaprClient {
pub fn new() -> Self {
Self {
oauth: None,
rwclient: reqwest::Client::new(),
}
}
pub fn subreddit(name: &str) -> RaSub {
RaSub {
name: String::from(name),
posts: Vec::new(),
after: None,
}
}
pub async fn fetch(&self, count: u32, sub: &mut RaSub) -> Result<Vec<RaPost>, Error> {
let url = match self.oauth {
None => format!("https://reddit.com/r/{}.json", sub.name),
Some(_) => format!("https://oauth.reddit.com/r/{}.json", sub.name),
};
let res = match &sub.after {
None => self
.rwclient
.get(url)
.query(&[("limit", count)])
.send()
.await
.unwrap(),
Some(after) => self
.rwclient
.get(url)
.query(&[("limit", count.to_string()), ("after", after.to_string())])
.send()
.await
.unwrap(),
};
let mut parsed = json::parse(res.text().await.unwrap().as_str()).unwrap();
let raw_posts: Vec<json::JsonValue> = match parsed["data"]["children"].take() {
json::JsonValue::Array(arr) => arr,
_ => return Err(Error::JsonParseError),
};
let mut parsed_posts: Vec<RaPost> = Vec::new();
for post in raw_posts {
parsed_posts.push(RaPost::parse(&post["data"]).unwrap());
}
if parsed["data"]["after"].is_string() {
sub.after = Some(parsed["data"]["after"].to_string());
}
sub.posts.append(&mut parsed_posts);
Ok(parsed_posts)
}
}