summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs85
1 files changed, 85 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..3b8e2d0
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,85 @@
+use actix_web::{get, web, App, HttpResponse, HttpServer, Responder};
+use anyhow::Result;
+use rand::seq::SliceRandom;
+use serde::Deserialize;
+
+#[derive(Debug, Clone)]
+struct Config {
+ search_engines: Vec<Engine>,
+}
+
+impl Config {
+ fn load_from<R: std::io::Read>(reader: R) -> Result<Self> {
+ let mut rdr = csv::ReaderBuilder::new()
+ .trim(csv::Trim::All)
+ .from_reader(reader);
+
+ let mut conf = Self {
+ search_engines: vec![],
+ };
+ for result in rdr.deserialize() {
+ let record: Engine = result?;
+ conf.search_engines.push(record);
+ }
+
+ Ok(conf)
+ }
+}
+
+#[derive(Deserialize, Debug, Clone)]
+struct Engine {
+ #[serde(rename = "NAME")]
+ name: String,
+ #[serde(rename = "SHORT")]
+ short: String,
+ #[serde(rename = "URL")]
+ url: String,
+ #[serde(rename = "GENERAL")]
+ general: bool,
+ #[serde(rename = "PRIORITY")]
+ priority: usize,
+}
+
+#[get("/search/{query}")]
+async fn search(config: web::Data<Config>, web::Path(query): web::Path<String>) -> impl Responder {
+ if query.starts_with('!') {
+ let mut split = query.split('+');
+ let short = split.next();
+ if let Some(short) = short {
+ let query = split.collect::<Vec<&str>>().join(" ");
+
+ let mut url: &str = "";
+ for se in &config.search_engines {
+ if se.short == short {
+ url = &se.url;
+ }
+ println!("hi");
+ }
+ return HttpResponse::Found()
+ .header("Location", url.replace("%s", &query))
+ .finish();
+ }
+ } else {
+ let general: Vec<&Engine> = config
+ .search_engines
+ .iter()
+ .filter(|se| se.general)
+ .collect();
+ let engine = general.choose(&mut rand::thread_rng()).unwrap();
+ return HttpResponse::Found()
+ .header("Location", engine.url.replace("%s", &query))
+ .finish();
+ }
+ HttpResponse::BadRequest().finish()
+}
+
+#[actix_web::main]
+async fn main() -> std::io::Result<()> {
+ let f = std::fs::File::open("search_engines.csv").unwrap();
+ let config = Config::load_from(f).unwrap();
+
+ HttpServer::new(move || App::new().data(config.clone()).service(search))
+ .bind("127.0.0.1:5005")?
+ .run()
+ .await
+}