Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build]
rustflags = ["-D", "warnings"]
rustdocflags = ["-D", "warnings"]
4 changes: 2 additions & 2 deletions crates/crabapi/examples/multiple_requests.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crabapi::core::requests::{build_request, send_requests};
use crabapi::core::requests::{Url, build_request, send_requests};
use http::{HeaderMap, Method};
use reqwest::{Body, Client};
use std::collections::HashMap;
Expand All @@ -16,7 +16,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
headers.insert("key", i.to_string().parse().unwrap());
reqs.push(build_request(
&client,
"http://localhost:7878",
Url::parse("http://localhost:7878").unwrap(),
query,
Method::POST,
headers,
Expand Down
4 changes: 2 additions & 2 deletions crates/crabapi/examples/one_request.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crabapi::core::requests::{build_request, send_requests};
use crabapi::core::requests::{Url, build_request, send_requests};
use http::{HeaderMap, Method};
use reqwest::{Body, Client};
use std::collections::HashMap;
Expand All @@ -11,7 +11,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// send 1 request
let req = build_request(
&client,
"http://localhost:7878",
Url::parse("http://localhost:7878").unwrap(),
HashMap::new(),
Method::GET,
HeaderMap::new(),
Expand Down
10 changes: 8 additions & 2 deletions crates/crabapi/src/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::core::app::constants;
use crate::core::requests::{build_request, print_response, send_requests};
use crate::core::requests::{
Url, build_request, constants as requests_constants, print_response, send_requests,
};
use clap::{Arg, ArgAction, Command};
use const_format::formatcp;
use http::{HeaderMap, HeaderName, HeaderValue, Method};
Expand Down Expand Up @@ -40,7 +42,10 @@ impl Cli {
.short('X')
.long("method")
.value_name("METHOD")
.help("HTTP method(GET, POST, PUT, DELETE, OPTIONS)")
.help(formatcp!(
"HTTP method({})",
requests_constants::ALL_METHODS_AS_STRING
))
.default_value("GET"),
headers_arg: Arg::new("headers")
.short('H')
Expand Down Expand Up @@ -98,6 +103,7 @@ impl Cli {
.unwrap()
.parse::<Method>()?;
let url = matches.get_one::<String>("url").unwrap();
let url = Url::parse(url).unwrap();

let mut headers = HeaderMap::new();
if let Some(header_values) = matches.get_many::<String>("headers") {
Expand Down
28 changes: 25 additions & 3 deletions crates/crabapi/src/core/requests.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,44 @@
use http::{HeaderMap, Method};
use reqwest::{Body, Client, Error, RequestBuilder, Response};
use std::collections::HashMap;
use tokio::task::JoinHandle;

pub use http::{HeaderMap, Method};
pub use reqwest::Url;

pub mod constants {
use const_format::formatcp;
use http::Method;

pub const USER_AGENT: &str = formatcp!(
"{} v{}",
crate::core::app::constants::APP_NAME,
crate::core::app::constants::APP_VERSION
);

pub const METHODS: [Method; 9] = [
Method::GET,
Method::POST,
Method::PUT,
Method::DELETE,
Method::HEAD,
Method::OPTIONS,
Method::CONNECT,
Method::PATCH,
Method::TRACE,
];

pub const METHODS_STRING: [&str; 9] = [
"GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS", "CONNECT", "PATCH", "TRACE",
];

pub const ALL_METHODS_AS_STRING: &str =
"GET, POST, PUT, DELETE, HEAD, OPTIONS, CONNECT, PATCH, TRACE";
}

// TODO: Implement params too
pub fn build_request(
client: &Client,
url: &str,
url: Url,
query: HashMap<String, String>,
method: Method,
headers: HeaderMap,
Expand All @@ -25,7 +47,7 @@ pub fn build_request(
let mut default_headers = HeaderMap::new();
default_headers.insert("User-Agent", constants::USER_AGENT.parse().unwrap());

let request = reqwest::Request::new(method, url.parse().unwrap());
let request = reqwest::Request::new(method, url);
RequestBuilder::from_parts(client.clone(), request)
.query(&query)
.headers(default_headers)
Expand Down
49 changes: 33 additions & 16 deletions crates/crabapi/src/gui/iced/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use iced;
use iced::widget::{Button, Column, Text, TextInput, column, row, text};
use iced::widget::{Button, Text, TextInput, column, row};
use iced::widget::{button, combo_box, container};
use iced::{Element, Length};

use http::Method;
use crate::core::requests::{Method, Url, constants};

pub fn init() {
iced::run(GUI::title, GUI::update, GUI::view).unwrap()
Expand All @@ -18,6 +18,7 @@ enum Message {
SendRequest,
HeaderKeyChanged(usize, String),
HeaderValueChanged(usize, String),
#[allow(dead_code)] // TODO: Remove this out-out warning
RemoveHeader(usize),
AddHeader,
}
Expand All @@ -27,23 +28,18 @@ enum Message {
pub struct GUI {
methods: combo_box::State<Method>,
method_selected: Option<Method>,
url_input: String, //http::Uri,
header_input: Vec<(String, String)>, //http::HeaderMap,
// body_input: String, //http::Body
url_input: String,
url_input_valid: bool,
header_input: Vec<(String, String)>,
}

impl GUI {
fn new() -> Self {
Self {
methods: combo_box::State::new(vec![
Method::GET,
Method::POST,
Method::PUT,
Method::DELETE,
Method::PATCH,
]),
methods: combo_box::State::new(constants::METHODS.into()),
method_selected: None,
url_input: String::new(),
url_input_valid: false,
header_input: vec![(String::new(), String::new())],
// body_input: String::new(),
}
Expand All @@ -59,7 +55,8 @@ impl GUI {
self.method_selected = Some(method);
}
Message::UrlInputChanged(url) => {
self.url_input = url; //http::Uri::from_static("http://localhost:7878");
self.url_input = url;
self.url_input_valid = GUI::is_valid_url(&self.url_input);
} // Message::HeaderInputChanged(header) => {
// self.header_input = header; // ttp::HeaderMap::new();
// }
Expand Down Expand Up @@ -88,16 +85,28 @@ impl GUI {

fn view(&self) -> Element<Message> {
// ROW: Method, URI, Send Button
let url_input_icon = iced::widget::text_input::Icon {
font: iced::Font::default(),
code_point: if self.url_input_valid { '✅' } else { '❌' },
size: Some(Self::input_size()),
spacing: 0.0,
side: iced::widget::text_input::Side::Right,
};

let url_input = TextInput::new("Enter URI", &self.url_input)
.on_input(Message::UrlInputChanged)
.size(Self::input_size())
.icon(url_input_icon)
.width(Length::Fill);
let method_combo_box = combo_box(
&self.methods,
"Method",
self.method_selected.as_ref(),
Message::MethodChanged,
)
.width(75);
.width(75)
.size(Self::input_size_as_f32());

let send_button = Button::new(Text::new("Send").size(20)).on_press(Message::SendRequest);
let request_row = row![method_combo_box, url_input, send_button]
.spacing(10)
Expand Down Expand Up @@ -136,8 +145,16 @@ impl GUI {
.into()
}

fn label(label: &str) -> Column<'_, Message> {
column![text(label)].spacing(10)
fn is_valid_url(url: &str) -> bool {
Url::parse(url).is_ok()
}

const fn input_size_as_f32() -> f32 {
20.0
}

const fn input_size() -> iced::Pixels {
iced::Pixels(Self::input_size_as_f32())
}
}

Expand Down