wip: add base64 encoding to impl, add custom errors to impl
Some checks failed
Rust / build (push) Failing after 7m58s

This commit is contained in:
Wyatt J. Miller 2024-08-30 08:17:53 -04:00
parent 8e85ceebaf
commit 02c62b7ba6
4 changed files with 92 additions and 112 deletions

View File

@ -2,11 +2,12 @@ use std::collections::HashMap;
use colored::*; use colored::*;
use reqwest::blocking::Client; use reqwest::blocking::Client;
use reqwest::{StatusCode, Response}; use reqwest::{Response, StatusCode};
use serde_derive::{Serialize, Deserialize}; use serde_derive::{Deserialize, Serialize};
use serde_json::Value; use serde_json::Value;
use crate::request::{Request, Authentication, AuthenticationType}; use crate::error;
use crate::request::{AuthenticationType, Request};
use crate::util; use crate::util;
pub struct Issue; pub struct Issue;
@ -44,6 +45,12 @@ pub struct IssueResponse {
pub repository: Repository, pub repository: Repository,
} }
#[derive(Deserialize)]
pub struct IssueErrorResponse {
pub message: String,
pub url: String,
}
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct User { pub struct User {
pub id: i64, pub id: i64,
@ -67,24 +74,12 @@ pub struct Repository {
pub full_name: String, pub full_name: String,
} }
// trait IssueRequest {
// fn client() -> &'static Client;
// fn url_request_decision() -> String;
// fn arg_value_decision() -> Vec<&'static str>;
// }
// impl IssueRequest for Issue {
// fn client() -> &'static Client {
// return
// }
// }
impl Issue { impl Issue {
pub fn new() -> Issue { pub fn new() -> Issue {
Issue {} Issue {}
} }
pub fn create_issue(&self, request: &Request) { pub fn create_issue(&self, request: &Request) -> Result<(), error::ErrorKind> {
let issue_title: String; let issue_title: String;
let issue_description: String; let issue_description: String;
let _issue_assignee: Option<String>; let _issue_assignee: Option<String>;
@ -119,51 +114,60 @@ impl Issue {
let response = client.post(&url).json(&map).send(); let response = client.post(&url).json(&map).send();
match response { match response {
Ok(repo) => { Ok(repo) => match repo.status() {
match repo.status() { StatusCode::CREATED => println!("{}", "Issue successfully created!".green()),
StatusCode::CREATED => println!("{}", "Issue successfully created!".green()), StatusCode::FORBIDDEN => println!("{}", "Issue creation forbidden!".red()),
StatusCode::FORBIDDEN => println!("{}", "Issue creation forbidden!".red()), StatusCode::UNPROCESSABLE_ENTITY => {
StatusCode::UNPROCESSABLE_ENTITY => println!("{}", "Issue input validation failed!".red()), println!("{}", "Issue input validation failed!".red())
_ => println!(),
} }
_ => println!(),
}, },
Err(e) => panic!("{}", e), Err(e) => panic!("{}", e),
} }
} }
pub fn list_issue(&self, request: &Request) { pub fn list_issue(&self, request: &Request) -> Result<(), error::ErrorKind> {
let client = &request.client; let client = &request.client;
let url = self.url_request_decision(&request); let url = self.url_request_decision(&request);
let response = client.get(&url).send(); let response = client.get(&url).send();
// TODO: fix this to match context // TODO: fix this to match context
match response { match response {
Ok(repo) => { Ok(repo) => match repo.status() {
match repo.status() { StatusCode::CREATED => {
StatusCode::CREATED => println!("{}", "Issue successfully created!".green()), println!("{}", "Issue successfully created!".green());
StatusCode::FORBIDDEN => println!("{}", "Issue creation forbidden!".red()), Ok(())
StatusCode::UNPROCESSABLE_ENTITY => println!("{}", "Issue input validation failed!".red()),
_ => println!(),
} }
StatusCode::FORBIDDEN => {
let deserialized = repo.json().unwrap();
Err(error::ErrorKind::ForbiddenRequest(deserialized.message))
}
StatusCode::UNPROCESSABLE_ENTITY => {
let deserialized = repo.json().unwrap();
Err(error::ErrorKind::UnprocessiableRequest(
deserialized.message,
))
}
_ => Err(error::ErrorKind::Other),
}, },
Err(e) => panic!("{}", e), Err(e) => panic!("{}", e),
} }
} }
pub fn search_issue(&self, request: &Request) { pub fn search_issue(&self, request: &Request) -> Result<(), error::ErrorKind> {
let client = &request.client; let client = &request.client;
let url = self.url_request_decision(&request); let url = self.url_request_decision(&request);
let response = client.get(&url).send(); let response = client.get(&url).send();
// TODO: fix this to match context // TODO: fix this to match context
match response { match response {
Ok(repo) => { Ok(repo) => match repo.status() {
match repo.status() { StatusCode::CREATED => println!("{}", "Issue successfully created!".green()),
StatusCode::CREATED => println!("{}", "Issue successfully created!".green()), StatusCode::FORBIDDEN => println!("{}", "Issue creation forbidden!".red()),
StatusCode::FORBIDDEN => println!("{}", "Issue creation forbidden!".red()), StatusCode::UNPROCESSABLE_ENTITY => {
StatusCode::UNPROCESSABLE_ENTITY => println!("{}", "Issue input validation failed!".red()), println!("{}", "Issue input validation failed!".red())
_ => println!(),
} }
_ => println!(),
}, },
Err(e) => panic!("{}", e), Err(e) => panic!("{}", e),
} }
@ -190,7 +194,7 @@ impl Issue {
repo = arg_value[1], repo = arg_value[1],
api_token = request.authentication.credentials.1.as_ref().unwrap() api_token = request.authentication.credentials.1.as_ref().unwrap()
) )
}, }
AuthenticationType::BasicAuth => { AuthenticationType::BasicAuth => {
format!( format!(
"{request}/repos/{owner}/{repo}/issues?token={api_token}", "{request}/repos/{owner}/{repo}/issues?token={api_token}",
@ -199,10 +203,9 @@ impl Issue {
repo = arg_value[1], repo = arg_value[1],
api_token = request.authentication.credentials.1.as_ref().unwrap() api_token = request.authentication.credentials.1.as_ref().unwrap()
) )
}, }
// this case _shouldn't_ happen but ya know // this case _shouldn't_ happen but ya know
AuthenticationType::None => panic!("idk what happened man you wrote the code 🤷") AuthenticationType::None => panic!("idk what happened man you wrote the code 🤷"),
} }
} }
} }

View File

@ -5,6 +5,7 @@
mod arg; mod arg;
mod config; mod config;
mod error;
mod generate; mod generate;
mod issue; mod issue;
mod pr; mod pr;

View File

@ -7,6 +7,7 @@ use serde_derive::{Deserialize, Serialize};
use crate::{ use crate::{
config::Configuration, config::Configuration,
error,
request::Request, request::Request,
util::{self, ErrorKind}, util::{self, ErrorKind},
}; };
@ -112,7 +113,7 @@ impl Repository {
Repository {} Repository {}
} }
pub fn create_repo(&self, request: &Request) { pub fn create_repo(&self, request: &Request) -> Result<(), error::ErrorKind> {
let client = &request.client; let client = &request.client;
let arg_value = request let arg_value = request
.arg_value .arg_value
@ -141,33 +142,30 @@ impl Repository {
let deserialized: RepositoryResponse = repo.json().unwrap(); let deserialized: RepositoryResponse = repo.json().unwrap();
println!("{}", "Repository successfully created!".green()); println!("{}", "Repository successfully created!".green());
println!("\tRepository name: {:0}\n\tRepository owner: {:1}\n\tRepository description: {:2}", deserialized.name, deserialized.owner.unwrap().full_name, deserialized.description); println!("\tRepository name: {:0}\n\tRepository owner: {:1}\n\tRepository description: {:2}", deserialized.name, deserialized.owner.unwrap().full_name, deserialized.description);
Ok(())
} }
StatusCode::BAD_REQUEST => { StatusCode::BAD_REQUEST => {
// TODO: implement error handling for the deserialization // TODO: implement error handling for the deserialization
let deserialized: RepositoryErrorResponse = repo.json().unwrap(); let deserialized: RepositoryErrorResponse = repo.json().unwrap();
println!( Err(error::ErrorKind::BadRequest(deserialized.message))
"{}", }
util::bad_response_message(&deserialized.message, ErrorKind::BadRequest) StatusCode::CONFLICT => {
.red() let deserialized: RepositoryErrorResponse = repo.json().unwrap();
); Err(error::ErrorKind::Conflict(deserialized.message))
} }
StatusCode::CONFLICT => println!(
"{}",
"Repository has the same name or already exists!".red()
),
StatusCode::UNPROCESSABLE_ENTITY => { StatusCode::UNPROCESSABLE_ENTITY => {
println!("{}", "Repository input validation failed!".red()) let deserialized: RepositoryErrorResponse = repo.json().unwrap();
Err(error::ErrorKind::UnprocessiableRequest(
deserialized.message,
))
} }
_ => println!( _ => Err(error::ErrorKind::Other),
"Repository creation failed! HTTP status code: {}",
repo.status().as_str()
),
}, },
Err(e) => panic!("{}", e), Err(_e) => Err(error::ErrorKind::Other),
} }
} }
pub fn delete_repo(&self, request: &Request) { pub fn delete_repo(&self, request: &Request) -> Result<(), error::ErrorKind> {
let client = &request.client; let client = &request.client;
let arg_value: Vec<&str> = request let arg_value: Vec<&str> = request
.arg_value .arg_value
@ -205,7 +203,7 @@ impl Repository {
} }
} }
pub fn fork_repo(&self, request: &Request) { pub fn fork_repo(&self, request: &Request) -> Result<(), error::ErrorKind> {
let client = &request.client; let client = &request.client;
let arg_item: Vec<&str> = request let arg_item: Vec<&str> = request
.arg_value .arg_value
@ -259,7 +257,7 @@ impl Repository {
} }
} }
pub fn search_repo(&self, request: &Request) { pub fn search_repo(&self, request: &Request) -> Result<(), error::ErrorKind> {
let client = &request.client; let client = &request.client;
let arg_value = request let arg_value = request
.arg_value .arg_value
@ -312,7 +310,7 @@ impl Repository {
} }
} }
pub fn list_repo(&self, request: &Request) { pub fn list_repo(&self, request: &Request) -> Result<(), error::ErrorKind> {
let client = &request.client; let client = &request.client;
let url = format!( let url = format!(
"{request}/repos/search?token={api_token}", "{request}/repos/search?token={api_token}",

View File

@ -1,6 +1,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use crate::{ use crate::{
error,
request::Request, request::Request,
util::{self, ErrorKind}, util::{self, ErrorKind},
}; };
@ -47,7 +48,7 @@ impl User {
User {} User {}
} }
pub fn create_user(&self, request: &Request) { pub fn create_user(&self, request: &Request) -> Result<(), error::ErrorKind> {
let client = &request.client; let client = &request.client;
let mut user_create_input: HashMap<String, String> = HashMap::new(); let mut user_create_input: HashMap<String, String> = HashMap::new();
let url = format!( let url = format!(
@ -65,6 +66,7 @@ impl User {
user_create_input.insert("password".to_string(), password); user_create_input.insert("password".to_string(), password);
let response = client.post(url.as_str()).json(&user_create_input).send(); let response = client.post(url.as_str()).json(&user_create_input).send();
// TODO: match return type
match response { match response {
Ok(repo) => match repo.status() { Ok(repo) => match repo.status() {
StatusCode::CREATED => { StatusCode::CREATED => {
@ -74,33 +76,23 @@ impl User {
"\tFull Name: {:0}\n\tUsername: {:1}\n\tEmail: {:2}\n", "\tFull Name: {:0}\n\tUsername: {:1}\n\tEmail: {:2}\n",
deserialized.full_name, deserialized.login, deserialized.email deserialized.full_name, deserialized.login, deserialized.email
); );
Ok(())
} }
StatusCode::BAD_REQUEST => { StatusCode::BAD_REQUEST => {
let deserialized: UserErrorResponse = repo.json().unwrap(); let deserialized: UserErrorResponse = repo.json().unwrap();
println!( Err(error::ErrorKind::BadRequest(deserialized.message))
"{}",
util::bad_response_message(&deserialized.message, ErrorKind::BadRequest)
.red()
);
} }
StatusCode::FORBIDDEN => { StatusCode::FORBIDDEN => {
let deserialized: UserErrorResponse = repo.json().unwrap(); let deserialized: UserErrorResponse = repo.json().unwrap();
println!( Err(error::ErrorKind::ForbiddenRequest(deserialized.message))
"{}",
util::bad_response_message(
&deserialized.message,
ErrorKind::ForbiddenRequest
)
.red()
);
} }
_ => println!("¯\\_(ツ)_/¯"), _ => Err(error::ErrorKind::Other),
}, },
Err(e) => println!("{}", e), Err(_e) => Err(error::ErrorKind::Other),
} }
} }
pub fn list_user(&self, request: &Request) { pub fn list_user(&self, request: &Request) -> Result<(), error::ErrorKind> {
let client = &request.client; let client = &request.client;
let url = format!( let url = format!(
@ -127,40 +119,30 @@ impl User {
"Total number of users indexed: {}", "Total number of users indexed: {}",
deserialized.data.len() deserialized.data.len()
); );
Ok(())
}
false => {
println!("{}", "No users found :(");
Ok(())
} }
false => println!("{}", "No users found :("),
} }
} }
StatusCode::BAD_REQUEST => { StatusCode::BAD_REQUEST => {
let deserialized: UserErrorResponse = repo.json().unwrap(); // TODO: handle let deserialized: UserErrorResponse = repo.json().unwrap(); // TODO: handle
println!( Err(error::ErrorKind::BadRequest(deserialized.message))
"{}",
util::bad_response_message(
&deserialized.message,
ErrorKind::BadRequest
)
.red()
);
} }
StatusCode::FORBIDDEN => { StatusCode::FORBIDDEN => {
let deserialzed: UserErrorResponse = repo.json().unwrap(); // TODO: handle errs let deserialzed: UserErrorResponse = repo.json().unwrap(); // TODO: handle errs
println!( Err(error::ErrorKind::ForbiddenRequest(deserialzed.message))
"{}",
util::bad_response_message(
&deserialzed.message,
ErrorKind::ForbiddenRequest
)
.red()
);
} }
_ => println!("huh?"), _ => Err(error::ErrorKind::Other),
} }
} }
Err(e) => panic!("{}", e), Err(_e) => Err(error::ErrorKind::Other),
} }
} }
pub fn search_user(&self, request: &Request) { pub fn search_user(&self, request: &Request) -> Result<(), error::ErrorKind> {
let client = &request.client; let client = &request.client;
let arg_value = request let arg_value = request
.arg_value .arg_value
@ -181,13 +163,14 @@ impl User {
match response { match response {
Ok(repo) => match repo.status() { Ok(repo) => match repo.status() {
_ => println!(""), StatusCode::OK => Ok(()),
_ => Err(error::ErrorKind::Other),
}, },
Err(e) => panic!("{}", e), Err(_e) => Err(error::ErrorKind::Other),
} }
} }
pub fn delete_user(&self, request: &Request) { pub fn delete_user(&self, request: &Request) -> Result<(), error::ErrorKind> {
let client = &request.client; let client = &request.client;
let arg_value = request let arg_value = request
.arg_value .arg_value
@ -207,21 +190,16 @@ impl User {
match response { match response {
Ok(repo) => match repo.status() { Ok(repo) => match repo.status() {
StatusCode::NO_CONTENT => { StatusCode::NO_CONTENT => {
println!("User successfully deleted!") println!("User successfully deleted!");
Ok(())
} }
StatusCode::FORBIDDEN => { StatusCode::FORBIDDEN => {
let deserialized: UserErrorResponse = repo.json().unwrap(); let deserialized: UserErrorResponse = repo.json().unwrap();
println!( Err(error::ErrorKind::ForbiddenRequest(deserialized.message))
"{}",
util::bad_response_message(
&deserialized.message,
ErrorKind::ForbiddenRequest
)
);
} }
_ => println!(""), _ => Err(error::ErrorKind::Other),
}, },
Err(e) => panic!("{}", e), Err(_e) => Err(error::ErrorKind::Other),
} }
} }