diff --git a/core/src/errors.rs b/core/src/errors.rs index 07fde48..bdb9e11 100644 --- a/core/src/errors.rs +++ b/core/src/errors.rs @@ -7,6 +7,8 @@ pub mod boards; pub mod messages; pub mod threads; +pub mod marks; + pub mod auth; pub mod authors; pub mod files; diff --git a/core/src/errors/marks.rs b/core/src/errors/marks.rs new file mode 100644 index 0000000..124e739 --- /dev/null +++ b/core/src/errors/marks.rs @@ -0,0 +1,18 @@ +use eva::data; + +use crate::types::mark; + +#[data(error, display("no such tag: {tag}"))] +pub struct NoSuchTag { + pub tag: mark::Tag, +} + +#[data(error, display("no such genre: {genre}"))] +pub struct NoSuchGenre { + pub genre: mark::Genre, +} + +#[data(error, display("no such badge: {badge}"))] +pub struct NoSuchBadge { + pub badge: mark::Badge, +} diff --git a/core/src/requests/games.rs b/core/src/requests/games.rs index 0a4acc3..f03ec32 100644 --- a/core/src/requests/games.rs +++ b/core/src/requests/games.rs @@ -1,6 +1,6 @@ use crate::{ errors, - types::{Patch, True, author, file, game}, + types::{Patch, True, author, file, game, mark}, }; use std::collections::HashMap; @@ -23,9 +23,9 @@ pub mod update { pub description: Patch>, pub slug: Patch, pub thumbnail: Patch>, - pub genres: Patch, - pub badges: Patch, - pub tags: Patch, + pub genres: Patch, + pub badges: Patch, + pub tags: Patch, pub screenshots: Patch, pub published: Patch, } @@ -37,6 +37,12 @@ pub mod update { pub enum Err { #[display("{_0}")] NotFound(#[from] errors::games::NotFound), + #[display("{_0}")] + NoSuchTag(#[from] errors::marks::NoSuchTag), + #[display("{_0}")] + NoSuchBadge(#[from] errors::marks::NoSuchBadge), + #[display("{_0}")] + NoSuchGenre(#[from] errors::marks::NoSuchGenre), } } @@ -53,9 +59,9 @@ pub mod search { #[data] #[derive(Default)] pub struct Marks { - pub tags: Logic, - pub genres: Logic, - pub badges: Logic, + pub tags: Logic, + pub genres: Logic, + pub badges: Logic, } type SortKey = (K, game::Id); @@ -141,6 +147,10 @@ pub mod create { pub description: Option, pub thumbnail: Option, pub author: author::Id, + #[serde(default)] + pub tags: mark::Tags, + #[serde(default)] + pub genres: mark::Genres, pub slug: Option, pub vndb: Option, pub release_date: Option, @@ -157,6 +167,10 @@ pub mod create { NoSuchAuthor(#[from] errors::authors::NotFound), #[display("{_0}")] AlreadyTaken(#[from] errors::games::AlreadyTaken), + #[display("{_0}")] + NoSuchTag(#[from] errors::marks::NoSuchTag), + #[display("{_0}")] + NoSuchGenre(#[from] errors::marks::NoSuchGenre), } } @@ -165,8 +179,8 @@ pub mod get { #[data] pub struct Marks { - pub tags: HashMap, - pub badges: HashMap, + pub tags: HashMap, + pub badges: HashMap, } #[data] diff --git a/core/src/requests/marks.rs b/core/src/requests/marks.rs index 964d58d..8bc40df 100644 --- a/core/src/requests/marks.rs +++ b/core/src/requests/marks.rs @@ -1,4 +1,4 @@ -use crate::types::game; +use crate::types::mark; use eva::{array, data, str}; @@ -18,7 +18,7 @@ pub mod add_tag { #[data] pub struct Ok { - pub id: game::Tag, + pub id: mark::Tag, } #[data(error, display("_"))] @@ -35,7 +35,7 @@ pub mod add_badge { #[data] pub struct Ok { - pub id: game::Badge, + pub id: mark::Badge, } #[data(error, display("_"))] @@ -52,7 +52,7 @@ pub mod list_genres { #[data] pub struct Ok { - pub genres: array::ImmutableHeap, + pub genres: array::ImmutableHeap, } #[data(error, display("_"))] @@ -69,7 +69,7 @@ pub mod list_badges { #[data] pub struct Ok { - pub badges: Vec>, + pub badges: Vec>, } #[data(error, display("_"))] @@ -86,7 +86,7 @@ pub mod list_tags { #[data] pub struct Ok { - pub tags: Vec>, + pub tags: Vec>, } #[data(error, display("_"))] diff --git a/core/src/types/game.rs b/core/src/types/game.rs index 4b3173b..a618a8e 100644 --- a/core/src/types/game.rs +++ b/core/src/types/game.rs @@ -1,18 +1,6 @@ use eva::{array, data, int, str, str::CompactString, time::Date}; -use crate::types::{author, entity::define_eid, file, slug, user}; - -#[data] -#[derive(Default)] -pub struct Tags(pub array::ImmutableHeap); - -#[data] -#[derive(Default)] -pub struct Genres(pub array::ImmutableHeap); - -#[data] -#[derive(Default)] -pub struct Badges(pub array::ImmutableHeap); +use crate::types::{author, entity::define_eid, file, mark, slug, user}; #[data] #[derive(Default)] @@ -100,9 +88,9 @@ pub struct Game { pub publication: Option, pub screenshots: Screenshots, - pub tags: Tags, - pub genres: Genres, - pub badges: Badges, + pub tags: mark::Tags, + pub genres: mark::Genres, + pub badges: mark::Badges, } #[data(copy)] @@ -129,17 +117,8 @@ pub struct Votes(pub u32); define_eid! { /// ID of the game. pub struct Id(Game); - - /// ID of the tag. - pub struct Tag(Tag); - - /// Game badge. - pub struct Badge(Badge); } -#[str(newtype, copy)] -pub struct Genre(pub slug::LowerSlug<15>); - /// Estimated time to read. #[int(u8, 0..=100)] pub enum TimeToReadHours {} diff --git a/core/src/types/mark.rs b/core/src/types/mark.rs new file mode 100644 index 0000000..4adf478 --- /dev/null +++ b/core/src/types/mark.rs @@ -0,0 +1,26 @@ +use eva::{array, data, str}; + +use crate::types::{entity, slug}; + +#[data] +#[derive(Default)] +pub struct Tags(pub array::ImmutableHeap); + +#[data] +#[derive(Default)] +pub struct Genres(pub array::ImmutableHeap); + +#[data] +#[derive(Default)] +pub struct Badges(pub array::ImmutableHeap); + +#[str(newtype, copy)] +pub struct Genre(pub slug::LowerSlug<15>); + +entity::define_eid! { + /// ID of the tag. + pub struct Tag(Tag); + + /// Game badge. + pub struct Badge(Badge); +} diff --git a/core/src/types/mod.rs b/core/src/types/mod.rs index a3dc5eb..414ea29 100644 --- a/core/src/types/mod.rs +++ b/core/src/types/mod.rs @@ -6,6 +6,8 @@ pub mod board; pub mod message; pub mod thread; +pub mod mark; + pub mod author; pub mod user; diff --git a/http/src/client/games.rs b/http/src/client/games.rs index bbf5e08..e3723ed 100644 --- a/http/src/client/games.rs +++ b/http/src/client/games.rs @@ -57,6 +57,8 @@ impl Games for HttpClient { slug, vndb, release_date, + tags, + genres, }| { ( "/games".into(), @@ -65,6 +67,8 @@ impl Games for HttpClient { description, thumbnail, author, + tags, + genres, slug, vndb, release_date, diff --git a/http/src/requests/games.rs b/http/src/requests/games.rs index 75066f2..82cc1ca 100644 --- a/http/src/requests/games.rs +++ b/http/src/requests/games.rs @@ -5,7 +5,7 @@ use crate::requests::status_code; use viendesu_core::{ errors, requests::games as reqs, - types::{Patch, author, file, game}, + types::{Patch, author, file, game, mark}, }; #[data] @@ -15,9 +15,9 @@ pub struct Update { pub description: Patch>, pub slug: Patch, pub thumbnail: Patch>, - pub genres: Patch, - pub badges: Patch, - pub tags: Patch, + pub genres: Patch, + pub badges: Patch, + pub tags: Patch, pub screenshots: Patch, pub published: Patch, } @@ -25,7 +25,7 @@ pub struct Update { impl_req!(Update => [reqs::update::Ok; reqs::update::Err]); status_code::direct!(reqs::update::Ok => OK); -status_code::map!(reqs::update::Err => [NotFound]); +status_code::map!(reqs::update::Err => [NotFound, NoSuchBadge, NoSuchGenre, NoSuchTag]); #[data] pub struct Search { @@ -62,6 +62,10 @@ pub struct Create { pub thumbnail: Option, pub author: author::Id, pub slug: Option, + #[serde(default)] + pub tags: mark::Tags, + #[serde(default)] + pub genres: mark::Genres, pub vndb: Option, pub release_date: Option, } @@ -69,7 +73,7 @@ pub struct Create { impl_req!(Create => [reqs::create::Ok; reqs::create::Err]); status_code::direct!(reqs::create::Ok => CREATED); -status_code::map!(reqs::create::Err => [AlreadyTaken, NoSuchAuthor]); +status_code::map!(reqs::create::Err => [AlreadyTaken, NoSuchAuthor, NoSuchGenre, NoSuchTag]); const _: () = { use errors::games::*; diff --git a/http/src/requests/marks.rs b/http/src/requests/marks.rs index a3c2e64..e00d23e 100644 --- a/http/src/requests/marks.rs +++ b/http/src/requests/marks.rs @@ -46,3 +46,13 @@ pub struct ListBadges { 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 => []); + +const _: () = { + use viendesu_core::errors::marks::*; + use status_code::*; + + direct!(NoSuchTag => NOT_FOUND); + direct!(NoSuchGenre => NOT_FOUND); + direct!(NoSuchBadge => NOT_FOUND); +}; + diff --git a/http/src/server/routes.rs b/http/src/server/routes.rs index df0e823..1463c53 100644 --- a/http/src/server/routes.rs +++ b/http/src/server/routes.rs @@ -350,6 +350,8 @@ fn games(router: RouterScope) -> RouterScope { title, description, thumbnail, + tags, + genres, author, slug, vndb, @@ -364,6 +366,8 @@ fn games(router: RouterScope) -> RouterScope { thumbnail, author, slug, + tags, + genres, vndb, release_date, })