From 02c62b7ba603067d71c217399e7ca058618f6f96 Mon Sep 17 00:00:00 2001 From: "Wyatt J. Miller" Date: Fri, 30 Aug 2024 08:17:53 -0400 Subject: [PATCH] wip: add base64 encoding to impl, add custom errors to impl --- src/issue.rs | 87 +++++++++++++++++++++++++++------------------------- src/main.rs | 1 + src/repo.rs | 38 +++++++++++------------ src/user.rs | 78 +++++++++++++++++----------------------------- 4 files changed, 92 insertions(+), 112 deletions(-) diff --git a/src/issue.rs b/src/issue.rs index afdfe38..8575582 100644 --- a/src/issue.rs +++ b/src/issue.rs @@ -2,11 +2,12 @@ use std::collections::HashMap; use colored::*; use reqwest::blocking::Client; -use reqwest::{StatusCode, Response}; -use serde_derive::{Serialize, Deserialize}; +use reqwest::{Response, StatusCode}; +use serde_derive::{Deserialize, Serialize}; use serde_json::Value; -use crate::request::{Request, Authentication, AuthenticationType}; +use crate::error; +use crate::request::{AuthenticationType, Request}; use crate::util; pub struct Issue; @@ -44,6 +45,12 @@ pub struct IssueResponse { pub repository: Repository, } +#[derive(Deserialize)] +pub struct IssueErrorResponse { + pub message: String, + pub url: String, +} + #[derive(Serialize, Deserialize)] pub struct User { pub id: i64, @@ -67,30 +74,18 @@ pub struct Repository { 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 { pub fn new() -> 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_description: String; let _issue_assignee: Option; let _issue_milestone: Option; let _issue_tags: Option; - + let client = &request.client; let arg_value: Vec<&str> = request .arg_value @@ -119,51 +114,60 @@ impl Issue { let response = client.post(&url).json(&map).send(); match response { - Ok(repo) => { - match repo.status() { - StatusCode::CREATED => println!("{}", "Issue successfully created!".green()), - StatusCode::FORBIDDEN => println!("{}", "Issue creation forbidden!".red()), - StatusCode::UNPROCESSABLE_ENTITY => println!("{}", "Issue input validation failed!".red()), - _ => println!(), + Ok(repo) => match repo.status() { + StatusCode::CREATED => println!("{}", "Issue successfully created!".green()), + StatusCode::FORBIDDEN => println!("{}", "Issue creation forbidden!".red()), + StatusCode::UNPROCESSABLE_ENTITY => { + println!("{}", "Issue input validation failed!".red()) } + _ => println!(), }, 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 url = self.url_request_decision(&request); let response = client.get(&url).send(); // TODO: fix this to match context match response { - Ok(repo) => { - match repo.status() { - StatusCode::CREATED => println!("{}", "Issue successfully created!".green()), - StatusCode::FORBIDDEN => println!("{}", "Issue creation forbidden!".red()), - StatusCode::UNPROCESSABLE_ENTITY => println!("{}", "Issue input validation failed!".red()), - _ => println!(), + Ok(repo) => match repo.status() { + StatusCode::CREATED => { + println!("{}", "Issue successfully created!".green()); + Ok(()) } + 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), } } - pub fn search_issue(&self, request: &Request) { + pub fn search_issue(&self, request: &Request) -> Result<(), error::ErrorKind> { let client = &request.client; let url = self.url_request_decision(&request); let response = client.get(&url).send(); // TODO: fix this to match context match response { - Ok(repo) => { - match repo.status() { - StatusCode::CREATED => println!("{}", "Issue successfully created!".green()), - StatusCode::FORBIDDEN => println!("{}", "Issue creation forbidden!".red()), - StatusCode::UNPROCESSABLE_ENTITY => println!("{}", "Issue input validation failed!".red()), - _ => println!(), + Ok(repo) => match repo.status() { + StatusCode::CREATED => println!("{}", "Issue successfully created!".green()), + StatusCode::FORBIDDEN => println!("{}", "Issue creation forbidden!".red()), + StatusCode::UNPROCESSABLE_ENTITY => { + println!("{}", "Issue input validation failed!".red()) } + _ => println!(), }, Err(e) => panic!("{}", e), } @@ -179,7 +183,7 @@ impl Issue { .values_of("search") .unwrap() .collect(); - + // TODO: fix the url formatting for basic auth match &request.authentication.auth_type { AuthenticationType::ApiToken => { @@ -190,7 +194,7 @@ impl Issue { repo = arg_value[1], api_token = request.authentication.credentials.1.as_ref().unwrap() ) - }, + } AuthenticationType::BasicAuth => { format!( "{request}/repos/{owner}/{repo}/issues?token={api_token}", @@ -199,10 +203,9 @@ impl Issue { repo = arg_value[1], api_token = request.authentication.credentials.1.as_ref().unwrap() ) - }, + } // 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 🤷"), } } - } diff --git a/src/main.rs b/src/main.rs index 70c462a..cd6bc88 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ mod arg; mod config; +mod error; mod generate; mod issue; mod pr; diff --git a/src/repo.rs b/src/repo.rs index feea55a..8028b53 100644 --- a/src/repo.rs +++ b/src/repo.rs @@ -7,6 +7,7 @@ use serde_derive::{Deserialize, Serialize}; use crate::{ config::Configuration, + error, request::Request, util::{self, ErrorKind}, }; @@ -112,7 +113,7 @@ impl Repository { Repository {} } - pub fn create_repo(&self, request: &Request) { + pub fn create_repo(&self, request: &Request) -> Result<(), error::ErrorKind> { let client = &request.client; let arg_value = request .arg_value @@ -141,33 +142,30 @@ impl Repository { let deserialized: RepositoryResponse = repo.json().unwrap(); 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); + Ok(()) } StatusCode::BAD_REQUEST => { // TODO: implement error handling for the deserialization let deserialized: RepositoryErrorResponse = repo.json().unwrap(); - println!( - "{}", - util::bad_response_message(&deserialized.message, ErrorKind::BadRequest) - .red() - ); + Err(error::ErrorKind::BadRequest(deserialized.message)) + } + StatusCode::CONFLICT => { + 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 => { - println!("{}", "Repository input validation failed!".red()) + let deserialized: RepositoryErrorResponse = repo.json().unwrap(); + Err(error::ErrorKind::UnprocessiableRequest( + deserialized.message, + )) } - _ => println!( - "Repository creation failed! HTTP status code: {}", - repo.status().as_str() - ), + _ => Err(error::ErrorKind::Other), }, - 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 arg_value: Vec<&str> = request .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 arg_item: Vec<&str> = request .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 arg_value = request .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 url = format!( "{request}/repos/search?token={api_token}", diff --git a/src/user.rs b/src/user.rs index 8d74a16..9e5fb2a 100644 --- a/src/user.rs +++ b/src/user.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use crate::{ + error, request::Request, util::{self, ErrorKind}, }; @@ -47,7 +48,7 @@ impl User { User {} } - pub fn create_user(&self, request: &Request) { + pub fn create_user(&self, request: &Request) -> Result<(), error::ErrorKind> { let client = &request.client; let mut user_create_input: HashMap = HashMap::new(); let url = format!( @@ -65,6 +66,7 @@ impl User { user_create_input.insert("password".to_string(), password); let response = client.post(url.as_str()).json(&user_create_input).send(); + // TODO: match return type match response { Ok(repo) => match repo.status() { StatusCode::CREATED => { @@ -74,33 +76,23 @@ impl User { "\tFull Name: {:0}\n\tUsername: {:1}\n\tEmail: {:2}\n", deserialized.full_name, deserialized.login, deserialized.email ); + Ok(()) } StatusCode::BAD_REQUEST => { let deserialized: UserErrorResponse = repo.json().unwrap(); - println!( - "{}", - util::bad_response_message(&deserialized.message, ErrorKind::BadRequest) - .red() - ); + Err(error::ErrorKind::BadRequest(deserialized.message)) } StatusCode::FORBIDDEN => { let deserialized: UserErrorResponse = repo.json().unwrap(); - println!( - "{}", - util::bad_response_message( - &deserialized.message, - ErrorKind::ForbiddenRequest - ) - .red() - ); + Err(error::ErrorKind::ForbiddenRequest(deserialized.message)) } - _ => 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 url = format!( @@ -127,40 +119,30 @@ impl User { "Total number of users indexed: {}", deserialized.data.len() ); + Ok(()) + } + false => { + println!("{}", "No users found :("); + Ok(()) } - false => println!("{}", "No users found :("), } } StatusCode::BAD_REQUEST => { let deserialized: UserErrorResponse = repo.json().unwrap(); // TODO: handle - println!( - "{}", - util::bad_response_message( - &deserialized.message, - ErrorKind::BadRequest - ) - .red() - ); + Err(error::ErrorKind::BadRequest(deserialized.message)) } StatusCode::FORBIDDEN => { let deserialzed: UserErrorResponse = repo.json().unwrap(); // TODO: handle errs - println!( - "{}", - util::bad_response_message( - &deserialzed.message, - ErrorKind::ForbiddenRequest - ) - .red() - ); + Err(error::ErrorKind::ForbiddenRequest(deserialzed.message)) } - _ => 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 arg_value = request .arg_value @@ -181,13 +163,14 @@ impl User { match response { 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 arg_value = request .arg_value @@ -207,21 +190,16 @@ impl User { match response { Ok(repo) => match repo.status() { StatusCode::NO_CONTENT => { - println!("User successfully deleted!") + println!("User successfully deleted!"); + Ok(()) } StatusCode::FORBIDDEN => { let deserialized: UserErrorResponse = repo.json().unwrap(); - println!( - "{}", - util::bad_response_message( - &deserialized.message, - ErrorKind::ForbiddenRequest - ) - ); + Err(error::ErrorKind::ForbiddenRequest(deserialized.message)) } - _ => println!(""), + _ => Err(error::ErrorKind::Other), }, - Err(e) => panic!("{}", e), + Err(_e) => Err(error::ErrorKind::Other), } }