diff options
author | Guillaume Pasquet <dev@etenil.net> | 2021-11-14 22:50:17 +0000 |
---|---|---|
committer | Guillaume Pasquet <dev@etenil.net> | 2021-11-14 22:50:17 +0000 |
commit | c9486ece952d2e07a78192a9ae0e7764fdee4164 (patch) | |
tree | 1fd086959e4fc7cbe52a1228acfa1b62cc26ac38 | |
parent | fce52576205ebbb6b03a466b8f9a137c45420fde (diff) |
First working version of the barbfile parser
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Cargo.lock | 357 | ||||
-rw-r--r-- | Cargo.toml | 9 | ||||
-rw-r--r-- | src/barbfile.rs | 168 | ||||
-rw-r--r-- | src/main.rs | 9 |
5 files changed, 544 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..1260a1c --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,357 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "barb" +version = "0.1.0" +dependencies = [ + "ureq", +] + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "bumpalo" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" + +[[package]] +name = "cc" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chunked_transfer" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e" + +[[package]] +name = "form_urlencoded" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "js-sys" +version = "0.3.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4bf49d50e2961077d9c99f4b7997d770a1114f087c3c2e0069b36c13fc2979d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1fa8cddc8fbbee11227ef194b5317ed014b8acbf15139bd716a18ad3fe99ec5" + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" + +[[package]] +name = "once_cell" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "proc-macro2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "rustls" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" +dependencies = [ + "base64", + "log", + "ring", + "sct", + "webpki", +] + +[[package]] +name = "sct" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "syn" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "tinyvec" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "unicode-bidi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "246f4c42e67e7a4e3c6106ff716a5d067d4132a642840b242e357e468a2a0085" + +[[package]] +name = "unicode-normalization" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "ureq" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3131cd6cb18488da91da1d10ed31e966f453c06b65bf010d35638456976a3fd7" +dependencies = [ + "base64", + "chunked_transfer", + "log", + "once_cell", + "rustls", + "url", + "webpki", + "webpki-roots", +] + +[[package]] +name = "url" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +dependencies = [ + "form_urlencoded", + "idna", + "matches", + "percent-encoding", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce9b1b516211d33767048e5d47fa2a381ed8b76fc48d2ce4aa39877f9f183e0" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe8dc78e2326ba5f845f4b5bf548401604fa20b1dd1d365fb73b6c1d6364041" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44468aa53335841d9d6b6c023eaab07c0cd4bddbcfdee3e2bb1e8d2cb8069fef" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0195807922713af1e67dc66132c7328206ed9766af3858164fb583eedc25fbad" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdb075a845574a1fa5f09fd77e43f7747599301ea3417a9fbffdeedfc1f4a29" + +[[package]] +name = "web-sys" +version = "0.3.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224b2f6b67919060055ef1a67807367c2066ed520c3862cc013d26cf893a783c" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" +dependencies = [ + "webpki", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..ab00200 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "barb" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +ureq = "2.2.0" diff --git a/src/barbfile.rs b/src/barbfile.rs new file mode 100644 index 0000000..be7cead --- /dev/null +++ b/src/barbfile.rs @@ -0,0 +1,168 @@ +use std::matches; +use std::str::FromStr; +use std::{error::Error, fmt}; + +#[derive(Debug)] +struct BarbParseError {} + +impl Error for BarbParseError {} + +impl fmt::Display for BarbParseError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Error parsing barb file") + } +} + +enum Method { + GET, + PUT, + POST, + PATCH, + DELETE, +} + +impl FromStr for Method { + type Err = BarbParseError; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + match s { + "GET" => Ok(Self::GET), + "PUT" => Ok(Self::PUT), + "POST" => Ok(Self::POST), + "PATCH" => Ok(Self::PATCH), + "DELETE" => Ok(Self::DELETE), + _ => Err(BarbParseError {}), + } + } +} + +#[derive(Debug)] +struct Header { + name: String, + value: String, +} + +impl fmt::Display for Header { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}: {}", self.name, self.value) + } +} + +struct BarbHeader { + pub method: Method, + pub url: String, + pub headers: Vec<Header>, + pub filter: Option<String>, +} + +impl BarbHeader { + fn new(method: Method, url: String, headers: Vec<Header>, filter: Option<String>) -> Self { + BarbHeader { + method: method, + url: url, + headers: headers, + filter: filter, + } + } +} + +struct BarbFile { + header: BarbHeader, + body: Option<String>, +} + +fn decode_url_line(line: &str) -> Result<(Method, String), BarbParseError> { + let mut components = line[1..].split('^'); + let meth = components.next().ok_or(BarbParseError {})?; + let url = components.next().ok_or(BarbParseError {})?; + return Ok((Method::from_str(meth)?, String::from(url))); +} + +fn decode_header(line: &str) -> Result<Header, BarbParseError> { + let mut components = line[1..].split(':'); + let header_name = components.next().ok_or(BarbParseError {})?; + let header_val = components.next().ok_or(BarbParseError {})?.trim(); + Ok(Header { + name: String::from(header_name), + value: String::from(header_val), + }) +} + +impl FromStr for BarbFile { + type Err = BarbParseError; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + let mut lines = s.split('\n'); + let (method, url) = decode_url_line(lines.next().ok_or(BarbParseError {})?)?; + let mut headers: Vec<Header> = vec![]; + let mut filter = None; + for line in lines { + if !matches!(line.chars().nth(0), Some('#')) { + break; // Reached the end of the header. + } + + if let Some(_) = line.find(':') { + headers.push(decode_header(line).unwrap()); + } + + if let None = filter { + filter = match &line[0..2] { + "#|" => Some(String::from(&line[2..])), + _ => None, + } + } + } + + Ok(BarbFile { + header: BarbHeader::new(method, url, headers, filter), + body: None, + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_method_from_str() { + assert!(matches!(Method::from_str("GET").unwrap(), Method::GET)); + assert!(matches!(Method::from_str("GET").unwrap(), Method::GET)); + assert!(matches!(Method::from_str("PUT").unwrap(), Method::PUT)); + assert!(matches!(Method::from_str("POST").unwrap(), Method::POST)); + assert!(matches!(Method::from_str("PATCH").unwrap(), Method::PATCH)); + assert!(matches!( + Method::from_str("DELETE").unwrap(), + Method::DELETE + )); + } + + #[test] + fn test_decode_url_line() { + let (method, url) = decode_url_line("#GET^http://blahblah").unwrap(); + assert!(matches!(method, Method::GET)); + assert_eq!(url, "http://blahblah"); + } + + #[test] + fn test_decode_header() { + let hdr = decode_header("#Authorization: TOKEN 12345").unwrap(); + assert_eq!(hdr.name, "Authorization"); + assert_eq!(hdr.value, "TOKEN 12345"); + } + + #[test] + fn test_parse_barbfile() { + let barbfile = + BarbFile::from_str("#GET^https://blah.com/api/blah\n#Authorization: BLAH\n#|filtr\n") + .unwrap(); + assert_eq!(barbfile.body, None); + assert!(matches!(barbfile.header.method, Method::GET)); + assert_eq!(barbfile.header.url, "https://blah.com/api/blah"); + assert_eq!(barbfile.header.filter, Some(String::from("filtr"))); + println!("{:?}", barbfile.header.headers); + assert_eq!(barbfile.header.headers.len(), 1); + assert_eq!(barbfile.header.headers[0].name, "Authorization"); + assert_eq!(barbfile.header.headers[0].value, "BLAH"); + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..816bebc --- /dev/null +++ b/src/main.rs @@ -0,0 +1,9 @@ +mod barbfile; + +use std::fs; +use ureq; + +fn main() { + let barbfile = fs::read_to_string("test.barb").expect("Failed to read file"); + ureq::get("https://api.met.no/weatherapi/tafmetar/1.0/tafmetar?icao=EGKK"); +} |