use serde::{Deserialize, Serialize};
use skyzen::{
extract::Path,
routing::{CreateRouteNode, Route, Router},
utils::Json,
Result as SkyResult, ToSchema,
};
use skyzen_services::{Kv, Storage};
use skyzen_test::mock::{InMemoryKv, InMemoryStorage};
#[derive(Debug, Serialize, Deserialize, ToSchema)]
struct FileMetadata {
name: String,
size: usize,
}
#[derive(Debug, Deserialize, ToSchema)]
struct UploadRequest {
name: String,
content: String,
}
async fn list_files(kv: Kv) -> SkyResult<Json<Vec<String>>> {
let keys = kv.list_all(Some("file:")).await?;
Ok(Json(keys))
}
async fn get_file(kv: Kv, Path(name): Path<String>) -> SkyResult<Json<Option<FileMetadata>>> {
let meta = kv.get_json::<FileMetadata>(&format!("file:{name}")).await?;
Ok(Json(meta))
}
async fn upload_file(
kv: Kv,
storage: Storage,
Json(body): Json<UploadRequest>,
) -> SkyResult<&'static str> {
let data = body.content.into_bytes();
let meta = FileMetadata {
name: body.name.clone(),
size: data.len(),
};
storage.put(&body.name, data).await?;
kv.put_json(&format!("file:{}", body.name), &meta).await?;
Ok("uploaded")
}
fn build_router(kv: Kv, storage: Storage) -> Router {
Route::new((
"/files".at(list_files),
"/files".post(upload_file),
"/files".route(("/{name}".at(get_file),)),
))
.with(kv)
.with(storage)
.build()
}
#[skyzen::main]
fn main() -> Router {
let kv = Kv::new(InMemoryKv::new());
let storage = Storage::new(InMemoryStorage::new());
build_router(kv, storage)
}