From c502f1da490a8199a7ca6443e27c00ba775a4d50 Mon Sep 17 00:00:00 2001 From: Alex Wellnitz Date: Mon, 12 Feb 2024 21:45:27 +0100 Subject: [PATCH] feat: add api functions and actix webserver --- src/handler/hello.rs | 3 --- src/handler/search.rs | 17 ------------- src/handlers/hello.rs | 15 +++++++++++ src/handlers/mod.rs | 2 ++ src/handlers/search.rs | 20 +++++++++++++++ src/lib.rs | 3 ++- src/main.rs | 56 +++++++++++++++++++++++++++++------------- src/search/engine.rs | 1 + src/types/app_state.rs | 7 ++++++ src/types/mod.rs | 1 + 10 files changed, 87 insertions(+), 38 deletions(-) delete mode 100644 src/handler/hello.rs delete mode 100644 src/handler/search.rs create mode 100644 src/handlers/hello.rs create mode 100644 src/handlers/mod.rs create mode 100644 src/handlers/search.rs create mode 100644 src/types/app_state.rs create mode 100644 src/types/mod.rs diff --git a/src/handler/hello.rs b/src/handler/hello.rs deleted file mode 100644 index bd673cf..0000000 --- a/src/handler/hello.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub async fn say_hello() -> &'static str { - "Hello, World!" -} \ No newline at end of file diff --git a/src/handler/search.rs b/src/handler/search.rs deleted file mode 100644 index 57691f3..0000000 --- a/src/handler/search.rs +++ /dev/null @@ -1,17 +0,0 @@ -use axum:: - Json -; -use serde::Deserialize; - -use crate::search::engine::SearchEngine; - -pub fn index_new_document(mut engine: SearchEngine, Json(payload): Json) { - engine.index(&payload.url, &payload.content); -} - -// the input to our `create_user` handler -#[derive(Deserialize)] -pub struct IndexNewDocument { - url: String, - content: String, -} \ No newline at end of file diff --git a/src/handlers/hello.rs b/src/handlers/hello.rs new file mode 100644 index 0000000..35c8068 --- /dev/null +++ b/src/handlers/hello.rs @@ -0,0 +1,15 @@ +use actix_web::{get, post, HttpResponse, Responder}; + +#[get("/")] +pub async fn say_hello() -> impl Responder { + HttpResponse::Ok().body("Hello world!") +} + +#[post("/echo")] +pub async fn echo(req_body: String) -> impl Responder { + HttpResponse::Ok().body(req_body) +} + +pub async fn manual_hello() -> impl Responder { + HttpResponse::Ok().body("Hey there!") +} \ No newline at end of file diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs new file mode 100644 index 0000000..98f7555 --- /dev/null +++ b/src/handlers/mod.rs @@ -0,0 +1,2 @@ +pub mod hello; +pub mod search; \ No newline at end of file diff --git a/src/handlers/search.rs b/src/handlers/search.rs new file mode 100644 index 0000000..a143da0 --- /dev/null +++ b/src/handlers/search.rs @@ -0,0 +1,20 @@ +use actix_web::{web, HttpResponse, Responder}; +use serde::Deserialize; + +use crate::types::app_state::AppStateWithSearchEngine; + +#[derive(Deserialize)] +pub struct AddDocumentRequest { + url: String, + content: String, +} + +pub async fn add_document_to_index(data: web::Data, req: web::Json) -> impl Responder { + data.search_engine.lock().unwrap().index(&req.url, &req.content); + HttpResponse::Created().body("Document added to index!") +} + +pub async fn get_number_of_documents(data: web::Data) -> impl Responder { + let number_of_documents = data.search_engine.lock().unwrap().number_of_documents(); + HttpResponse::Ok().body(format!("Number of documents: {}", number_of_documents)) +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 10770cb..7d7886c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,3 @@ pub mod search; -pub mod handler; \ No newline at end of file +pub mod handlers; +pub mod types; \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index a725ec6..9355ab3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,23 +1,45 @@ -use axum::{routing::get, Router}; +use std::sync::Mutex; -use rustysearch::search::engine::SearchEngine; +use actix_web::{middleware::Logger, web, App, HttpServer}; +use env_logger::Env; -#[tokio::main] -async fn main() { - // initialize tracing - tracing_subscriber::fmt::init(); +use rustysearch::{ + handlers::{hello, search}, + search::engine::SearchEngine, + types::app_state::AppStateWithSearchEngine, +}; - // initialize our search engine - let mut search_engine = SearchEngine::new(1.5, 0.75); - search_engine.index("https://www.rust-lang.org/", "Rust Programming Language"); +#[actix_web::main] +async fn main() -> std::io::Result<()> { + // Initialize logger + env_logger::init_from_env(Env::default().default_filter_or("debug")); - // build our application with a route - let app = Router::new() - // `GET /` goes to `root` - .route("/", get(rustysearch::handler::hello::say_hello)); - // .route("/search/add", post(rustysearch::handler::search::index_new_document)); + let search_engine = SearchEngine::new(1.5, 0.75); - // run our app with hyper, listening globally on port 3000 - let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(); - axum::serve(listener, app).await.unwrap(); + let app_state = web::Data::new(AppStateWithSearchEngine { + search_engine: Mutex::new(search_engine.clone()), + }); + + HttpServer::new(move || { + App::new() + // Inject the search engine into the application state + .app_data(app_state.clone()) + // enable logger + .wrap(Logger::default()) + .service(hello::say_hello) + .service(hello::echo) + .route("/hey", web::get().to(hello::manual_hello)) + // Search Routes + .route( + "/search/index/document", + web::post().to(search::add_document_to_index), + ) + .route( + "/search/index/number_of_documents", + web::get().to(search::get_number_of_documents), + ) + }) + .bind(("127.0.0.1", 8080))? + .run() + .await } diff --git a/src/search/engine.rs b/src/search/engine.rs index a7b600f..d3289ac 100644 --- a/src/search/engine.rs +++ b/src/search/engine.rs @@ -13,6 +13,7 @@ pub fn normalize_string(input_string: &str) -> String { string_without_double_spaces.to_lowercase() } +#[derive(Default, Debug, Clone)] pub struct SearchEngine { index: HashMap>, documents: HashMap, diff --git a/src/types/app_state.rs b/src/types/app_state.rs new file mode 100644 index 0000000..fa99c8f --- /dev/null +++ b/src/types/app_state.rs @@ -0,0 +1,7 @@ +use std::sync::Mutex; + +use crate::search::engine::SearchEngine; + +pub struct AppStateWithSearchEngine { + pub search_engine: Mutex, // <- Mutex is necessary to mutate safely across threads +} \ No newline at end of file diff --git a/src/types/mod.rs b/src/types/mod.rs new file mode 100644 index 0000000..14c3110 --- /dev/null +++ b/src/types/mod.rs @@ -0,0 +1 @@ +pub mod app_state; \ No newline at end of file