Skip to main content

vn_core/http/request/
post.rs

1use 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}