vn_core/http/request/
post.rs1use super::request_json;
2use crate::error::Result;
3use crate::http::{Endpoint, JsonQueryBuilder as Query, UrlQueryParams};
4use crate::make_request;
5use crate::model::prelude::*;
6use crate::vndb::{Token, Vndb};
7use http::Method;
8use serde::Serialize;
9use serde::de::DeserializeOwned;
10use std::sync::Weak;
11use tokio::sync::Semaphore;
12use tokio::time::Duration;
13
14pub mod prelude {
15 pub use super::{
16 CharacterQuery, Post, ProducerQuery, ReleaseQuery, StaffQuery, TagQuery, TraitQuery,
17 VisualNovelQuery,
18 };
19}
20
21pub type CharacterQuery = Query<CharacterField, SortCharacterBy, Response<Character>>;
22pub type ProducerQuery = Query<ProducerField, SortProducerBy, Response<Producer>>;
23pub type ReleaseQuery = Query<ReleaseField, SortReleaseBy, Response<Release>>;
24pub type StaffQuery = Query<StaffField, SortStaffBy, Response<Staff>>;
25pub type TagQuery = Query<TagField, SortTagBy, Response<Tag>>;
26pub type TraitQuery = Query<TraitField, SortTraitBy, Response<Trait>>;
27pub type VisualNovelQuery = Query<VisualNovelField, SortVisualNovelBy, Response<VisualNovel>>;
28
29pub struct Post {
30 vndb: Weak<Vndb>,
31}
32
33macro_rules! post_request {
34 ($self:expr, $kind:ident, $endpoint:ident) => {{
35 let vndb = Weak::clone(&$self.vndb);
36 $kind::new(Box::new(move |query| {
37 Box::pin(async move {
38 let vndb = Vndb::upgrade(&vndb)?;
39 make_request!(vndb, post_json(Endpoint::$endpoint, &query))
40 })
41 }))
42 }};
43}
44
45impl Post {
46 pub fn new(vndb: Weak<Vndb>) -> Self {
47 Self { vndb }
48 }
49
50 pub fn character(&self) -> CharacterQuery {
51 post_request!(self, CharacterQuery, Character)
52 }
53
54 pub fn producer(&self) -> ProducerQuery {
55 post_request!(self, ProducerQuery, Producer)
56 }
57
58 pub fn release(&self) -> ReleaseQuery {
59 post_request!(self, ReleaseQuery, Release)
60 }
61
62 pub fn staff(&self) -> StaffQuery {
63 post_request!(self, StaffQuery, Staff)
64 }
65
66 pub fn tag(&self) -> TagQuery {
67 post_request!(self, TagQuery, Tag)
68 }
69
70 pub fn r#trait(&self) -> TraitQuery {
71 post_request!(self, TraitQuery, Trait)
72 }
73
74 pub fn visual_novel(&self) -> VisualNovelQuery {
75 post_request!(self, VisualNovelQuery, VisualNovel)
76 }
77}
78
79impl Clone for Post {
80 fn clone(&self) -> Self {
81 Self { vndb: Weak::clone(&self.vndb) }
82 }
83}
84
85#[bon::builder]
86async fn post_json<Body, Json>(
87 #[builder(start_fn)] endpoint: Endpoint,
88 #[builder(start_fn)] body: &Body,
89 query: Option<UrlQueryParams>,
90 semaphore: Weak<Semaphore>,
91 token: Option<&Token>,
92 delay: Option<Duration>,
93 timeout: Option<Duration>,
94 user_agent: Option<&str>,
95) -> Result<Json>
96where
97 Body: Serialize + ?Sized,
98 Json: DeserializeOwned,
99{
100 request_json(endpoint)
101 .method(Method::POST)
102 .semaphore(semaphore)
103 .body(body)
104 .maybe_query(query)
105 .maybe_token(token)
106 .maybe_delay(delay)
107 .maybe_timeout(timeout)
108 .maybe_user_agent(user_agent)
109 .call()
110 .await
111}