Compare commits
No commits in common. "5a122371da9023df122cec749aac43bff8984f65" and "776d5ead9bcb3e196dbae183856275d672a12934" have entirely different histories.
5a122371da
...
776d5ead9b
5 changed files with 3 additions and 272 deletions
24
Cargo.lock
generated
24
Cargo.lock
generated
|
@ -395,7 +395,6 @@ dependencies = [
|
||||||
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"simple_logger 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"simple_logger 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1280,14 +1279,6 @@ name = "regex-syntax"
|
||||||
version = "0.6.12"
|
version = "0.6.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "remove_dir_all"
|
|
||||||
version = "0.5.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "resolv-conf"
|
name = "resolv-conf"
|
||||||
version = "0.6.2"
|
version = "0.6.2"
|
||||||
|
@ -1452,19 +1443,6 @@ dependencies = [
|
||||||
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tempfile"
|
|
||||||
version = "3.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "term_size"
|
name = "term_size"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
|
@ -1868,7 +1846,6 @@ dependencies = [
|
||||||
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
|
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
|
||||||
"checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd"
|
"checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd"
|
||||||
"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
|
"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
|
||||||
"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
|
|
||||||
"checksum resolv-conf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b263b4aa1b5de9ffc0054a2386f96992058bb6870aab516f8cdeb8a667d56dcb"
|
"checksum resolv-conf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b263b4aa1b5de9ffc0054a2386f96992058bb6870aab516f8cdeb8a667d56dcb"
|
||||||
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
|
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
|
||||||
"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
|
"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
|
||||||
|
@ -1889,7 +1866,6 @@ dependencies = [
|
||||||
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||||
"checksum syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238"
|
"checksum syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238"
|
||||||
"checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545"
|
"checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545"
|
||||||
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
|
|
||||||
"checksum term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e5b9a66db815dcfd2da92db471106457082577c3c278d4138ab3e3b4e189327"
|
"checksum term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e5b9a66db815dcfd2da92db471106457082577c3c278d4138ab3e3b4e189327"
|
||||||
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||||
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
||||||
|
|
|
@ -21,8 +21,5 @@ log = "0.4"
|
||||||
simple_logger = "1.3"
|
simple_logger = "1.3"
|
||||||
clap = { version = "2.33", features = ["yaml", "wrap_help"] }
|
clap = { version = "2.33", features = ["yaml", "wrap_help"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
tempfile = "3.1"
|
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = true
|
lto = true
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use std::error::Error;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -10,8 +9,6 @@ pub enum BunBunError {
|
||||||
LoggerInitError(log::SetLoggerError),
|
LoggerInitError(log::SetLoggerError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error for BunBunError {}
|
|
||||||
|
|
||||||
impl fmt::Display for BunBunError {
|
impl fmt::Display for BunBunError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
|
178
src/main.rs
178
src/main.rs
|
@ -1,5 +1,3 @@
|
||||||
#![forbid(unsafe_code)]
|
|
||||||
|
|
||||||
use actix_web::{middleware::Logger, App, HttpServer};
|
use actix_web::{middleware::Logger, App, HttpServer};
|
||||||
use clap::{crate_authors, crate_version, load_yaml, App as ClapApp};
|
use clap::{crate_authors, crate_version, load_yaml, App as ClapApp};
|
||||||
use error::BunBunError;
|
use error::BunBunError;
|
||||||
|
@ -97,7 +95,7 @@ fn init_logger(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, PartialEq)]
|
#[derive(Deserialize)]
|
||||||
struct Config {
|
struct Config {
|
||||||
bind_address: String,
|
bind_address: String,
|
||||||
public_address: String,
|
public_address: String,
|
||||||
|
@ -105,7 +103,7 @@ struct Config {
|
||||||
groups: Vec<RouteGroup>,
|
groups: Vec<RouteGroup>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug, PartialEq, Clone)]
|
#[derive(Deserialize, Serialize)]
|
||||||
struct RouteGroup {
|
struct RouteGroup {
|
||||||
name: String,
|
name: String,
|
||||||
description: Option<String>,
|
description: Option<String>,
|
||||||
|
@ -236,175 +234,3 @@ fn start_watch(
|
||||||
|
|
||||||
Ok(watch)
|
Ok(watch)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod init_logger {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn defaults_to_warn() -> Result<(), BunBunError> {
|
|
||||||
init_logger(0, 0)?;
|
|
||||||
assert_eq!(log::max_level(), log::Level::Warn);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[ignore]
|
|
||||||
fn caps_to_2_when_log_level_is_lt_2() -> Result<(), BunBunError> {
|
|
||||||
init_logger(0, 3)?;
|
|
||||||
assert_eq!(log::max_level(), log::LevelFilter::Off);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[ignore]
|
|
||||||
fn caps_to_3_when_log_level_is_gt_3() -> Result<(), BunBunError> {
|
|
||||||
init_logger(4, 0)?;
|
|
||||||
assert_eq!(log::max_level(), log::Level::Trace);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod read_config {
|
|
||||||
use super::*;
|
|
||||||
use tempfile::NamedTempFile;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn returns_default_config_if_path_does_not_exist() {
|
|
||||||
assert_eq!(
|
|
||||||
read_config("/this_is_a_non_existent_file").unwrap(),
|
|
||||||
serde_yaml::from_slice(DEFAULT_CONFIG).unwrap()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn returns_error_if_given_empty_config() {
|
|
||||||
assert_eq!(
|
|
||||||
read_config("/dev/null").unwrap_err().to_string(),
|
|
||||||
"EOF while parsing a value"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn returns_error_if_given_invalid_config() -> Result<(), std::io::Error> {
|
|
||||||
let mut tmp_file = NamedTempFile::new()?;
|
|
||||||
tmp_file.write_all(b"g")?;
|
|
||||||
assert_eq!(
|
|
||||||
read_config(tmp_file.path().to_str().unwrap())
|
|
||||||
.unwrap_err()
|
|
||||||
.to_string(),
|
|
||||||
r#"invalid type: string "g", expected struct Config at line 1 column 1"#
|
|
||||||
);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn returns_error_if_config_missing_field() -> Result<(), std::io::Error> {
|
|
||||||
let mut tmp_file = NamedTempFile::new()?;
|
|
||||||
tmp_file.write_all(
|
|
||||||
br#"
|
|
||||||
bind_address: "localhost"
|
|
||||||
public_address: "localhost"
|
|
||||||
"#,
|
|
||||||
)?;
|
|
||||||
assert_eq!(
|
|
||||||
read_config(tmp_file.path().to_str().unwrap())
|
|
||||||
.unwrap_err()
|
|
||||||
.to_string(),
|
|
||||||
"missing field `groups` at line 2 column 19"
|
|
||||||
);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn returns_ok_if_valid_config() -> Result<(), std::io::Error> {
|
|
||||||
let mut tmp_file = NamedTempFile::new()?;
|
|
||||||
tmp_file.write_all(
|
|
||||||
br#"
|
|
||||||
bind_address: "a"
|
|
||||||
public_address: "b"
|
|
||||||
groups: []"#,
|
|
||||||
)?;
|
|
||||||
assert_eq!(
|
|
||||||
read_config(tmp_file.path().to_str().unwrap()).unwrap(),
|
|
||||||
Config {
|
|
||||||
bind_address: String::from("a"),
|
|
||||||
public_address: String::from("b"),
|
|
||||||
groups: vec![],
|
|
||||||
default_route: None,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod cache_routes {
|
|
||||||
use super::*;
|
|
||||||
use std::iter::FromIterator;
|
|
||||||
|
|
||||||
fn generate_routes(routes: &[(&str, &str)]) -> HashMap<String, String> {
|
|
||||||
HashMap::from_iter(
|
|
||||||
routes
|
|
||||||
.iter()
|
|
||||||
.map(|(k, v)| (String::from(*k), String::from(*v))),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn empty_groups_yield_empty_routes() {
|
|
||||||
assert_eq!(cache_routes(&[]), HashMap::new());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn disjoint_groups_yield_summed_routes() {
|
|
||||||
let group1 = RouteGroup {
|
|
||||||
name: String::from("x"),
|
|
||||||
description: Some(String::from("y")),
|
|
||||||
routes: generate_routes(&[("a", "b"), ("c", "d")]),
|
|
||||||
};
|
|
||||||
|
|
||||||
let group2 = RouteGroup {
|
|
||||||
name: String::from("5"),
|
|
||||||
description: Some(String::from("6")),
|
|
||||||
routes: generate_routes(&[("1", "2"), ("3", "4")]),
|
|
||||||
};
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
cache_routes(&[group1, group2]),
|
|
||||||
generate_routes(&[("a", "b"), ("c", "d"), ("1", "2"), ("3", "4")])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn overlapping_groups_use_latter_routes() {
|
|
||||||
let group1 = RouteGroup {
|
|
||||||
name: String::from("x"),
|
|
||||||
description: Some(String::from("y")),
|
|
||||||
routes: generate_routes(&[("a", "b"), ("c", "d")]),
|
|
||||||
};
|
|
||||||
|
|
||||||
let group2 = RouteGroup {
|
|
||||||
name: String::from("5"),
|
|
||||||
description: Some(String::from("6")),
|
|
||||||
routes: generate_routes(&[("a", "1"), ("c", "2")]),
|
|
||||||
};
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
cache_routes(&[group1.clone(), group2]),
|
|
||||||
generate_routes(&[("a", "1"), ("c", "2")])
|
|
||||||
);
|
|
||||||
|
|
||||||
let group3 = RouteGroup {
|
|
||||||
name: String::from("5"),
|
|
||||||
description: Some(String::from("6")),
|
|
||||||
routes: generate_routes(&[("a", "1"), ("b", "2")]),
|
|
||||||
};
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
cache_routes(&[group1, group3]),
|
|
||||||
generate_routes(&[("a", "1"), ("b", "2"), ("c", "d")])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -112,10 +112,7 @@ fn resolve_hop(
|
||||||
(None, Some(route)) => {
|
(None, Some(route)) => {
|
||||||
let args = split_args.join(" ");
|
let args = split_args.join(" ");
|
||||||
debug!("Using default route {} with args {}", route, args);
|
debug!("Using default route {} with args {}", route, args);
|
||||||
match routes.get(route) {
|
(routes.get(route).cloned(), args)
|
||||||
Some(v) => (Some(v.to_owned()), args),
|
|
||||||
None => (None, String::new()),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// No default route and no match
|
// No default route and no match
|
||||||
(None, None) => {
|
(None, None) => {
|
||||||
|
@ -159,65 +156,3 @@ pub async fn opensearch(data: StateData, req: HttpRequest) -> impl Responder {
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod resolve_hop {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
fn generate_route_result(
|
|
||||||
keyword: &str,
|
|
||||||
args: &str,
|
|
||||||
) -> (Option<String>, String) {
|
|
||||||
(Some(String::from(keyword)), String::from(args))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn empty_routes_no_default_yields_failed_hop() {
|
|
||||||
assert_eq!(
|
|
||||||
resolve_hop("hello world", &HashMap::new(), &None),
|
|
||||||
(None, String::new())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn empty_routes_some_default_yields_failed_hop() {
|
|
||||||
assert_eq!(
|
|
||||||
resolve_hop(
|
|
||||||
"hello world",
|
|
||||||
&HashMap::new(),
|
|
||||||
&Some(String::from("google"))
|
|
||||||
),
|
|
||||||
(None, String::new())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn only_default_routes_some_default_yields_default_hop() {
|
|
||||||
let mut map = HashMap::new();
|
|
||||||
map.insert(String::from("google"), String::from("https://example.com"));
|
|
||||||
assert_eq!(
|
|
||||||
resolve_hop("hello world", &map, &Some(String::from("google"))),
|
|
||||||
generate_route_result("https://example.com", "hello world"),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn non_default_routes_some_default_yields_non_default_hop() {
|
|
||||||
let mut map = HashMap::new();
|
|
||||||
map.insert(String::from("google"), String::from("https://example.com"));
|
|
||||||
assert_eq!(
|
|
||||||
resolve_hop("google hello world", &map, &Some(String::from("a"))),
|
|
||||||
generate_route_result("https://example.com", "hello world"),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn non_default_routes_no_default_yields_non_default_hop() {
|
|
||||||
let mut map = HashMap::new();
|
|
||||||
map.insert(String::from("google"), String::from("https://example.com"));
|
|
||||||
assert_eq!(
|
|
||||||
resolve_hop("google hello world", &map, &None),
|
|
||||||
generate_route_result("https://example.com", "hello world"),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue