picox/src/main.rs

94 lines
2.5 KiB
Rust
Raw Normal View History

mod api;
mod model;
mod storage_manager;
mod config;
mod state;
use std::path::PathBuf;
use std::sync::Arc;
use axum::{Json, Router};
use axum::extract::{Path, Query, State};
use axum::http::StatusCode;
use axum::response::IntoResponse;
use axum::routing::{get, post};
use axum_macros::debug_handler;
use j_db::database::Database;
use serde::{Deserialize, Serialize};
use structopt::StructOpt;
use log::info;
use crate::config::PicOxConfig;
use crate::model::album::Album;
use crate::state::Context;
#[derive(Debug, Clone, StructOpt)]
struct Args {
config: PathBuf
}
#[derive(Debug, Clone, Serialize, Deserialize)]
struct CreateAlbum {
pub album_name: String
}
async fn create_album(State(context): State<Arc<Context>>, Json(album): Json<CreateAlbum>) -> impl IntoResponse {
info!("Creating new album '{}'", album.album_name);
let new_album = Album::new(&album.album_name, Vec::new(), 0);
let new_album = context.db.insert(new_album).unwrap();
(StatusCode::OK, Json(new_album))
}
async fn get_album(album_id: Path<u64>, State(context): State<Arc<Context>>) -> impl IntoResponse {
let album = context.db.get::<Album>(*album_id).unwrap();
(StatusCode::OK, Json(album))
}
#[derive(Debug, Clone, Serialize, Deserialize)]
struct AlbumQuery {
pub album_name: Option<String>
}
async fn query_album(album_query: Query<AlbumQuery>, State(context): State<Arc<Context>>) -> impl IntoResponse {
let resp = if let Some(album_name) = &album_query.album_name {
context.db.filter(|_, album: &Album| {album.album_name == *album_name}).unwrap().next() }
else {
None
};
(StatusCode::OK, Json(resp))
}
#[tokio::main]
async fn main() {
let args = Args::from_args();
let config = PicOxConfig::new(args.config);
let db = Database::new(&config.db_path).unwrap();
let context = Context {
db,
config,
};
let context = Arc::new(context);
// initialize tracing
tracing_subscriber::fmt::init();
// build our application with a route
let app = Router::new()
// `GET /` goes to `root`
.route("/api/album/create", post(create_album))
.route("/api/album/:id", get(get_album))
.route("/api/album/", get(query_album))
.with_state(context.clone());
// run our app with hyper, listening globally on port 3000
let listener = tokio::net::TcpListener::bind(&context.config.host).await.unwrap();
info!("Serving at {}", context.config.host);
axum::serve(listener, app).await.unwrap();
}