impl rest of http

This commit is contained in:
Aleksandr 2025-10-06 20:24:47 +03:00
parent 5743585a77
commit d3c25799cd
6 changed files with 277 additions and 11 deletions

View file

@ -11,7 +11,7 @@ use crate::types::{entity, file, slug, user};
#[data(copy, ord)]
#[serde(untagged)]
pub enum Selector {
#[display("{_0}")]
#[display("{}", _0.to_str())]
Id(#[from] Id),
#[display("@{_0}")]
#[serde(with = "SlugStr")]

View file

@ -500,7 +500,7 @@ macro_rules! _define_eid {
}
/// Generic entity identifier.
#[data(copy, ord, not(serde, schemars, Debug), display("{}:{}", self.metadata().kind(), self.to_str()))]
#[data(copy, ord, not(serde, schemars, Debug), display("{}", self.to_str()))]
#[derive(Hash)]
pub struct Id(NonZeroU128);
@ -524,7 +524,14 @@ impl Id {
impl fmt::Debug for Id {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("Id").field(&self.to_str().as_str()).finish()
write!(
f,
"{}:{}",
self.metadata()
.kind()
.as_static_str(Some(eva::generic::Case::Snake)),
self.to_str()
)
}
}

View file

@ -14,10 +14,39 @@ impl AuthorsRef for Hidden<'_> {
impl AuthorsMut for Hidden<'_> {
fn create(&mut self) -> impl CallStep<create::Args, Ok = create::Ok, Err = create::Err> {
self.do_call(Method::POST, todo::<_, requests::Create>())
self.do_call(
Method::POST,
|create::Args {
title,
slug,
description,
owner,
}| {
(
"/authors".into(),
requests::Create {
title,
description,
slug,
owner,
},
)
},
)
}
fn update(&mut self) -> impl CallStep<update::Args, Ok = update::Ok, Err = update::Err> {
self.do_call(Method::PATCH, todo::<_, requests::Update>())
self.do_call(Method::PATCH, |update::Args { author, update }| {
(
format_compact!("/authors/{author}"),
requests::Update {
title: update.title,
description: update.description,
pfp: update.pfp,
slug: update.slug,
verified: update.verified,
},
)
})
}
}

View file

@ -1,25 +1,97 @@
use super::*;
use viendesu_core::requests::games::{create, get, search, update};
use viendesu_core::{
requests::games::{create, get, search, update},
types::game::Selector,
};
use crate::requests::games as requests;
impl GamesRef for Hidden<'_> {
fn get(&mut self) -> impl CallStep<get::Args, Ok = get::Ok, Err = get::Err> {
self.do_call(Method::GET, todo::<_, requests::Get>())
self.do_call(Method::GET, |get::Args { game }| match game {
Selector::Id(id) => (format_compact!("/games/{}", id.to_str()), requests::Get {}),
Selector::FullyQualified(fq) => (
format_compact!("/games/{}/{}", fq.author, fq.slug),
requests::Get {},
),
})
}
fn search(&mut self) -> impl CallStep<search::Args, Ok = search::Ok, Err = search::Err> {
self.do_call(Method::POST, todo::<_, requests::Search>())
self.do_call(
Method::POST,
|search::Args {
query,
author,
include,
exclude,
order,
sort_by,
limit,
}| {
(
"/games/search".into(),
requests::Search {
query,
author,
include,
exclude,
order,
sort_by,
limit,
},
)
},
)
}
}
impl GamesMut for Hidden<'_> {
fn create(&mut self) -> impl CallStep<create::Args, Ok = create::Ok, Err = create::Err> {
self.do_call(Method::POST, todo::<_, requests::Create>())
self.do_call(
Method::POST,
|create::Args {
title,
description,
thumbnail,
author,
slug,
vndb,
release_date,
}| {
(
"/games".into(),
requests::Create {
title,
description,
thumbnail,
author,
slug,
vndb,
release_date,
},
)
},
)
}
fn update(&mut self) -> impl CallStep<update::Args, Ok = update::Ok, Err = update::Err> {
self.do_call(Method::PATCH, todo::<_, requests::Update>())
self.do_call(Method::PATCH, |update::Args { id, update }| {
(
format_compact!("/games/{id}"),
requests::Update {
title: update.title,
description: update.description,
slug: update.slug,
thumbnail: update.thumbnail,
genres: update.genres,
badges: update.badges,
tags: update.tags,
screenshots: update.screenshots,
published: update.published,
},
)
})
}
}

View file

@ -2,7 +2,7 @@ use axum::{
http::StatusCode,
response::{IntoResponse, Response as AxumResponse},
};
use serde::{Serialize, Deserialize};
use serde::{Deserialize, Serialize};
use crate::format::{DumpParams, Format};
use crate::requests::{IsResponse, status_code::HasStatusCode};

View file

@ -174,11 +174,169 @@ fn users<T: Types>(router: RouterScope<T>) -> RouterScope<T> {
}
fn authors<T: Types>(router: RouterScope<T>) -> RouterScope<T> {
use crate::requests::authors::{Create, Get, Update};
use viendesu_core::{
requests::authors::{create, get, update},
service::authors::{AuthorsMut as _, AuthorsRef as _},
types::author,
};
router
.route(
"/",
post(async |mut session: SessionOf<T>, ctx: Ctx<Create>| {
let Create {
title,
slug,
description,
owner,
} = ctx.request;
session
.authors_mut()
.create()
.call(create::Args {
title,
slug,
description,
owner,
})
.await
}),
)
.route(
"/{selector}",
get(async |mut session: SessionOf<T>, mut ctx: Ctx<Get>| {
let author: author::Selector = ctx.path().await?;
let Get {} = ctx.request;
session.authors().get().call(get::Args { author }).await
}),
)
.route(
"/{selector}",
patch(async |mut session: SessionOf<T>, mut ctx: Ctx<Update>| {
let author: author::Selector = ctx.path().await?;
let Update {
title,
description,
pfp,
slug,
verified,
} = ctx.request;
session
.authors_mut()
.update()
.call(update::Args {
author,
update: update::Update {
title,
description,
pfp,
slug,
verified,
},
})
.await
}),
)
}
fn games<T: Types>(router: RouterScope<T>) -> RouterScope<T> {
use crate::requests::games::{Create, Get, Search, Update};
use viendesu_core::{
requests::games::{create, get, search, update},
service::games::{GamesMut as _, GamesRef as _},
types::{author, game},
};
router
.route(
"/",
post(async |mut session: SessionOf<T>, ctx: Ctx<Create>| {
let Create {
title,
description,
thumbnail,
author,
slug,
vndb,
release_date,
} = ctx.request;
session
.games_mut()
.create()
.call(create::Args {
title,
description,
thumbnail,
author,
slug,
vndb,
release_date,
})
.await
}),
)
.route(
"/{game_id}",
get(async |mut session: SessionOf<T>, mut ctx: Ctx<Get>| {
let game_id: game::Id = ctx.path().await?;
let Get {} = ctx.request;
session
.games()
.get()
.call(get::Args {
game: game_id.into(),
})
.await
}),
)
.route(
"/{author}/{slug}",
get(async |mut session: SessionOf<T>, mut ctx: Ctx<Get>| {
let (author, slug) = ctx.path::<(author::Selector, game::Slug)>().await?;
session
.games()
.get()
.call(get::Args {
game: game::Selector::FullyQualified(game::FullyQualified { author, slug }),
})
.await
}),
)
.route(
"/search",
post(async |mut session: SessionOf<T>, ctx: Ctx<Search>| {
let Search {
query,
author,
include,
exclude,
order,
sort_by,
limit,
} = ctx.request;
session
.games()
.search()
.call(search::Args {
query,
author,
include,
exclude,
order,
sort_by,
limit,
})
.await
}),
)
}
fn boards<T: Types>(router: RouterScope<T>) -> RouterScope<T> {