diff --git a/core/src/requests/games.rs b/core/src/requests/games.rs index 77fb6cc..33f6900 100644 --- a/core/src/requests/games.rs +++ b/core/src/requests/games.rs @@ -56,27 +56,25 @@ pub mod search { pub badges: Logic, } + type SortKey = (K, game::Id); + #[data(copy, display(name))] pub enum SortBy { + /// By game id. Simplest possible ordering. + Id { after: Option }, /// By game release date. - ReleaseDate { - after: Option<(time::Date, game::Id)>, - }, - /// Sort by game creation date. - CreatedAt { after: Option }, + ReleaseDate { after: Option> }, /// By publish on site date. - PublishedAt { - after: Option<(time::Date, game::Id)>, - }, + PublishedAt { after: Option> }, /// By game rating. Rating { - after: Option<(game::RatingValue, game::Id)>, + after: Option>, }, } impl Default for SortBy { fn default() -> Self { - Self::CreatedAt { after: None } + Self::Id { after: None } } } diff --git a/core/src/requests/marks.rs b/core/src/requests/marks.rs new file mode 100644 index 0000000..789c7ad --- /dev/null +++ b/core/src/requests/marks.rs @@ -0,0 +1,81 @@ +use crate::{ + errors, + types::{Patch, True, author, entity, file, game}, +}; + +use eva::{array, data, str}; + +#[data] +pub struct TextEntry { + pub id: I, + pub text: str::CompactString, +} + +pub mod add { + use super::*; + + #[data] + pub enum Args { + Tag(str::CompactString), + Badge(str::CompactString), + } + + #[data] + pub struct Ok { + pub id: entity::Id, + } + + #[data(error, display("_"))] + pub enum Err {} +} + +pub mod list_genres { + use super::*; + + pub const MAX: usize = 256; + + #[data] + pub struct Args {} + + #[data] + pub struct Ok { + pub genres: array::ImmutableHeap, + } + + #[data(error, display("_"))] + pub enum Err {} +} + +pub mod list_badges { + use super::*; + + #[data] + pub struct Args { + pub query: str::CompactString, + } + + #[data] + pub struct Ok { + pub badges: Vec>, + } + + #[data(error, display("_"))] + pub enum Err {} +} + +pub mod list_tags { + use super::*; + + #[data] + pub struct Args { + pub query: str::CompactString, + } + + #[data] + pub struct Ok { + pub tags: Vec>, + } + + #[data(error, display("_"))] + pub enum Err {} +} diff --git a/core/src/requests/mod.rs b/core/src/requests/mod.rs index 9819537..fc9760d 100644 --- a/core/src/requests/mod.rs +++ b/core/src/requests/mod.rs @@ -2,6 +2,8 @@ use crate::errors::Generic; pub type Response = Result>; +pub mod marks; + pub mod boards; pub mod messages; pub mod threads; diff --git a/core/src/requests/uploads.rs b/core/src/requests/uploads.rs index ee1576d..fe482e3 100644 --- a/core/src/requests/uploads.rs +++ b/core/src/requests/uploads.rs @@ -1,3 +1,5 @@ +use std::num::NonZeroU64; + use eva::{data, str}; use crate::{ @@ -14,6 +16,7 @@ pub mod start { //! - Concurrent uploads limit - also by bytes //! //! Quotas are applied per-class. + use super::*; #[data] @@ -27,11 +30,11 @@ pub mod start { pub hash: file::Hash, /// Class of the file. - pub class: file::Class, + pub class: file::ClassKind, /// Size of the file to upload. Must be known /// prior to upload, streaming is not supported. - pub size: u64, + pub size: NonZeroU64, } #[data] @@ -51,10 +54,10 @@ pub mod start { pub mod finish { use super::*; - #[data] - pub struct Args { + #[data(not(Debug, serde, schemars, Clone, PartialEq))] + pub struct Args { pub id: upload::Id, - pub stream: S, + pub stream: UploadStream<'static>, } #[data] diff --git a/core/src/service/api_looks.rs b/core/src/service/api_looks.rs new file mode 100644 index 0000000..d80e1e0 --- /dev/null +++ b/core/src/service/api_looks.rs @@ -0,0 +1,32 @@ +use crate::service::IsSession; + +#[derive(Debug, Clone, Copy)] +#[repr(transparent)] +pub struct Session(S); + +impl Session { + pub const fn new(session: S) -> Self { + Self(session) + } +} + +macro_rules! project { + ($(fn $method:ident() -> $($path:ident)::+;)*) => {$( + pub const fn $method(&mut self) -> impl $crate::service::$($path)::* { + &mut self.0 + } + )*}; +} + +#[rustfmt::skip] +impl Session {project!{ + fn users() -> users::Users; + fn authors() -> authors::Authors; + fn games() -> games::Games; + + fn boards() -> boards::Boards; + fn threads() -> threads::Threads; + fn messages() -> messages::Messages; + + fn authz() -> authz::Authentication; +}} diff --git a/core/src/service/authors.rs b/core/src/service/authors.rs index a0f41f7..1b9ad3d 100644 --- a/core/src/service/authors.rs +++ b/core/src/service/authors.rs @@ -6,12 +6,9 @@ use crate::{ use eva::auto_impl; #[auto_impl(&mut, Box)] -pub trait AuthorsRef: Send + Sync { +pub trait Authors: Send + Sync { fn get(&mut self) -> impl CallStep; -} -#[auto_impl(&mut, Box)] -pub trait AuthorsMut: AuthorsRef { fn create(&mut self) -> impl CallStep; fn update(&mut self) -> impl CallStep; } diff --git a/core/src/service/authz.rs b/core/src/service/authz.rs index a7db5c2..d5eddca 100644 --- a/core/src/service/authz.rs +++ b/core/src/service/authz.rs @@ -3,7 +3,7 @@ use eva::auto_impl; use crate::{service::AuxFut, types::session}; #[auto_impl(&mut)] -pub trait AuthenticationMut: Send + Sync { +pub trait Authentication: Send + Sync { fn authenticate(&mut self, session: session::Token) -> impl AuxFut<()>; fn clear(&mut self); diff --git a/core/src/service/boards.rs b/core/src/service/boards.rs index 19acad9..329f75d 100644 --- a/core/src/service/boards.rs +++ b/core/src/service/boards.rs @@ -6,12 +6,9 @@ use crate::{ }; #[auto_impl(&mut, Box)] -pub trait BoardsRef: Send + Sync { +pub trait Boards: Send + Sync { fn get(&mut self) -> impl CallStep; -} -#[auto_impl(&mut, Box)] -pub trait BoardsMut: BoardsRef { fn create(&mut self) -> impl CallStep; fn delete(&mut self) -> impl CallStep; fn edit(&mut self) -> impl CallStep; diff --git a/core/src/service/files.rs b/core/src/service/files.rs new file mode 100644 index 0000000..ab3ce25 --- /dev/null +++ b/core/src/service/files.rs @@ -0,0 +1,9 @@ +use eva::auto_impl; + +use crate::{requests::files::get_info, service::CallStep}; + +#[auto_impl(&mut, Box)] +pub trait Files { + fn get_info(&mut self) + -> impl CallStep; +} diff --git a/core/src/service/games.rs b/core/src/service/games.rs index e8405d7..1f7a52a 100644 --- a/core/src/service/games.rs +++ b/core/src/service/games.rs @@ -6,13 +6,10 @@ use crate::{ }; #[auto_impl(&mut, Box)] -pub trait GamesRef: Send + Sync { +pub trait Games: Send + Sync { fn get(&mut self) -> impl CallStep; fn search(&mut self) -> impl CallStep; -} -#[auto_impl(&mut, Box)] -pub trait GamesMut: GamesRef { fn create(&mut self) -> impl CallStep; fn update(&mut self) -> impl CallStep; } diff --git a/core/src/service/messages.rs b/core/src/service/messages.rs index 711e203..6f1a850 100644 --- a/core/src/service/messages.rs +++ b/core/src/service/messages.rs @@ -6,12 +6,9 @@ use crate::{ }; #[auto_impl(&mut, Box)] -pub trait MessagesRef: Send + Sync { +pub trait Messages: Send + Sync { fn get(&mut self) -> impl CallStep; -} -#[auto_impl(&mut, Box)] -pub trait MessagesMut: Send + Sync { fn post(&mut self) -> impl CallStep; fn delete(&mut self) -> impl CallStep; fn edit(&mut self) -> impl CallStep; diff --git a/core/src/service/mod.rs b/core/src/service/mod.rs index c2bd572..2bd9af7 100644 --- a/core/src/service/mod.rs +++ b/core/src/service/mod.rs @@ -2,6 +2,10 @@ use eva::{auto_impl, handling, trait_set}; use crate::{errors::Aux, requests::Response}; +pub use self::api_looks::Session; + +mod api_looks; + pub mod boards; pub mod messages; pub mod threads; @@ -10,6 +14,9 @@ pub mod authors; pub mod games; pub mod users; +pub mod files; +pub mod uploads; + pub mod authz; pub type SessionOf = ::Session; @@ -17,6 +24,23 @@ pub type SessionOf = ::Session; trait_set! { pub trait RespFut = Future> + Send; pub trait AuxFut = Future> + Send; + + pub trait IsService = SessionMaker; + pub trait IsSession = boards::Boards + + messages::Messages + + threads::Threads + + authors::Authors + + games::Games + + users::Users + + authz::Authentication + ; +} + +#[auto_impl(&, &mut, Arc)] +pub trait SessionMaker: Send + Sync { + type Session: IsSession; + + fn make_session(&self) -> impl AuxFut>; } pub trait CallStep: Send + Sync { @@ -44,32 +68,3 @@ where type Ok = O; type Err = E; } - -#[auto_impl(&, &mut, Arc)] -pub trait SessionMaker: Send + Sync { - type Session: Session; - - fn make_session(&self) -> impl AuxFut; -} - -trait_set! { - pub trait Service = SessionMaker; -} - -#[auto_impl(&mut)] -pub trait Session: Send + Sync { - fn users(&mut self) -> impl users::UsersRef; - fn users_mut(&mut self) -> impl users::UsersMut; - - fn authors(&mut self) -> impl authors::AuthorsRef; - fn authors_mut(&mut self) -> impl authors::AuthorsMut; - - fn games(&mut self) -> impl games::GamesRef; - fn games_mut(&mut self) -> impl games::GamesMut; - - fn authentication_mut(&mut self) -> impl authz::AuthenticationMut; - - fn boards(&mut self) -> impl boards::BoardsMut; - fn threads(&mut self) -> impl threads::ThreadsMut; - fn messages(&mut self) -> impl messages::MessagesMut; -} diff --git a/core/src/service/threads.rs b/core/src/service/threads.rs index f336ab7..59d6853 100644 --- a/core/src/service/threads.rs +++ b/core/src/service/threads.rs @@ -6,13 +6,10 @@ use crate::{ }; #[auto_impl(&mut, Box)] -pub trait ThreadsRef: Send + Sync { +pub trait Threads: Send + Sync { fn get(&mut self) -> impl CallStep; fn search(&mut self) -> impl CallStep; -} -#[auto_impl(&mut, Box)] -pub trait ThreadsMut: ThreadsRef { fn delete(&mut self) -> impl CallStep; fn edit(&mut self) -> impl CallStep; fn create(&mut self) -> impl CallStep; diff --git a/core/src/service/uploads.rs b/core/src/service/uploads.rs new file mode 100644 index 0000000..afa5287 --- /dev/null +++ b/core/src/service/uploads.rs @@ -0,0 +1,17 @@ +use eva::auto_impl; + +use crate::{ + requests::uploads::{abort, finish, list_pending, start}, + service::CallStep, +}; + +#[auto_impl(&mut, Box)] +pub trait Uploads: Send + Sync { + fn list_pending( + &mut self, + ) -> impl CallStep; + + fn start(&mut self) -> impl CallStep; + fn abort(&mut self) -> impl CallStep; + fn finish(&mut self) -> impl CallStep; +} diff --git a/core/src/service/users.rs b/core/src/service/users.rs index bce7722..c62020a 100644 --- a/core/src/service/users.rs +++ b/core/src/service/users.rs @@ -8,15 +8,12 @@ use crate::{ }; #[auto_impl(&mut)] -pub trait UsersRef: Send + Sync { +pub trait Users: Send + Sync { fn get(&mut self) -> impl CallStep; fn check_auth( &mut self, ) -> impl CallStep; -} -#[auto_impl(&mut)] -pub trait UsersMut: UsersRef { fn begin_auth( &mut self, ) -> impl CallStep; diff --git a/core/src/types/file.rs b/core/src/types/file.rs index cebc0df..089e94b 100644 --- a/core/src/types/file.rs +++ b/core/src/types/file.rs @@ -17,37 +17,28 @@ use eva::{data, hash::blake3, int, rand::Rng, str, str::ToCompactString, time::C pub type Hash = blake3::Hash; +pub mod game_file; +pub mod image; + #[data] pub struct FileInfo { pub id: Id, - pub format: FileFormat, pub class: Class, pub size: NonZeroU64, } -#[data(copy)] -pub enum FileFormat { - #[display("image:{_0}")] - Image(ImageFormat), - #[display("opaque")] - Opaque, -} - #[data(copy, ord, display(name))] -pub enum ImageFormat { - Png, - Jpeg, - Bmp, - Gif, - Webp, -} - -#[data(copy, ord, display(name))] -pub enum Class { +pub enum ClassKind { Image, GameFile, } +#[data] +pub enum Class { + Image(image::ImageInfo), + GameFile(game_file::GameFileInfo), +} + lazy_static::lazy_static! { static ref BASE_NAME_CHAR_PAT: String = { let mut out = String::from("^"); diff --git a/core/src/types/file/game_file.rs b/core/src/types/file/game_file.rs new file mode 100644 index 0000000..256f0d8 --- /dev/null +++ b/core/src/types/file/game_file.rs @@ -0,0 +1,11 @@ +use eva::data; + +#[data(copy, ord)] +pub enum GameFileFormat { + BinaryData, +} + +#[data] +pub struct GameFileInfo { + pub format: GameFileFormat, +} diff --git a/core/src/types/file/image.rs b/core/src/types/file/image.rs new file mode 100644 index 0000000..e035cdf --- /dev/null +++ b/core/src/types/file/image.rs @@ -0,0 +1,19 @@ +use std::num::NonZeroU16; + +use eva::data; + +#[data] +pub struct ImageInfo { + pub format: ImageFormat, + pub width: NonZeroU16, + pub height: NonZeroU16, +} + +#[data(copy, ord, display(name))] +pub enum ImageFormat { + Png, + Jpeg, + Bmp, + Gif, + Webp, +} diff --git a/core/src/uploads.rs b/core/src/uploads.rs index 4ea5642..f3d70ad 100644 --- a/core/src/uploads.rs +++ b/core/src/uploads.rs @@ -1,6 +1,6 @@ -use eva::{bytes::Bytes, data, trait_set}; +use eva::{bytes::Bytes, data}; -use futures::stream::Stream; +use futures::stream::BoxStream; #[data] pub enum Action { @@ -8,6 +8,4 @@ pub enum Action { Abort, } -trait_set! { - pub trait UploadStream = Stream + Unpin + Send; -} +pub type UploadStream<'a> = BoxStream<'a, Action>; diff --git a/http/Cargo.toml b/http/Cargo.toml index 685d832..474f1e4 100644 --- a/http/Cargo.toml +++ b/http/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2024" [features] -default = [] +default = ["server", "client"] client = ["dep:reqwest"] server = [ "dep:axum", diff --git a/http/src/client/auth.rs b/http/src/client/auth.rs index 46ff3d1..c5ea992 100644 --- a/http/src/client/auth.rs +++ b/http/src/client/auth.rs @@ -2,14 +2,14 @@ use viendesu_core::errors::AuxResult; use super::*; -impl AuthenticationMut for Hidden<'_> { +impl Authentication for HttpClient { async fn authenticate(&mut self, session: session::Token) -> AuxResult<()> { - self.0.session = Some(session); + self.session = Some(session); Ok(()) } fn clear(&mut self) { - self.0.session = None; + self.session = None; } } diff --git a/http/src/client/authors.rs b/http/src/client/authors.rs index e6894ba..ce22b0b 100644 --- a/http/src/client/authors.rs +++ b/http/src/client/authors.rs @@ -4,15 +4,13 @@ use viendesu_core::requests::authors::{create, get, update}; use crate::requests::authors as requests; -impl AuthorsRef for Hidden<'_> { +impl Authors for HttpClient { fn get(&mut self) -> impl CallStep { self.do_call(Method::GET, |get::Args { author }| { (format_compact!("/authors/{author}"), requests::Get {}) }) } -} -impl AuthorsMut for Hidden<'_> { fn create(&mut self) -> impl CallStep { self.do_call( Method::POST, diff --git a/http/src/client/boards.rs b/http/src/client/boards.rs index 9f35c4f..dc0fcb4 100644 --- a/http/src/client/boards.rs +++ b/http/src/client/boards.rs @@ -4,13 +4,11 @@ use viendesu_core::requests::boards::{create, delete, edit, get}; use crate::requests::boards as requests; -impl BoardsRef for Hidden<'_> { +impl Boards for HttpClient { fn get(&mut self) -> impl CallStep { self.do_call(Method::GET, todo::<_, requests::Get>()) } -} -impl BoardsMut for Hidden<'_> { fn create(&mut self) -> impl CallStep { self.do_call(Method::POST, todo::<_, requests::Create>()) } diff --git a/http/src/client/games.rs b/http/src/client/games.rs index ab6aa94..bbf5e08 100644 --- a/http/src/client/games.rs +++ b/http/src/client/games.rs @@ -7,7 +7,7 @@ use viendesu_core::{ use crate::requests::games as requests; -impl GamesRef for Hidden<'_> { +impl Games for HttpClient { fn get(&mut self) -> impl CallStep { self.do_call(Method::GET, |get::Args { game }| match game { Selector::Id(id) => (format_compact!("/games/{}", id.to_str()), requests::Get {}), @@ -45,9 +45,7 @@ impl GamesRef for Hidden<'_> { }, ) } -} -impl GamesMut for Hidden<'_> { fn create(&mut self) -> impl CallStep { self.do_call( Method::POST, diff --git a/http/src/client/messages.rs b/http/src/client/messages.rs index aa32cf9..6fcf669 100644 --- a/http/src/client/messages.rs +++ b/http/src/client/messages.rs @@ -4,13 +4,11 @@ use viendesu_core::requests::messages::{delete, edit, get, post}; use crate::requests::messages as requests; -impl MessagesRef for Hidden<'_> { +impl Messages for HttpClient { fn get(&mut self) -> impl CallStep { self.do_call(Method::GET, todo::<_, requests::Get>()) } -} -impl MessagesMut for Hidden<'_> { fn post(&mut self) -> impl CallStep { self.do_call(Method::POST, todo::<_, requests::Post>()) } diff --git a/http/src/client/mod.rs b/http/src/client/mod.rs index 9e10f3c..7239a54 100644 --- a/http/src/client/mod.rs +++ b/http/src/client/mod.rs @@ -10,14 +10,8 @@ use viendesu_core::{ errors::{self, Aux}, requests::Response, service::{ - CallStep, Session, SessionMaker, - authors::{AuthorsMut, AuthorsRef}, - authz::AuthenticationMut, - boards::{BoardsMut, BoardsRef}, - games::{GamesMut, GamesRef}, - messages::{MessagesMut, MessagesRef}, - threads::{ThreadsMut, ThreadsRef}, - users::{UsersMut, UsersRef}, + CallStep, Session, SessionMaker, authors::Authors, authz::Authentication, boards::Boards, + games::Games, messages::Messages, threads::Threads, users::Users, }, types::session, }; @@ -57,30 +51,10 @@ where } } -struct Hidden<'a>(&'a mut HttpClient); - fn todo() -> impl Send + Sync + FnMut(C) -> (CompactString, O) { |_| todo!() } -impl<'t> Hidden<'t> { - fn do_call<'this, P>(&'this mut self, method: Method, map_payload: P) -> DoRequest<'this, P> { - DoRequest { - client: self.0, - method, - map_payload, - } - } -} - -macro_rules! fwd { - ($($method:ident -> $Ret:ident;)*) => {$( - fn $method(&mut self) -> impl $Ret { - Hidden(self) - } - )*}; -} - pub struct HttpClient { options: Arc, client: reqwest::Client, @@ -88,6 +62,14 @@ pub struct HttpClient { } impl HttpClient { + fn do_call<'this, P>(&'this mut self, method: Method, map_payload: P) -> DoRequest<'this, P> { + DoRequest { + client: self, + method, + map_payload, + } + } + async fn do_request( &self, method: Method, @@ -150,21 +132,6 @@ impl HttpClient { } } -impl Session for HttpClient { - fwd! { - users -> UsersRef; - users_mut -> UsersMut; - authors -> AuthorsRef; - authors_mut -> AuthorsMut; - games -> GamesRef; - games_mut -> GamesMut; - boards -> BoardsMut; - threads -> ThreadsMut; - messages -> MessagesMut; - authentication_mut -> AuthenticationMut; - } -} - pub struct ClientOptions { pub format: Format, pub endpoint: String, @@ -179,12 +146,12 @@ pub struct HttpService { impl SessionMaker for HttpService { type Session = HttpClient; - async fn make_session(&self) -> errors::AuxResult { - Ok(HttpClient { + async fn make_session(&self) -> errors::AuxResult> { + Ok(Session::new(HttpClient { options: Arc::clone(&self.options), client: self.inner.clone(), session: None, - }) + })) } } diff --git a/http/src/client/threads.rs b/http/src/client/threads.rs index 40d4f9e..2aa9a55 100644 --- a/http/src/client/threads.rs +++ b/http/src/client/threads.rs @@ -4,7 +4,7 @@ use viendesu_core::requests::threads::{create, delete, edit, get, search}; use crate::requests::threads as requests; -impl ThreadsRef for Hidden<'_> { +impl Threads for HttpClient { fn get(&mut self) -> impl CallStep { self.do_call(Method::GET, todo::<_, requests::Get>()) } @@ -12,9 +12,7 @@ impl ThreadsRef for Hidden<'_> { fn search(&mut self) -> impl CallStep { self.do_call(Method::POST, todo::<_, requests::Search>()) } -} -impl ThreadsMut for Hidden<'_> { fn delete(&mut self) -> impl CallStep { self.do_call(Method::DELETE, todo::<_, requests::Delete>()) } diff --git a/http/src/client/users.rs b/http/src/client/users.rs index ab16640..6a2fab2 100644 --- a/http/src/client/users.rs +++ b/http/src/client/users.rs @@ -8,7 +8,7 @@ use viendesu_core::requests::users::{ use crate::requests::users as requests; -impl UsersRef for Hidden<'_> { +impl Users for HttpClient { fn get(&mut self) -> impl CallStep { self.do_call(Method::GET, |get::Args { user }| match user { Some(u) => (format_compact!("/users/{u}"), requests::Get {}), @@ -23,9 +23,7 @@ impl UsersRef for Hidden<'_> { ("/users/check_auth".into(), requests::CheckAuth {}) }) } -} -impl UsersMut for Hidden<'_> { fn begin_auth( &mut self, ) -> impl CallStep { diff --git a/http/src/requests/files.rs b/http/src/requests/files.rs new file mode 100644 index 0000000..17c2157 --- /dev/null +++ b/http/src/requests/files.rs @@ -0,0 +1,19 @@ +use eva::data; + +use crate::requests::status_code; + +use viendesu_core::{errors, requests::files as reqs}; + +#[data] +pub struct GetInfo {} + +impl_req!(GetInfo => [reqs::get_info::Ok; reqs::get_info::Err]); +status_code::direct!(reqs::get_info::Ok => OK); +status_code::map!(reqs::get_info::Err => [NotFound]); + +const _: () = { + use errors::files::*; + use status_code::direct; + + direct!(NotFound => NOT_FOUND); +}; diff --git a/http/src/requests/mod.rs b/http/src/requests/mod.rs index 9761f3c..61f58bd 100644 --- a/http/src/requests/mod.rs +++ b/http/src/requests/mod.rs @@ -32,3 +32,6 @@ pub mod games; pub mod boards; pub mod messages; pub mod threads; + +pub mod files; +pub mod uploads; diff --git a/http/src/requests/uploads.rs b/http/src/requests/uploads.rs new file mode 100644 index 0000000..8d1d7b3 --- /dev/null +++ b/http/src/requests/uploads.rs @@ -0,0 +1,57 @@ +use std::num::NonZeroU64; + +use eva::data; + +use crate::requests::status_code; + +use viendesu_core::{errors, requests::uploads as reqs, types::file}; + +#[data] +pub struct ListPending {} + +impl_req!(ListPending => [reqs::list_pending::Ok; reqs::list_pending::Err]); +status_code::direct!(reqs::list_pending::Ok => OK); +status_code::map!(reqs::list_pending::Err => []); + +#[data] +pub struct Start { + pub file_name: Option, + pub hash: file::Hash, + pub class: file::ClassKind, + pub size: NonZeroU64, +} + +impl_req!(Start => [reqs::start::Ok; reqs::start::Err]); +status_code::direct!(reqs::start::Ok => CREATED); +status_code::map!(reqs::start::Err => [QuotaExceeded, SimUpQuotaExceeded]); + +#[data] +pub struct Finish {} + +impl_req!(Finish => [reqs::finish::Ok; reqs::finish::Err]); +status_code::direct!(reqs::finish::Ok => OK); +status_code::map!(reqs::finish::Err => [ + HashMismatch, + NotFound, + Overuploading, + ConcurrentUploadInProgress, +]); + +#[data] +pub struct Abort {} + +impl_req!(Abort => [reqs::abort::Ok; reqs::abort::Err]); +status_code::direct!(reqs::abort::Ok => OK); +status_code::map!(reqs::abort::Err => [NotFound]); + +const _: () = { + use errors::uploads::*; + use status_code::direct; + + direct!(ConcurrentUploadInProgress => BAD_REQUEST); + direct!(NotFound => NOT_FOUND); + direct!(QuotaExceeded => TOO_MANY_REQUESTS); + direct!(SimUpQuotaExceeded => TOO_MANY_REQUESTS); + direct!(Overuploading => BAD_REQUEST); + direct!(HashMismatch => BAD_REQUEST); +}; diff --git a/http/src/server/handler.rs b/http/src/server/handler.rs index f3ca9d5..2a5e220 100644 --- a/http/src/server/handler.rs +++ b/http/src/server/handler.rs @@ -11,17 +11,14 @@ use axum::{ use viendesu_core::{ errors as core_errors, - service::{Session, SessionOf, authz::AuthenticationMut}, + service::{Session, SessionOf, authz::Authentication as _}, }; -use crate::{ - format::Format, - server::{ - State, Types, - context::{Context, load_args}, - request::{ServerRequest, extract}, - response, - }, +use crate::server::{ + State, Types, + context::{Context, load_args}, + request::{ServerRequest, extract}, + response, }; struct Inner { @@ -130,7 +127,7 @@ impl> FinishedHandler: - Send + Sync + 'static + Fn(SessionOf, Context) -> Self::HFut + Send + Sync + 'static + Fn(Session>, Context) -> Self::HFut { type HFut: Fut> + Captures>; @@ -254,7 +251,7 @@ pub trait MakeRequest: impl MakeRequest for H where - H: Send + Sync + 'static + Fn(SessionOf, Context) -> F, + H: Send + Sync + 'static + Fn(Session>, Context) -> F, F: Fut> + Captures>, T: Types, R: ServerRequest, diff --git a/http/src/server/mod.rs b/http/src/server/mod.rs index c7532b7..690c31a 100644 --- a/http/src/server/mod.rs +++ b/http/src/server/mod.rs @@ -5,7 +5,7 @@ use eva::{ use eyre::Context; use viendesu_core::{ errors::AuxResult, - service::{Service, SessionMaker, SessionOf}, + service::{IsService, Session, SessionMaker, SessionOf}, }; use tokio::net; @@ -22,7 +22,7 @@ mod response; mod routes; pub trait Types: Send + Sync + 'static { - type Service: Service + Clone; + type Service: IsService + Clone; } pub async fn serve( @@ -73,7 +73,7 @@ struct State { } impl State { - async fn make_session(&self) -> AuxResult> { - self.service.make_session().await + async fn make_session(&self) -> AuxResult>> { + Ok(self.service.make_session().await?) } } diff --git a/http/src/server/routes.rs b/http/src/server/routes.rs index 8c0982a..c3cbbca 100644 --- a/http/src/server/routes.rs +++ b/http/src/server/routes.rs @@ -5,14 +5,11 @@ use crate::server::{ }; use viendesu_core::{ - service::{ - CallStep, Session, SessionOf as SessionOfService, - users::{UsersMut, UsersRef}, - }, + service::{CallStep, Session, SessionOf as SessionOfService}, types::user, }; -type SessionOf = SessionOfService<::Service>; +type SessionOf = Session::Service>>; pub fn make(router: RouterScope) -> RouterScope { router @@ -30,8 +27,11 @@ fn users(router: RouterScope) -> RouterScope { use crate::requests::users::{ BeginAuth, CheckAuth, ConfirmSignUp, FinishAuth, Get, SignIn, SignUp, Update, }; - use viendesu_core::requests::users::{ - begin_auth, check_auth, confirm_sign_up, finish_auth, get, sign_in, sign_up, update, + use viendesu_core::{ + requests::users::{ + begin_auth, check_auth, confirm_sign_up, finish_auth, get, sign_in, sign_up, update, + }, + service::users::Users, }; fn convert_update(u: Update) -> update::Update { @@ -64,7 +64,7 @@ fn users(router: RouterScope) -> RouterScope { "/begin-auth", post(async |mut session: SessionOf, ctx: Ctx| { session - .users_mut() + .users() .begin_auth() .call(begin_auth::Args { method: ctx.request.method, @@ -78,7 +78,7 @@ fn users(router: RouterScope) -> RouterScope { async |mut session: SessionOf, mut ctx: Ctx| { let auth_session: user::AuthSessionId = ctx.path().await?; session - .users_mut() + .users() .finish_auth() .call(finish_auth::Args { auth_session }) .await @@ -101,7 +101,7 @@ fn users(router: RouterScope) -> RouterScope { "/sign_in", post(async |mut session: SessionOf, ctx: Ctx| { session - .users_mut() + .users() .sign_in() .call(sign_in::Args { nickname: ctx.request.nickname, @@ -120,7 +120,7 @@ fn users(router: RouterScope) -> RouterScope { display_name, } = ctx.request; session - .users_mut() + .users() .sign_up() .call(sign_up::Args { nickname, @@ -136,7 +136,7 @@ fn users(router: RouterScope) -> RouterScope { patch(async |mut session: SessionOf, mut ctx: Ctx| { let user: user::Selector = ctx.path().await?; session - .users_mut() + .users() .update() .call(update::Args { user: Some(user), @@ -149,7 +149,7 @@ fn users(router: RouterScope) -> RouterScope { "/me", patch(async |mut session: SessionOf, ctx: Ctx| { session - .users_mut() + .users() .update() .call(update::Args { user: None, @@ -164,7 +164,7 @@ fn users(router: RouterScope) -> RouterScope { async |mut session: SessionOf, mut ctx: Ctx| { let (user, token) = ctx.path().await?; session - .users_mut() + .users() .confirm_sign_up() .call(confirm_sign_up::Args { user, token }) .await @@ -173,12 +173,20 @@ fn users(router: RouterScope) -> RouterScope { ) } +fn uploads(router: RouterScope) -> RouterScope { + use crate::requests::uploads::{Abort, Finish, ListPending, Start}; + + use viendesu_core::requests::uploads::{abort, finish, list_pending, start}; + + router +} + fn authors(router: RouterScope) -> RouterScope { use crate::requests::authors::{Create, Get, Update}; use viendesu_core::{ requests::authors::{create, get, update}, - service::authors::{AuthorsMut as _, AuthorsRef as _}, + service::authors::Authors, types::author, }; @@ -193,7 +201,7 @@ fn authors(router: RouterScope) -> RouterScope { owner, } = ctx.request; session - .authors_mut() + .authors() .create() .call(create::Args { title, @@ -226,7 +234,7 @@ fn authors(router: RouterScope) -> RouterScope { } = ctx.request; session - .authors_mut() + .authors() .update() .call(update::Args { author, @@ -248,7 +256,7 @@ fn games(router: RouterScope) -> RouterScope { use viendesu_core::{ requests::games::{create, get, search, update}, - service::games::{GamesMut as _, GamesRef as _}, + service::games::Games, types::{author, game}, }; @@ -266,7 +274,7 @@ fn games(router: RouterScope) -> RouterScope { release_date, } = ctx.request; session - .games_mut() + .games() .create() .call(create::Args { title,