about summary refs log tree commit diff
path: root/web/atward/src
diff options
context:
space:
mode:
Diffstat (limited to 'web/atward/src')
-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 0000000000..01e0ac0464
--- /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,);
+    }
+}