diff --git a/core/src/requests/marks.rs b/core/src/requests/marks.rs index e8abcbc..964d58d 100644 --- a/core/src/requests/marks.rs +++ b/core/src/requests/marks.rs @@ -1,4 +1,4 @@ -use crate::types::{entity, game}; +use crate::types::game; use eva::{array, data, str}; @@ -8,18 +8,34 @@ pub struct TextEntry { pub text: str::CompactString, } -pub mod add { +pub mod add_tag { use super::*; #[data] - pub enum Args { - Tag(str::CompactString), - Badge(str::CompactString), + pub struct Args { + pub tag: str::CompactString, } #[data] pub struct Ok { - pub id: entity::Id, + pub id: game::Tag, + } + + #[data(error, display("_"))] + pub enum Err {} +} + +pub mod add_badge { + use super::*; + + #[data] + pub struct Args { + pub badge: str::CompactString, + } + + #[data] + pub struct Ok { + pub id: game::Badge, } #[data(error, display("_"))] @@ -48,7 +64,7 @@ pub mod list_badges { #[data] pub struct Args { - pub query: str::CompactString, + pub query: Option, } #[data] @@ -65,7 +81,7 @@ pub mod list_tags { #[data] pub struct Args { - pub query: str::CompactString, + pub query: Option, } #[data] diff --git a/core/src/service/api_looks.rs b/core/src/service/api_looks.rs index d80e1e0..b90898e 100644 --- a/core/src/service/api_looks.rs +++ b/core/src/service/api_looks.rs @@ -29,4 +29,8 @@ impl Session {project!{ fn messages() -> messages::Messages; fn authz() -> authz::Authentication; + + fn tags() -> marks::Tags; + fn genres() -> marks::Genres; + fn badges() -> marks::Badges; }} diff --git a/core/src/service/marks.rs b/core/src/service/marks.rs new file mode 100644 index 0000000..2b3c199 --- /dev/null +++ b/core/src/service/marks.rs @@ -0,0 +1,27 @@ +use eva::auto_impl; + +use crate::{ + requests::marks::{add_badge, add_tag, list_badges, list_genres, list_tags}, + service::CallStep, +}; + +#[auto_impl(&mut)] +pub trait Genres: Send + Sync { + fn list( + &mut self, + ) -> impl CallStep; +} + +#[auto_impl(&mut)] +pub trait Badges: Send + Sync { + fn list( + &mut self, + ) -> impl CallStep; + fn add(&mut self) -> impl CallStep; +} + +#[auto_impl(&mut)] +pub trait Tags: Send + Sync { + fn list(&mut self) -> impl CallStep; + fn add(&mut self) -> impl CallStep; +} diff --git a/core/src/service/mod.rs b/core/src/service/mod.rs index 2bd9af7..e650e95 100644 --- a/core/src/service/mod.rs +++ b/core/src/service/mod.rs @@ -6,6 +6,8 @@ pub use self::api_looks::Session; mod api_looks; +pub mod marks; + pub mod boards; pub mod messages; pub mod threads; @@ -33,6 +35,9 @@ trait_set! { + games::Games + users::Users + authz::Authentication + + marks::Tags + + marks::Genres + + marks::Badges ; } diff --git a/http/Cargo.toml b/http/Cargo.toml index 474f1e4..685d832 100644 --- a/http/Cargo.toml +++ b/http/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2024" [features] -default = ["server", "client"] +default = [] client = ["dep:reqwest"] server = [ "dep:axum", diff --git a/http/src/client/marks.rs b/http/src/client/marks.rs new file mode 100644 index 0000000..140528e --- /dev/null +++ b/http/src/client/marks.rs @@ -0,0 +1,45 @@ +use super::*; + +use crate::requests::marks as requests; + +use viendesu_core::requests::marks::{add_badge, add_tag, list_badges, list_genres, list_tags}; + +impl Genres for HttpClient { + fn list( + &mut self, + ) -> impl CallStep { + self.do_call(Method::GET, |list_genres::Args {}| { + ("/genres".into(), requests::ListGenres {}) + }) + } +} + +impl Tags for HttpClient { + fn list(&mut self) -> impl CallStep { + self.do_call(Method::GET, |list_tags::Args { query }| { + ("/tags".into(), requests::ListTags { query }) + }) + } + + fn add(&mut self) -> impl CallStep { + self.do_call(Method::POST, |add_tag::Args { tag }| { + ("/tags".into(), requests::AddTag { text: tag }) + }) + } +} + +impl Badges for HttpClient { + fn list( + &mut self, + ) -> impl CallStep { + self.do_call(Method::GET, |list_badges::Args { query }| { + ("/badges".into(), requests::ListBadges { query }) + }) + } + + fn add(&mut self) -> impl CallStep { + self.do_call(Method::POST, |add_badge::Args { badge }| { + ("/badges".into(), requests::AddBadge { text: badge }) + }) + } +} diff --git a/http/src/client/mod.rs b/http/src/client/mod.rs index 7239a54..f4ecdca 100644 --- a/http/src/client/mod.rs +++ b/http/src/client/mod.rs @@ -10,8 +10,15 @@ use viendesu_core::{ errors::{self, Aux}, requests::Response, service::{ - CallStep, Session, SessionMaker, authors::Authors, authz::Authentication, boards::Boards, - games::Games, messages::Messages, threads::Threads, users::Users, + CallStep, Session, SessionMaker, + authors::Authors, + authz::Authentication, + boards::Boards, + games::Games, + marks::{Badges, Genres, Tags}, + messages::Messages, + threads::Threads, + users::Users, }, types::session, }; @@ -28,6 +35,8 @@ mod authors; mod games; mod users; +mod marks; + struct DoRequest<'c, P> { client: &'c mut HttpClient, method: Method, diff --git a/http/src/requests/marks.rs b/http/src/requests/marks.rs new file mode 100644 index 0000000..a3c2e64 --- /dev/null +++ b/http/src/requests/marks.rs @@ -0,0 +1,48 @@ +use eva::{data, str::CompactString}; + +use crate::requests::status_code; + +use viendesu_core::requests::marks as reqs; + +#[data] +pub struct AddBadge { + pub text: CompactString, +} + +impl_req!(AddBadge => [reqs::add_badge::Ok; reqs::add_badge::Err]); +status_code::direct!(reqs::add_badge::Ok => CREATED); +status_code::map!(reqs::add_badge::Err => []); + +#[data] +pub struct AddTag { + pub text: CompactString, +} + +impl_req!(AddTag => [reqs::add_tag::Ok; reqs::add_tag::Err]); +status_code::direct!(reqs::add_tag::Ok => CREATED); +status_code::map!(reqs::add_tag::Err => []); + +#[data] +pub struct ListGenres {} + +impl_req!(ListGenres => [reqs::list_genres::Ok; reqs::list_genres::Err]); +status_code::direct!(reqs::list_genres::Ok => OK); +status_code::map!(reqs::list_genres::Err => []); + +#[data] +pub struct ListTags { + pub query: Option, +} + +impl_req!(ListTags => [reqs::list_tags::Ok; reqs::list_tags::Err]); +status_code::direct!(reqs::list_tags::Ok => OK); +status_code::map!(reqs::list_tags::Err => []); + +#[data] +pub struct ListBadges { + pub query: Option, +} + +impl_req!(ListBadges => [reqs::list_badges::Ok; reqs::list_badges::Err]); +status_code::direct!(reqs::list_badges::Ok => OK); +status_code::map!(reqs::list_badges::Err => []); diff --git a/http/src/requests/mod.rs b/http/src/requests/mod.rs index 61f58bd..5c1f75a 100644 --- a/http/src/requests/mod.rs +++ b/http/src/requests/mod.rs @@ -24,6 +24,7 @@ macro_rules! impl_req { }; } +pub mod marks; pub mod users; pub mod authors; diff --git a/http/src/server/routes.rs b/http/src/server/routes.rs index aec09a7..df0e823 100644 --- a/http/src/server/routes.rs +++ b/http/src/server/routes.rs @@ -21,10 +21,90 @@ pub fn make(router: RouterScope) -> RouterScope { .nest("/messages", messages) .nest("/uploads", uploads) .nest("/files", files) + .nest("/tags", tags) + .nest("/badges", badges) + .nest("/genres", genres) } // == Routes == +fn genres(router: RouterScope) -> RouterScope { + use crate::requests::marks::ListGenres; + + use viendesu_core::{requests::marks::list_genres, service::marks::Genres as _}; + + router.route( + "/", + get( + async move |mut session: SessionOf, ctx: Ctx| { + let ListGenres {} = ctx.request; + + session.genres().list().call(list_genres::Args {}).await + }, + ), + ) +} + +fn badges(router: RouterScope) -> RouterScope { + use crate::requests::marks::{AddBadge, ListBadges}; + + use viendesu_core::{ + requests::marks::{add_badge, list_badges}, + service::marks::Badges as _, + }; + + router + .route( + "/", + get( + async move |mut session: SessionOf, ctx: Ctx| { + let ListBadges { query } = ctx.request; + session + .badges() + .list() + .call(list_badges::Args { query }) + .await + }, + ), + ) + .route( + "/", + post(async move |mut session: SessionOf, ctx: Ctx| { + let AddBadge { text } = ctx.request; + session + .badges() + .add() + .call(add_badge::Args { badge: text }) + .await + }), + ) +} + +fn tags(router: RouterScope) -> RouterScope { + use crate::requests::marks::{AddTag, ListTags}; + + use viendesu_core::{ + requests::marks::{add_tag, list_tags}, + service::marks::Tags as _, + }; + + router + .route( + "/", + get(async move |mut session: SessionOf, ctx: Ctx| { + let ListTags { query } = ctx.request; + session.tags().list().call(list_tags::Args { query }).await + }), + ) + .route( + "/", + post(async move |mut session: SessionOf, ctx: Ctx| { + let AddTag { text } = ctx.request; + session.tags().add().call(add_tag::Args { tag: text }).await + }), + ) +} + fn users(router: RouterScope) -> RouterScope { use crate::requests::users::{ BeginAuth, CheckAuth, ConfirmSignUp, FinishAuth, Get, SignIn, SignUp, Update,