From 5a1ff49fe38451451a55266e86a9e9aedecfb44d Mon Sep 17 00:00:00 2001 From: metamuffin Date: Sun, 19 Feb 2023 15:55:34 +0100 Subject: added api --- server/src/routes/api/error.rs | 57 ++++++++++++++++++++++++++++++++++++++++++ server/src/routes/api/mod.rs | 51 +++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 server/src/routes/api/error.rs create mode 100644 server/src/routes/api/mod.rs (limited to 'server/src/routes/api') diff --git a/server/src/routes/api/error.rs b/server/src/routes/api/error.rs new file mode 100644 index 0000000..ef5374c --- /dev/null +++ b/server/src/routes/api/error.rs @@ -0,0 +1,57 @@ +// TODO: Slightâ„¢ code duplication with `ui/error.rs` + +use rocket::{ + response::{self, Responder}, + Request, +}; +use serde_json::{json, Value}; +use std::fmt::Display; + +use crate::routes::ui::error::MyError; + +pub type ApiResult = Result; + +#[derive(Debug)] +pub struct ApiError(pub anyhow::Error); + +impl<'r> Responder<'r, 'static> for ApiError { + fn respond_to(self, req: &'r Request<'_>) -> response::Result<'static> { + json!({ "error": format!("{}", self.0) }).respond_to(req) + } +} + +impl Display for ApiError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} +impl From for ApiError { + fn from(err: anyhow::Error) -> ApiError { + ApiError(err) + } +} +impl From for ApiError { + fn from(err: std::fmt::Error) -> ApiError { + ApiError(anyhow::anyhow!("{err}")) + } +} +impl From for ApiError { + fn from(err: std::io::Error) -> Self { + ApiError(anyhow::anyhow!("{err}")) + } +} +impl From for ApiError { + fn from(err: sled::Error) -> Self { + ApiError(anyhow::anyhow!("{err}")) + } +} +impl From for ApiError { + fn from(err: serde_json::Error) -> Self { + ApiError(anyhow::anyhow!("{err}")) + } +} +impl From for ApiError { + fn from(value: MyError) -> Self { + Self(value.0) + } +} diff --git a/server/src/routes/api/mod.rs b/server/src/routes/api/mod.rs new file mode 100644 index 0000000..5f48873 --- /dev/null +++ b/server/src/routes/api/mod.rs @@ -0,0 +1,51 @@ +pub mod error; + +use std::path::PathBuf; + +use super::ui::account::{login_logic, LoginForm}; +use crate::{ + database::Database, + library::{Library, Node}, + routes::{api::error::ApiResult, ui::account::session::Session}, +}; +use anyhow::Context; +use rocket::{get, http::CookieJar, post, serde::json::Json, State}; +use serde_json::{json, Value}; + +#[get("/api/version")] +pub fn r_api_version() -> &'static str { + "1" +} + +#[post("/api/account/login", data = "")] +pub fn r_api_account_login( + database: &State, + jar: &CookieJar, + data: Json, +) -> ApiResult { + login_logic(jar, database, &data.username, &data.password)?; + Ok(json!({ "ok": true })) +} + +#[get("/api/library/")] +pub fn r_api_library_node( + _sess: Session, + path: PathBuf, + library: &State, +) -> ApiResult { + let node = library + .nested_path(&path) + .context("retrieving library node")?; + + match node.as_ref() { + Node::Directory(d) => Ok(json!({ + "identifier": d.identifier, + "info": d.info, + "children": d.children.iter().map(|c| c.identifier().to_string()).collect::>() + })), + Node::Item(i) => Ok(json!({ + "identifier": i.identifier, + "info": i.info, + })), + } +} -- cgit v1.2.3-70-g09d2