From d4bdfe8127f9a54bb9a15b6c278267bb725e3457 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Thu, 6 May 2021 16:11:45 +0200 Subject: refactor(atward): Construct an atward query type from user requests Rather than dealing with passing down the rouille request to handlers (which would have become necessary as we start supporting more user-controlled features), a new `atward::Query` type is constructed from requests and passed to the dispatching logic instead. For now this introduces no new features, it just shuffles things around to prepare for that. Change-Id: I08e18422c1fdbac4712c739a7acbb810ada697ca Reviewed-on: https://cl.tvl.fyi/c/depot/+/3101 Tested-by: BuildkiteCI Reviewed-by: tazjin --- web/atward/src/main.rs | 59 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/web/atward/src/main.rs b/web/atward/src/main.rs index 9dd2a38fbc62..400e77341650 100644 --- a/web/atward/src/main.rs +++ b/web/atward/src/main.rs @@ -19,7 +19,33 @@ struct Handler { /// /// Returning `None` causes atward to fall through to the next /// query (and eventually to the default search engine). - target: for<'s> fn(&'s str, regex::Captures<'s>) -> Option, + target: for<'s> fn(&Query, regex::Captures<'s>) -> Option, +} + +/// An Atward query supplied by a user. +struct Query { + /// Query string itself. + query: String, +} + +impl Query { + fn from_request(req: &rouille::Request) -> Option { + let query = match req.get_param("q") { + Some(q) => q, + None => return None, + }; + + Some(Query { query }) + } +} + +#[cfg(test)] +impl From<&str> for Query { + fn from(query: &str) -> Query { + Query { + query: query.to_string(), + } + } } /// Create a URL to a file (and, optionally, specific line) in cgit. @@ -55,10 +81,10 @@ fn handlers() -> Vec { /// Attempt to match against all known query types, and return the /// destination URL if one is found. -fn dispatch(queries: &[Handler], uri: &str) -> Option { - for query in queries { - if let Some(captures) = query.pattern.captures(uri) { - if let Some(destination) = (query.target)(uri, captures) { +fn dispatch(handlers: &[Handler], query: &Query) -> Option { + for handler in handlers { + if let Some(captures) = handler.pattern.captures(&query.query) { + if let Some(destination) = (handler.target)(query, captures) { return Some(destination); } } @@ -79,7 +105,7 @@ fn main() { rouille::start_server(&address, move |request| { rouille::log(&request, std::io::stderr(), || { - let query = match request.get_param("q") { + let query = match Query::from_request(&request) { Some(q) => q, None => return fallback(), }; @@ -99,40 +125,43 @@ mod tests { #[test] fn bug_query() { assert_eq!( - dispatch(&handlers(), "b/42"), + dispatch(&handlers(), &"b/42".into()), Some("https://b.tvl.fyi/42".to_string()) ); - assert_eq!(dispatch(&handlers(), "something only mentioning b/42"), None,); - assert_eq!(dispatch(&handlers(), "b/invalid"), None,); + assert_eq!( + dispatch(&handlers(), &"something only mentioning b/42".into()), + None, + ); + assert_eq!(dispatch(&handlers(), &"b/invalid".into()), None,); } #[test] fn cl_query() { assert_eq!( - dispatch(&handlers(), "cl/42"), + dispatch(&handlers(), &"cl/42".into()), Some("https://cl.tvl.fyi/42".to_string()) ); assert_eq!( - dispatch(&handlers(), "something only mentioning cl/42"), + dispatch(&handlers(), &"something only mentioning cl/42".into()), None, ); - assert_eq!(dispatch(&handlers(), "cl/invalid"), None,); + assert_eq!(dispatch(&handlers(), &"cl/invalid".into()), None,); } #[test] fn depot_path_query() { assert_eq!( - dispatch(&handlers(), "//web/atward/default.nix"), + dispatch(&handlers(), &"//web/atward/default.nix".into()), Some("https://code.tvl.fyi/tree/web/atward/default.nix".to_string()), ); assert_eq!( - dispatch(&handlers(), "//nix/readTree/README.md"), + dispatch(&handlers(), &"//nix/readTree/README.md".into()), Some("https://code.tvl.fyi/about/nix/readTree/README.md".to_string()), ); - assert_eq!(dispatch(&handlers(), "/not/a/depot/path"), None); + assert_eq!(dispatch(&handlers(), &"/not/a/depot/path".into()), None); } } -- cgit 1.4.1