Skip to content
This repository has been archived by the owner on Oct 8, 2024. It is now read-only.

Commit

Permalink
feat: fix clunky input, make inline input menu
Browse files Browse the repository at this point in the history
  • Loading branch information
PThorpe92 committed Apr 1, 2024
1 parent f55ebd1 commit 00e3213
Show file tree
Hide file tree
Showing 22 changed files with 465 additions and 378 deletions.
139 changes: 100 additions & 39 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,11 @@ impl<'a> App<'a> {
self.input.reset();
self.screen_stack.push(screen.clone());
self.current_screen = screen.clone();

self.cursor = 0;
match screen {
Screen::Method => {
// If The Method Screen Is Hit, We Reset options
self.remove_all_app_options();
self.clear_all_options();
self.input.reset();
self.items = screen.get_opts(None);
}
Expand Down Expand Up @@ -162,9 +161,13 @@ impl<'a> App<'a> {
.get_collections()
.unwrap_or_default()
.iter()
.map(|col| ListItem::new(format!("{}{}", col.name, OPTION_PADDING_MID)))
.map(|col| ListItem::new(format!("{}{}", col.get_name(), OPTION_PADDING_MID)))
.collect();
}
Screen::RequestMenu(opt) if opt.as_ref().is_some_and(|op| !op.is_error()) => {
self.input_mode = InputMode::Editing;
self.selected = None;
}
_ => {
self.items = screen.get_opts(None);
}
Expand All @@ -174,24 +177,25 @@ impl<'a> App<'a> {

pub fn go_back_screen(&mut self) {
let last = self.screen_stack.pop().unwrap_or_default(); // current screen
match self.screen_stack.last() {
Some(screen) if screen == &last => self.go_back_screen(),
match self.screen_stack.last().cloned() {
Some(screen) if screen == last => self.go_back_screen(),
Some(
Screen::InputMenu(_)
| Screen::CmdMenu(_)
| Screen::ColMenu(_)
| Screen::KeysMenu(_),
) => self.go_back_screen(),
Some(Screen::RequestBodyInput) => self.goto_screen(&Screen::Method),
Some(Screen::Error(_)) => self.goto_screen(&Screen::Home),
Some(Screen::RequestMenu(ref e)) => {
if e.to_lowercase().contains("error") || e.to_lowercase().contains("alert") {
self.goto_screen(&Screen::RequestMenu(String::new()));
if !e.as_ref().is_some_and(|err| err.is_error()) {
self.goto_screen(&Screen::RequestMenu(e.clone()));
} else {
self.goto_screen(&Screen::Method);
}
}
Some(screen) => {
self.goto_screen(&screen.clone());
self.goto_screen(&screen);
}
_ => self.goto_screen(&Screen::Home),
}
Expand All @@ -207,20 +211,46 @@ impl<'a> App<'a> {
}

pub fn move_cursor_down(&mut self) {
if self.items.is_empty() {
return;
}
if !self.items.is_empty() && self.cursor < self.items.len() - 1 {
self.cursor += 1;
match self.current_screen {
Screen::RequestMenu(ref opt) => {
if opt.clone().is_some_and(|op| !op.is_error()) {
self.goto_screen(&Screen::RequestMenu(None));
return;
}
if !self.items.is_empty() && self.cursor < self.items.len() - 1 {
self.cursor += 1;
}
}
_ => {
if self.items.is_empty() {
return;
}
if !self.items.is_empty() && self.cursor < self.items.len() - 1 {
self.cursor += 1;
}
}
}
}

pub fn move_cursor_up(&mut self) {
if self.items.is_empty() {
return;
}
if let Some(res) = self.cursor.checked_sub(1) {
self.cursor = res;
match self.current_screen {
Screen::RequestMenu(ref opt) => {
if opt.clone().is_some_and(|op| !op.is_error()) {
self.goto_screen(&Screen::RequestMenu(None));
return;
}
if let Some(res) = self.cursor.checked_sub(1) {
self.cursor = res;
}
}
_ => {
if self.items.is_empty() {
return;
}
if let Some(res) = self.cursor.checked_sub(1) {
self.cursor = res;
}
}
}
}

Expand All @@ -234,6 +264,40 @@ impl<'a> App<'a> {
});
}

pub fn get_special_items(&self) -> Option<Vec<String>> {
match self.current_screen {
Screen::SavedKeys => Some(
self.get_saved_keys()
.unwrap_or_default()
.into_iter()
.map(|x| x.to_string())
.collect::<Vec<String>>(),
),
Screen::SavedCommands(coll_id) => Some(
self.get_saved_commands(coll_id)
.unwrap_or_default()
.into_iter()
.map(|x| format!("{:?}", x))
.collect::<Vec<String>>(),
),
Screen::ViewSavedCollections => Some(
self.get_collections()
.unwrap_or_default()
.into_iter()
.map(|x| x.get_name().to_string())
.collect::<Vec<String>>(),
),
Screen::SavedCollections => Some(
self.get_collections()
.unwrap_or_default()
.into_iter()
.map(|x| x.get_name().to_string())
.collect::<Vec<String>>(),
),
_ => None,
}
}

pub fn get_url(&self) -> &str {
self.command.get_url()
}
Expand All @@ -258,6 +322,14 @@ impl<'a> App<'a> {
self.db.get_collections()
}

pub fn get_collection_by_id(&self, id: i32) -> Result<SavedCollection, rusqlite::Error> {
self.db.get_collection_by_id(id)
}

pub fn get_command_by_id(&self, id: i32) -> Result<SavedCommand, rusqlite::Error> {
self.db.get_command_by_id(id)
}

pub fn add_saved_key(&mut self, key: String) -> Result<(), rusqlite::Error> {
match self.db.as_ref().add_key(&key) {
Ok(_) => Ok(()),
Expand Down Expand Up @@ -291,25 +363,15 @@ impl<'a> App<'a> {
}

// Takes an array index of the selected item
pub fn execute_saved_command(&mut self, index: usize) {
if let Ok(saved_commands) = self.get_saved_commands(None) {
match saved_commands.get(index) {
Some(cmd) => {
let mut command: Curl = serde_json::from_str(cmd.get_curl_json())
.map_err(|e| e.to_string())
.unwrap();
command.easy_from_opts();
match command.execute(None) {
Ok(_) => self.set_response(&command.get_response()),
Err(e) => self.set_response(&e),
};
self.goto_screen(&Screen::Response(self.response.clone().unwrap()));
}
None => self.goto_screen(&Screen::Error("Saved command not found".to_string())),
}
} else {
self.goto_screen(&Screen::Error("Saved command not found".to_string()));
}
pub fn execute_saved_command(&mut self, json: &str) {
let mut command: Curl = serde_json::from_str(json)
.map_err(|e| e.to_string())
.unwrap();
command.easy_from_opts();
match command.execute(None) {
Ok(_) => self.set_response(&command.get_response()),
Err(e) => self.set_response(&e),
};
}

pub fn set_key_label(&self, key: i32, label: &str) -> Result<(), String> {
Expand Down Expand Up @@ -422,8 +484,7 @@ impl<'a> App<'a> {
.retain(|x| mem::discriminant(x) != mem::discriminant(opt));
}

// Need a button to reset everything
pub fn remove_all_app_options(&mut self) {
pub fn clear_all_options(&mut self) {
self.opts.clear();
self.messages.clear();
self.response = None;
Expand Down
59 changes: 52 additions & 7 deletions src/database/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ use std::{

#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
pub struct SavedCommand {
pub id: i32,
pub command: String,
pub curl_json: String,
pub collection_id: Option<i32>,
id: i32,
command: String,
curl_json: String,
collection_id: Option<i32>,
}

#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
pub struct SavedCollection {
pub id: i32,
pub name: String,
id: i32,
name: String,
}

impl Display for SavedCollection {
Expand All @@ -38,7 +38,7 @@ pub struct SavedKey {

#[derive(Debug)]
pub struct DB {
pub conn: Connection,
conn: Connection,
}

impl DB {
Expand Down Expand Up @@ -130,6 +130,33 @@ impl DB {
Ok(())
}

pub fn get_command_by_id(&self, id: i32) -> Result<SavedCommand> {
let mut stmt = self
.conn
.prepare("SELECT id, command, curl_json, collection_id from commands WHERE id = ?1")?;
stmt.query_row(params![id], |row| {
Ok(SavedCommand {
id: row.get(0)?,
command: row.get(1)?,
curl_json: row.get(2)?,
collection_id: row.get(3)?,
})
})
}

pub fn get_collection_by_id(&self, id: i32) -> Result<SavedCollection> {
let mut stmt = self
.conn
.prepare("SELECT id, name FROM collections WHERE id = ?")?;
let collection = stmt.query_row(params![id], |row| {
Ok(SavedCollection {
id: row.get(0)?,
name: row.get(1)?,
})
})?;
Ok(collection)
}

pub fn create_collection(&self, name: &str) -> Result<(), rusqlite::Error> {
let mut stmt = self
.conn
Expand Down Expand Up @@ -301,6 +328,15 @@ impl SavedCommand {
Ok(serde_json::to_string(&self).expect("Failed to serialize"))
}

pub fn new(command: &str, curl_json: &str, collection_id: Option<i32>) -> Self {
SavedCommand {
command: command.to_string(),
curl_json: curl_json.to_string(),
collection_id,
..Default::default()
}
}

pub fn get_id(&self) -> i32 {
self.id
}
Expand Down Expand Up @@ -366,3 +402,12 @@ impl SavedKey {
Ok(serde_json::from_str(json).expect("Failed to deserialize"))
}
}

impl SavedCollection {
pub fn get_name(&self) -> &str {
&self.name
}
pub fn get_id(&self) -> i32 {
self.id
}
}
16 changes: 6 additions & 10 deletions src/database/postman.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ impl From<PostmanCollection> for Vec<SavedCommand> {
curl_cmd.set_request_body(body);
}
}
if resp.get("url").is_some() && !curl_cmd.get_url().is_empty() {
let url = resp.get("url").unwrap().as_object().unwrap();
let url = url.get("raw").unwrap().as_str().unwrap();
curl_cmd.set_url(url);
}
if let Some(cookie) = resp.get("cookie") {
if let Some(cookie) = cookie.as_array() {
cookie.iter().for_each(|ck| {
Expand All @@ -97,23 +102,14 @@ impl From<PostmanCollection> for Vec<SavedCommand> {
});
}
}
if let Some(url) = resp.get("url") {
let url = url.as_object().unwrap();
let url = url.get("raw").unwrap().as_str().unwrap();
curl_cmd.set_url(url);
}
}
});
}
}
});
let cmd = curl_cmd.get_command_string();
let curl_json: String = serde_json::to_string(&curl_cmd).unwrap_or_default();
saved_commands.push(SavedCommand {
command: cmd,
curl_json,
..Default::default()
});
saved_commands.push(SavedCommand::new(&cmd, &curl_json, None));
saved_commands
}
}
Expand Down
11 changes: 11 additions & 0 deletions src/display/inputopt.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::request::curl::Method;
use crate::screens::auth::AuthType;
use std::fmt::Display;

Expand Down Expand Up @@ -25,6 +26,14 @@ pub enum InputOpt {
ImportCollection,
CreateCollection,
RenameCollection(i32),
RequestError(String),
Method(Method),
}

impl InputOpt {
pub fn is_error(&self) -> bool {
matches!(self, InputOpt::RequestError(_))
}
}

impl Display for InputOpt {
Expand Down Expand Up @@ -52,6 +61,8 @@ impl Display for InputOpt {
InputOpt::ImportCollection => write!(f, "| Import Collection"),
InputOpt::CreateCollection => write!(f, "| Create Collection"),
InputOpt::RenameCollection(_) => write!(f, "| Rename Collection"),
InputOpt::RequestError(ref err) => write!(f, "| Error: {}", err),
InputOpt::Method(method) => write!(f, "| Method: {}", method),
}
}
}
Loading

0 comments on commit 00e3213

Please sign in to comment.