Optimize Rust code with Clippy

This commit is contained in:
spikecodes 2021-01-01 12:33:57 -08:00
parent 64a92195dd
commit d43b49e7e4
7 changed files with 71 additions and 73 deletions

View File

@ -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
} }

View File

@ -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"),
), ),
}); });
} }

View File

@ -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(""))
} }

View File

@ -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();

View File

@ -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)),

View File

@ -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"),
}) })
} }

View File

@ -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)