about summary refs log tree commit diff
path: root/web/atward/src/main.rs
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2021-05-03T21·31+0200
committertazjin <mail@tazj.in>2021-05-03T22·55+0000
commit51b5475f40111d0a084b3ede6eec77d28b375536 (patch)
treecf28c7c2d53b755b41d5ee50a5bf1fd7285979fd /web/atward/src/main.rs
parent35aa79d14b2f4032efd79cda2c25b11540768107 (diff)
feat(web/atward): Implement match scaffolding for TVL redirector r/2559
atward is going to be a new TVL service, living at atward.tvl.fyi,
which users can configure as a search engine in their browser.

It will understand a variety of TVL-specific query types (such as
bug/CL links or code paths). In the future it might also support
features like go-links.

This commit configures the initial setup for query matchers in atward
and adds an example query type (for bugs).

This is not yet wired up to a web server.

Change-Id: Ifaf06c3f5cc378eee7894b7576ef583fc89264f0
Reviewed-on: https://cl.tvl.fyi/c/depot/+/3087
Tested-by: BuildkiteCI
Reviewed-by: isomer <isomer@tvl.fyi>
Diffstat (limited to 'web/atward/src/main.rs')
-rw-r--r--web/atward/src/main.rs67
1 files changed, 67 insertions, 0 deletions
diff --git a/web/atward/src/main.rs b/web/atward/src/main.rs
new file mode 100644
index 000000000000..01e0ac046482
--- /dev/null
+++ b/web/atward/src/main.rs
@@ -0,0 +1,67 @@
+//! Atward implements TVL's redirection service, living at
+//! atward.tvl.fyi
+//!
+//! This service is designed to be added as a search engine to web
+//! browsers and attempts to send users to useful locations based on
+//! their search query (falling back to another search engine).
+use regex::Regex;
+
+/// A query type supported by atward. It consists of a pattern on
+/// which to match and trigger the query, and a function to execute
+/// that returns the target URL.
+struct Query {
+    /// Regular expression on which to match the query string.
+    pattern: Regex,
+
+    /// Function to construct the target URL. If the pattern matches,
+    /// this is invoked with the captured matches and the entire URI.
+    ///
+    /// 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<String>,
+}
+
+/// Definition of all supported queries in atward.
+fn queries() -> Vec<Query> {
+    vec![
+        // Bug IDs (e.g. b/123)
+        Query {
+            pattern: Regex::new("^b/(?P<bug>\\d+)$").unwrap(),
+            target: |_, captures| Some(format!("https://b.tvl.fyi/{}", &captures["bug"])),
+        },
+    ]
+}
+
+/// Attempt to match against all known query types, and return the
+/// destination URL if one is found.
+fn dispatch(queries: &[Query], uri: &str) -> Option<String> {
+    for query in queries {
+        if let Some(captures) = query.pattern.captures(uri) {
+            if let Some(destination) = (query.target)(uri, captures) {
+                return Some(destination);
+            }
+        }
+    }
+
+    None
+}
+
+fn main() {
+    println!("Hello, world!");
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn bug_query() {
+        assert_eq!(
+            dispatch(&queries(), "b/42"),
+            Some("https://b.tvl.fyi/42".to_string())
+        );
+
+        assert_eq!(dispatch(&queries(), "something only mentioning b/42"), None,);
+        assert_eq!(dispatch(&queries(), "b/invalid"), None,);
+    }
+}