Optimize Rust code with Clippy
This commit is contained in:
parent
64a92195dd
commit
d43b49e7e4
@ -31,7 +31,7 @@ async fn main() -> std::io::Result<()> {
|
|||||||
if args.len() > 1 {
|
if args.len() > 1 {
|
||||||
for arg in args {
|
for arg in args {
|
||||||
if arg.starts_with("--address=") || arg.starts_with("-a=") {
|
if arg.starts_with("--address=") || arg.starts_with("-a=") {
|
||||||
let split: Vec<&str> = arg.split("=").collect();
|
let split: Vec<&str> = arg.split('=').collect();
|
||||||
address = split[1].to_string();
|
address = split[1].to_string();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -48,7 +48,7 @@ async fn main() -> std::io::Result<()> {
|
|||||||
.default_service(web::get().to(utils::error))
|
.default_service(web::get().to(utils::error))
|
||||||
// GENERAL SERVICES
|
// GENERAL SERVICES
|
||||||
.route("/style.css/", web::get().to(style))
|
.route("/style.css/", web::get().to(style))
|
||||||
.route("/favicon.ico/", web::get().to(|| HttpResponse::Ok()))
|
.route("/favicon.ico/", web::get().to(HttpResponse::Ok))
|
||||||
.route("/robots.txt/", web::get().to(robots))
|
.route("/robots.txt/", web::get().to(robots))
|
||||||
// PROXY SERVICE
|
// PROXY SERVICE
|
||||||
.route("/proxy/{url:.*}/", web::get().to(proxy::handler))
|
.route("/proxy/{url:.*}/", web::get().to(proxy::handler))
|
||||||
@ -72,7 +72,7 @@ async fn main() -> std::io::Result<()> {
|
|||||||
.route("/r/{sub}/comments/{id}/{title}/{comment_id}/", web::get().to(post::item))
|
.route("/r/{sub}/comments/{id}/{title}/{comment_id}/", web::get().to(post::item))
|
||||||
})
|
})
|
||||||
.bind(address.clone())
|
.bind(address.clone())
|
||||||
.expect(format!("Cannot bind to the address: {}", address).as_str())
|
.unwrap_or_else(|_| panic!("Cannot bind to the address: {}", address))
|
||||||
.run()
|
.run()
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
42
src/post.rs
42
src/post.rs
@ -18,7 +18,7 @@ struct PostTemplate {
|
|||||||
|
|
||||||
pub async fn item(req: HttpRequest) -> Result<HttpResponse> {
|
pub async fn item(req: HttpRequest) -> Result<HttpResponse> {
|
||||||
let path = format!("{}.json?{}&raw_json=1", req.path(), req.query_string());
|
let path = format!("{}.json?{}&raw_json=1", req.path(), req.query_string());
|
||||||
let sort = param(&path, "sort").await;
|
let sort = param(&path, "sort");
|
||||||
let id = req.match_info().get("id").unwrap_or("").to_string();
|
let id = req.match_info().get("id").unwrap_or("").to_string();
|
||||||
|
|
||||||
// Log the post ID being fetched in debug mode
|
// Log the post ID being fetched in debug mode
|
||||||
@ -80,22 +80,22 @@ async fn parse_post(json: serde_json::Value) -> Result<Post, &'static str> {
|
|||||||
|
|
||||||
// Build a post using data parsed from Reddit post API
|
// Build a post using data parsed from Reddit post API
|
||||||
let post = Post {
|
let post = Post {
|
||||||
title: val(post_data, "title").await,
|
title: val(post_data, "title"),
|
||||||
community: val(post_data, "subreddit").await,
|
community: val(post_data, "subreddit"),
|
||||||
body: val(post_data, "selftext_html").await,
|
body: val(post_data, "selftext_html"),
|
||||||
author: val(post_data, "author").await,
|
author: val(post_data, "author"),
|
||||||
author_flair: Flair(
|
author_flair: Flair(
|
||||||
val(post_data, "author_flair_text").await,
|
val(post_data, "author_flair_text"),
|
||||||
val(post_data, "author_flair_background_color").await,
|
val(post_data, "author_flair_background_color"),
|
||||||
val(post_data, "author_flair_text_color").await,
|
val(post_data, "author_flair_text_color"),
|
||||||
),
|
),
|
||||||
url: val(post_data, "permalink").await,
|
url: val(post_data, "permalink"),
|
||||||
score: format_num(score),
|
score: format_num(score),
|
||||||
post_type: media.0,
|
post_type: media.0,
|
||||||
flair: Flair(
|
flair: Flair(
|
||||||
val(post_data, "link_flair_text").await,
|
val(post_data, "link_flair_text"),
|
||||||
val(post_data, "link_flair_background_color").await,
|
val(post_data, "link_flair_background_color"),
|
||||||
if val(post_data, "link_flair_text_color").await == "dark" {
|
if val(post_data, "link_flair_text_color") == "dark" {
|
||||||
"black".to_string()
|
"black".to_string()
|
||||||
} else {
|
} else {
|
||||||
"white".to_string()
|
"white".to_string()
|
||||||
@ -128,25 +128,25 @@ async fn parse_comments(json: serde_json::Value) -> Result<Vec<Comment>, &'stati
|
|||||||
}
|
}
|
||||||
|
|
||||||
let score = comment["data"]["score"].as_i64().unwrap_or(0);
|
let score = comment["data"]["score"].as_i64().unwrap_or(0);
|
||||||
let body = val(comment, "body_html").await;
|
let body = val(comment, "body_html");
|
||||||
|
|
||||||
let replies: Vec<Comment> = if comment["data"]["replies"].is_object() {
|
let replies: Vec<Comment> = if comment["data"]["replies"].is_object() {
|
||||||
parse_comments(comment["data"]["replies"].clone()).await.unwrap_or(Vec::new())
|
parse_comments(comment["data"]["replies"].clone()).await.unwrap_or_default()
|
||||||
} else {
|
} else {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
comments.push(Comment {
|
comments.push(Comment {
|
||||||
id: val(comment, "id").await,
|
id: val(comment, "id"),
|
||||||
body: body,
|
body,
|
||||||
author: val(comment, "author").await,
|
author: val(comment, "author"),
|
||||||
score: format_num(score),
|
score: format_num(score),
|
||||||
time: Utc.timestamp(unix_time, 0).format("%b %e %Y %H:%M UTC").to_string(),
|
time: Utc.timestamp(unix_time, 0).format("%b %e %Y %H:%M UTC").to_string(),
|
||||||
replies: replies,
|
replies,
|
||||||
flair: Flair(
|
flair: Flair(
|
||||||
val(comment, "author_flair_text").await,
|
val(comment, "author_flair_text"),
|
||||||
val(comment, "author_flair_background_color").await,
|
val(comment, "author_flair_background_color"),
|
||||||
val(comment, "author_flair_text_color").await,
|
val(comment, "author_flair_text_color"),
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ pub async fn handler(web::Path(url): web::Path<String>) -> Result<HttpResponse>
|
|||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
.and_then(|res| Ok(HttpResponse::build(res.status()).streaming(res)))
|
.map(|res| HttpResponse::build(res.status()).streaming(res))
|
||||||
} else {
|
} else {
|
||||||
Ok(HttpResponse::Ok().body(""))
|
Ok(HttpResponse::Ok().body(""))
|
||||||
}
|
}
|
||||||
|
@ -18,11 +18,11 @@ struct SearchTemplate {
|
|||||||
// SERVICES
|
// SERVICES
|
||||||
pub async fn find(req: HttpRequest) -> Result<HttpResponse> {
|
pub async fn find(req: HttpRequest) -> Result<HttpResponse> {
|
||||||
let path = format!("{}.json?{}", req.path(), req.query_string());
|
let path = format!("{}.json?{}", req.path(), req.query_string());
|
||||||
let q = param(&path, "q").await;
|
let q = param(&path, "q");
|
||||||
let sort = if param(&path, "sort").await.is_empty() {
|
let sort = if param(&path, "sort").is_empty() {
|
||||||
"relevance".to_string()
|
"relevance".to_string()
|
||||||
} else {
|
} else {
|
||||||
param(&path, "sort").await
|
param(&path, "sort")
|
||||||
};
|
};
|
||||||
let sub = req.match_info().get("sub").unwrap_or("").to_string();
|
let sub = req.match_info().get("sub").unwrap_or("").to_string();
|
||||||
|
|
||||||
@ -36,9 +36,9 @@ pub async fn find(req: HttpRequest) -> Result<HttpResponse> {
|
|||||||
let s = SearchTemplate {
|
let s = SearchTemplate {
|
||||||
posts: items.0,
|
posts: items.0,
|
||||||
query: q,
|
query: q,
|
||||||
sub: sub,
|
sub,
|
||||||
sort: (sort, param(&path, "t").await),
|
sort: (sort, param(&path, "t")),
|
||||||
ends: (param(&path, "after").await, items.1),
|
ends: (param(&path, "after"), items.1),
|
||||||
}
|
}
|
||||||
.render()
|
.render()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -21,7 +21,7 @@ pub async fn page(req: HttpRequest) -> Result<HttpResponse> {
|
|||||||
let sub = req.match_info().get("sub").unwrap_or("popular").to_string();
|
let sub = req.match_info().get("sub").unwrap_or("popular").to_string();
|
||||||
let sort = req.match_info().get("sort").unwrap_or("hot").to_string();
|
let sort = req.match_info().get("sort").unwrap_or("hot").to_string();
|
||||||
|
|
||||||
let sub_result = if !&sub.contains("+") && sub != "popular" {
|
let sub_result = if !&sub.contains('+') && sub != "popular" {
|
||||||
subreddit(&sub).await
|
subreddit(&sub).await
|
||||||
} else {
|
} else {
|
||||||
Ok(Subreddit::default())
|
Ok(Subreddit::default())
|
||||||
@ -31,14 +31,14 @@ pub async fn page(req: HttpRequest) -> Result<HttpResponse> {
|
|||||||
if posts.is_err() {
|
if posts.is_err() {
|
||||||
error(posts.err().unwrap().to_string()).await
|
error(posts.err().unwrap().to_string()).await
|
||||||
} else {
|
} else {
|
||||||
let sub = sub_result.unwrap_or(Subreddit::default());
|
let sub = sub_result.unwrap_or_default();
|
||||||
let items = posts.unwrap();
|
let items = posts.unwrap();
|
||||||
|
|
||||||
let s = SubredditTemplate {
|
let s = SubredditTemplate {
|
||||||
sub: sub,
|
sub,
|
||||||
posts: items.0,
|
posts: items.0,
|
||||||
sort: (sort, param(&path, "t").await),
|
sort: (sort, param(&path, "t")),
|
||||||
ends: (param(&path, "after").await, items.1),
|
ends: (param(&path, "after"), items.1),
|
||||||
}
|
}
|
||||||
.render()
|
.render()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -47,7 +47,7 @@ pub async fn page(req: HttpRequest) -> Result<HttpResponse> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SUBREDDIT
|
// SUBREDDIT
|
||||||
async fn subreddit(sub: &String) -> Result<Subreddit, &'static str> {
|
async fn subreddit(sub: &str) -> Result<Subreddit, &'static str> {
|
||||||
// Build the Reddit JSON API url
|
// Build the Reddit JSON API url
|
||||||
let url: String = format!("r/{}/about.json?raw_json=1", sub);
|
let url: String = format!("r/{}/about.json?raw_json=1", sub);
|
||||||
|
|
||||||
@ -67,18 +67,14 @@ async fn subreddit(sub: &String) -> Result<Subreddit, &'static str> {
|
|||||||
let active = res["data"]["accounts_active"].as_u64().unwrap_or(0);
|
let active = res["data"]["accounts_active"].as_u64().unwrap_or(0);
|
||||||
|
|
||||||
// Fetch subreddit icon either from the community_icon or icon_img value
|
// Fetch subreddit icon either from the community_icon or icon_img value
|
||||||
let community_icon: &str = res["data"]["community_icon"].as_str().unwrap_or("").split("?").collect::<Vec<&str>>()[0];
|
let community_icon: &str = res["data"]["community_icon"].as_str().unwrap_or("").split('?').collect::<Vec<&str>>()[0];
|
||||||
let icon = if community_icon.is_empty() {
|
let icon = if community_icon.is_empty() { val(&res, "icon_img") } else { community_icon.to_string() };
|
||||||
val(&res, "icon_img").await
|
|
||||||
} else {
|
|
||||||
community_icon.to_string()
|
|
||||||
};
|
|
||||||
|
|
||||||
let sub = Subreddit {
|
let sub = Subreddit {
|
||||||
name: val(&res, "display_name").await,
|
name: val(&res, "display_name"),
|
||||||
title: val(&res, "title").await,
|
title: val(&res, "title"),
|
||||||
description: val(&res, "public_description").await,
|
description: val(&res, "public_description"),
|
||||||
info: val(&res, "description_html").await.replace("\\", ""),
|
info: val(&res, "description_html").replace("\\", ""),
|
||||||
icon: format_url(icon).await,
|
icon: format_url(icon).await,
|
||||||
members: format_num(members.try_into().unwrap_or(0)),
|
members: format_num(members.try_into().unwrap_or(0)),
|
||||||
active: format_num(active.try_into().unwrap_or(0)),
|
active: format_num(active.try_into().unwrap_or(0)),
|
||||||
|
16
src/user.rs
16
src/user.rs
@ -19,7 +19,7 @@ pub async fn profile(req: HttpRequest) -> Result<HttpResponse> {
|
|||||||
let path = format!("{}.json?{}&raw_json=1", req.path(), req.query_string());
|
let path = format!("{}.json?{}&raw_json=1", req.path(), req.query_string());
|
||||||
|
|
||||||
// Retrieve other variables from Libreddit request
|
// Retrieve other variables from Libreddit request
|
||||||
let sort = param(&path, "sort").await;
|
let sort = param(&path, "sort");
|
||||||
let username = req.match_info().get("username").unwrap_or("").to_string();
|
let username = req.match_info().get("username").unwrap_or("").to_string();
|
||||||
|
|
||||||
// Request user profile data and user posts/comments from Reddit
|
// Request user profile data and user posts/comments from Reddit
|
||||||
@ -35,8 +35,8 @@ pub async fn profile(req: HttpRequest) -> Result<HttpResponse> {
|
|||||||
let s = UserTemplate {
|
let s = UserTemplate {
|
||||||
user: user.unwrap(),
|
user: user.unwrap(),
|
||||||
posts: posts_unwrapped.0,
|
posts: posts_unwrapped.0,
|
||||||
sort: (sort, param(&path, "t").await),
|
sort: (sort, param(&path, "t")),
|
||||||
ends: (param(&path, "after").await, posts_unwrapped.1),
|
ends: (param(&path, "after"), posts_unwrapped.1),
|
||||||
}
|
}
|
||||||
.render()
|
.render()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -50,7 +50,7 @@ pub async fn profile(req: HttpRequest) -> Result<HttpResponse> {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// USER
|
// USER
|
||||||
async fn user(name: &String) -> Result<User, &'static str> {
|
async fn user(name: &str) -> Result<User, &'static str> {
|
||||||
// Build the Reddit JSON API path
|
// Build the Reddit JSON API path
|
||||||
let path: String = format!("user/{}/about.json", name);
|
let path: String = format!("user/{}/about.json", name);
|
||||||
|
|
||||||
@ -71,11 +71,11 @@ async fn user(name: &String) -> Result<User, &'static str> {
|
|||||||
// Parse the JSON output into a User struct
|
// Parse the JSON output into a User struct
|
||||||
Ok(User {
|
Ok(User {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
title: nested_val(&res, "subreddit", "title").await,
|
title: nested_val(&res, "subreddit", "title"),
|
||||||
icon: format_url(nested_val(&res, "subreddit", "icon_img").await).await,
|
icon: format_url(nested_val(&res, "subreddit", "icon_img")).await,
|
||||||
karma: res["data"]["total_karma"].as_i64().unwrap(),
|
karma: res["data"]["total_karma"].as_i64().unwrap(),
|
||||||
created: Utc.timestamp(created, 0).format("%b %e, %Y").to_string(),
|
created: Utc.timestamp(created, 0).format("%b %e, %Y").to_string(),
|
||||||
banner: nested_val(&res, "subreddit", "banner_img").await,
|
banner: nested_val(&res, "subreddit", "banner_img"),
|
||||||
description: nested_val(&res, "subreddit", "public_description").await,
|
description: nested_val(&res, "subreddit", "public_description"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
38
src/utils.rs
38
src/utils.rs
@ -94,7 +94,7 @@ pub struct ErrorTemplate {
|
|||||||
//
|
//
|
||||||
|
|
||||||
// Grab a query param from a url
|
// Grab a query param from a url
|
||||||
pub async fn param(path: &String, value: &str) -> String {
|
pub fn param(path: &str, value: &str) -> String {
|
||||||
let url = Url::parse(format!("https://reddit.com/{}", path).as_str()).unwrap();
|
let url = Url::parse(format!("https://reddit.com/{}", path).as_str()).unwrap();
|
||||||
let pairs: std::collections::HashMap<_, _> = url.query_pairs().into_owned().collect();
|
let pairs: std::collections::HashMap<_, _> = url.query_pairs().into_owned().collect();
|
||||||
pairs.get(value).unwrap_or(&String::new()).to_owned()
|
pairs.get(value).unwrap_or(&String::new()).to_owned()
|
||||||
@ -129,12 +129,12 @@ pub fn format_num(num: i64) -> String {
|
|||||||
//
|
//
|
||||||
|
|
||||||
// val() function used to parse JSON from Reddit APIs
|
// val() function used to parse JSON from Reddit APIs
|
||||||
pub async fn val(j: &serde_json::Value, k: &str) -> String {
|
pub fn val(j: &serde_json::Value, k: &str) -> String {
|
||||||
String::from(j["data"][k].as_str().unwrap_or(""))
|
String::from(j["data"][k].as_str().unwrap_or(""))
|
||||||
}
|
}
|
||||||
|
|
||||||
// nested_val() function used to parse JSON from Reddit APIs
|
// nested_val() function used to parse JSON from Reddit APIs
|
||||||
pub async fn nested_val(j: &serde_json::Value, n: &str, k: &str) -> String {
|
pub fn nested_val(j: &serde_json::Value, n: &str, k: &str) -> String {
|
||||||
String::from(j["data"][n][k].as_str().unwrap())
|
String::from(j["data"][n][k].as_str().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,32 +157,32 @@ pub async fn fetch_posts(path: String, fallback_title: String) -> Result<(Vec<Po
|
|||||||
let mut posts: Vec<Post> = Vec::new();
|
let mut posts: Vec<Post> = Vec::new();
|
||||||
|
|
||||||
for post in post_list {
|
for post in post_list {
|
||||||
let img = if val(post, "thumbnail").await.starts_with("https:/") {
|
let img = if val(post, "thumbnail").starts_with("https:/") {
|
||||||
format_url(val(post, "thumbnail").await).await
|
format_url(val(post, "thumbnail")).await
|
||||||
} else {
|
} else {
|
||||||
String::new()
|
String::new()
|
||||||
};
|
};
|
||||||
let unix_time: i64 = post["data"]["created_utc"].as_f64().unwrap().round() as i64;
|
let unix_time: i64 = post["data"]["created_utc"].as_f64().unwrap().round() as i64;
|
||||||
let score = post["data"]["score"].as_i64().unwrap();
|
let score = post["data"]["score"].as_i64().unwrap();
|
||||||
let title = val(post, "title").await;
|
let title = val(post, "title");
|
||||||
|
|
||||||
posts.push(Post {
|
posts.push(Post {
|
||||||
title: if title.is_empty() { fallback_title.to_owned() } else { title },
|
title: if title.is_empty() { fallback_title.to_owned() } else { title },
|
||||||
community: val(post, "subreddit").await,
|
community: val(post, "subreddit"),
|
||||||
body: val(post, "body_html").await,
|
body: val(post, "body_html"),
|
||||||
author: val(post, "author").await,
|
author: val(post, "author"),
|
||||||
author_flair: Flair(
|
author_flair: Flair(
|
||||||
val(post, "author_flair_text").await,
|
val(post, "author_flair_text"),
|
||||||
val(post, "author_flair_background_color").await,
|
val(post, "author_flair_background_color"),
|
||||||
val(post, "author_flair_text_color").await,
|
val(post, "author_flair_text_color"),
|
||||||
),
|
),
|
||||||
score: format_num(score),
|
score: format_num(score),
|
||||||
post_type: "link".to_string(),
|
post_type: "link".to_string(),
|
||||||
media: img,
|
media: img,
|
||||||
flair: Flair(
|
flair: Flair(
|
||||||
val(post, "link_flair_text").await,
|
val(post, "link_flair_text"),
|
||||||
val(post, "link_flair_background_color").await,
|
val(post, "link_flair_background_color"),
|
||||||
if val(post, "link_flair_text_color").await == "dark" {
|
if val(post, "link_flair_text_color") == "dark" {
|
||||||
"black".to_string()
|
"black".to_string()
|
||||||
} else {
|
} else {
|
||||||
"white".to_string()
|
"white".to_string()
|
||||||
@ -192,7 +192,7 @@ pub async fn fetch_posts(path: String, fallback_title: String) -> Result<(Vec<Po
|
|||||||
nsfw: post["data"]["over_18"].as_bool().unwrap_or(false),
|
nsfw: post["data"]["over_18"].as_bool().unwrap_or(false),
|
||||||
stickied: post["data"]["stickied"].as_bool().unwrap_or(false),
|
stickied: post["data"]["stickied"].as_bool().unwrap_or(false),
|
||||||
},
|
},
|
||||||
url: val(post, "permalink").await,
|
url: val(post, "permalink"),
|
||||||
time: Utc.timestamp(unix_time, 0).format("%b %e '%y").to_string(),
|
time: Utc.timestamp(unix_time, 0).format("%b %e '%y").to_string(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -244,10 +244,12 @@ pub async fn request(path: String) -> Result<serde_json::Value, &'static str> {
|
|||||||
let json: Value = from_str(body.as_str()).unwrap_or(Value::Null);
|
let json: Value = from_str(body.as_str()).unwrap_or(Value::Null);
|
||||||
|
|
||||||
if !success {
|
if !success {
|
||||||
println!("! {} - {}", url, "Page not found");
|
#[cfg(debug_assertions)]
|
||||||
|
dbg!(format!("{} - Page not found", url));
|
||||||
Err("Page not found")
|
Err("Page not found")
|
||||||
} else if json == Value::Null {
|
} else if json == Value::Null {
|
||||||
println!("! {} - {}", url, "Failed to parse page JSON data");
|
#[cfg(debug_assertions)]
|
||||||
|
dbg!(format!("{} - Failed to parse page JSON data", url));
|
||||||
Err("Failed to parse page JSON data")
|
Err("Failed to parse page JSON data")
|
||||||
} else {
|
} else {
|
||||||
Ok(json)
|
Ok(json)
|
||||||
|
Loading…
Reference in New Issue
Block a user