diff options
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 85 |
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 +} |