diff --git a/Cargo.lock b/Cargo.lock index 0761aab..2fcf31d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,7 +20,7 @@ dependencies = [ "enum_delegate", "futures", "futures-core", - "http", + "http 1.1.0", "http-signature-normalization", "http-signature-normalization-reqwest", "httpdate", @@ -214,7 +214,7 @@ dependencies = [ "axum-core", "bytes", "futures-util", - "http", + "http 1.1.0", "http-body", "http-body-util", "hyper", @@ -248,7 +248,7 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http", + "http 1.1.0", "http-body", "http-body-util", "mime", @@ -271,7 +271,7 @@ dependencies = [ "bytes", "cookie", "futures-util", - "http", + "http 1.1.0", "http-body", "http-body-util", "mime", @@ -1440,6 +1440,108 @@ dependencies = [ "regex", ] +[[package]] +name = "gloo" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d15282ece24eaf4bd338d73ef580c6714c8615155c4190c781290ee3fa0fd372" +dependencies = [ + "gloo-console", + "gloo-dialogs", + "gloo-events", + "gloo-file", + "gloo-history", + "gloo-net 0.5.0", + "gloo-render", + "gloo-storage", + "gloo-timers", + "gloo-utils", + "gloo-worker", +] + +[[package]] +name = "gloo-console" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a17868f56b4a24f677b17c8cb69958385102fa879418052d60b50bc1727e261" +dependencies = [ + "gloo-utils", + "js-sys", + "serde", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-dialogs" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4748e10122b01435750ff530095b1217cf6546173459448b83913ebe7815df" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-events" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27c26fb45f7c385ba980f5fa87ac677e363949e065a083722697ef1b2cc91e41" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-file" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97563d71863fb2824b2e974e754a81d19c4a7ec47b09ced8a0e6656b6d54bd1f" +dependencies = [ + "gloo-events", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-history" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "903f432be5ba34427eac5e16048ef65604a82061fe93789f2212afc73d8617d6" +dependencies = [ + "getrandom", + "gloo-events", + "gloo-utils", + "serde", + "serde-wasm-bindgen", + "serde_urlencoded", + "thiserror 1.0.69", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-net" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43aaa242d1239a8822c15c645f02166398da4f8b5c4bae795c1f5b44e9eee173" +dependencies = [ + "futures-channel", + "futures-core", + "futures-sink", + "gloo-utils", + "http 0.2.12", + "js-sys", + "pin-project", + "serde", + "serde_json", + "thiserror 1.0.69", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "gloo-net" version = "0.6.0" @@ -1450,7 +1552,7 @@ dependencies = [ "futures-core", "futures-sink", "gloo-utils", - "http", + "http 1.1.0", "js-sys", "pin-project", "serde", @@ -1461,6 +1563,31 @@ dependencies = [ "web-sys", ] +[[package]] +name = "gloo-render" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56008b6744713a8e8d98ac3dcb7d06543d5662358c9c805b4ce2167ad4649833" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-storage" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc8031e8c92758af912f9bc08fbbadd3c6f3cfcbf6b64cdf3d6a81f0139277a" +dependencies = [ + "gloo-utils", + "js-sys", + "serde", + "serde_json", + "thiserror 1.0.69", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "gloo-timers" version = "0.3.0" @@ -1486,6 +1613,37 @@ dependencies = [ "web-sys", ] +[[package]] +name = "gloo-worker" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "085f262d7604911c8150162529cefab3782e91adb20202e8658f7275d2aefe5d" +dependencies = [ + "bincode", + "futures", + "gloo-utils", + "gloo-worker-macros", + "js-sys", + "pinned", + "serde", + "thiserror 1.0.69", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "gloo-worker-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956caa58d4857bc9941749d55e4bd3000032d8212762586fa5705632967140e7" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "guardian" version = "1.2.0" @@ -1503,7 +1661,7 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http", + "http 1.1.0", "indexmap", "slab", "tokio", @@ -1563,6 +1721,17 @@ dependencies = [ "utf8-width", ] +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http" version = "1.1.0" @@ -1581,7 +1750,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http", + "http 1.1.0", ] [[package]] @@ -1592,7 +1761,7 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", "futures-util", - "http", + "http 1.1.0", "http-body", "pin-project-lite", ] @@ -1667,7 +1836,7 @@ dependencies = [ "futures-channel", "futures-util", "h2", - "http", + "http 1.1.0", "http-body", "httparse", "httpdate", @@ -1685,7 +1854,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", - "http", + "http 1.1.0", "hyper", "hyper-util", "rustls", @@ -1721,7 +1890,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http", + "http 1.1.0", "http-body", "hyper", "pin-project-lite", @@ -1779,6 +1948,7 @@ dependencies = [ "env_logger", "futures", "getrandom", + "gloo", "hex", "jsonwebtoken", "katex", @@ -2139,7 +2309,7 @@ dependencies = [ "default-struct-builder", "futures-util", "gloo-timers", - "http", + "http 1.1.0", "js-sys", "lazy_static", "leptos", @@ -2285,7 +2455,7 @@ dependencies = [ "any_spawner", "either_of", "futures", - "gloo-net", + "gloo-net 0.6.0", "js-sys", "leptos", "leptos_router_macro", @@ -2612,7 +2782,7 @@ dependencies = [ "bytes", "encoding_rs", "futures-util", - "http", + "http 1.1.0", "httparse", "memchr", "mime", @@ -2953,6 +3123,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pinned" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a829027bd95e54cfe13e3e258a1ae7b645960553fb82b75ff852c29688ee595b" +dependencies = [ + "futures", + "rustversion", + "thiserror 1.0.69", +] + [[package]] name = "pkcs1" version = "0.7.5" @@ -3037,6 +3218,16 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -3420,7 +3611,7 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http", + "http 1.1.0", "http-body", "http-body-util", "hyper", @@ -3466,7 +3657,7 @@ checksum = "562ceb5a604d3f7c885a792d42c199fd8af239d0a51b2fa6a78aafa092452b04" dependencies = [ "anyhow", "async-trait", - "http", + "http 1.1.0", "reqwest", "serde", "thiserror 1.0.69", @@ -3726,6 +3917,17 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-wasm-bindgen" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + [[package]] name = "serde_derive" version = "1.0.215" @@ -3803,8 +4005,8 @@ dependencies = [ "const_format", "dashmap", "futures", - "gloo-net", - "http", + "gloo-net 0.6.0", + "http 1.1.0", "http-body-util", "hyper", "inventory", @@ -4338,7 +4540,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_edit 0.22.22", ] [[package]] @@ -4350,6 +4552,17 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow 0.5.40", +] + [[package]] name = "toml_edit" version = "0.22.22" @@ -4360,7 +4573,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.6.20", ] [[package]] @@ -4403,7 +4616,7 @@ dependencies = [ "bitflags 2.6.0", "bytes", "futures-util", - "http", + "http 1.1.0", "http-body", "http-body-util", "http-range-header", @@ -4428,7 +4641,7 @@ dependencies = [ "bitflags 2.6.0", "bytes", "futures-util", - "http", + "http 1.1.0", "http-body", "http-body-util", "http-range-header", @@ -4939,6 +5152,15 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + [[package]] name = "winnow" version = "0.6.20" diff --git a/Cargo.toml b/Cargo.toml index b3fb05f..05452e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -121,6 +121,7 @@ tower = { version = "0.5.1", optional = true } tower-layer = { version = "0.3.3", optional = true } console_log = "1.0.0" send_wrapper = "0.6.0" +gloo = "0.11.0" [dev-dependencies] pretty_assertions = "1.4.1" diff --git a/src/frontend/api.rs b/src/frontend/api.rs index 522bbae..34fac6f 100644 --- a/src/frontend/api.rs +++ b/src/frontend/api.rs @@ -2,38 +2,18 @@ use crate::{ common::{ newtypes::{ArticleId, ConflictId}, utils::http_protocol_str, - ApiConflict, - ApproveArticleForm, - ArticleView, - CreateArticleForm, - DbArticle, - DbInstance, - DbPerson, - DeleteConflictForm, - EditArticleForm, - FollowInstance, - ForkArticleForm, - GetArticleForm, - GetInstance, - GetUserForm, - InstanceView, - ListArticlesForm, - LocalUserView, - LoginUserForm, - Notification, - ProtectArticleForm, - RegisterUserForm, - ResolveObject, - SearchArticleForm, - SiteView, + ApiConflict, ApproveArticleForm, ArticleView, CreateArticleForm, DbArticle, DbInstance, + DbPerson, DeleteConflictForm, EditArticleForm, FollowInstance, ForkArticleForm, + GetArticleForm, GetInstance, GetUserForm, InstanceView, ListArticlesForm, LocalUserView, + LoginUserForm, Notification, ProtectArticleForm, RegisterUserForm, ResolveObject, + SearchArticleForm, SiteView, }, frontend::error::MyResult, }; use anyhow::anyhow; use reqwest::{Client, RequestBuilder, StatusCode}; -use send_wrapper::SendWrapper; use serde::{Deserialize, Serialize}; -use std::{future::Future, sync::LazyLock}; +use std::sync::LazyLock; use url::Url; pub static CLIENT: LazyLock = LazyLock::new(|| ApiClient::new(Client::new(), None)); @@ -73,7 +53,7 @@ impl ApiClient { } } - async fn get_query(&self, endpoint: &str, query: Option) -> MyResult + async fn get(&self, endpoint: &str, query: Option) -> MyResult where T: for<'de> Deserialize<'de>, R: Serialize, @@ -82,280 +62,192 @@ impl ApiClient { if let Some(query) = query { req = req.query(&query); } - handle_json_res::(req).await + send::(req).await } - pub fn get_article( - &self, - data: GetArticleForm, - ) -> impl Future> + Send + '_ { - SendWrapper::new(async move { self.get_query("/api/v1/article", Some(data)).await }) + pub async fn get_article(&self, data: GetArticleForm) -> MyResult { + self.get("/api/v1/article", Some(data)).await } - pub fn list_articles( - &self, - data: ListArticlesForm, - ) -> impl Future>> + Send + '_ { - SendWrapper::new(async move { self.get_query("/api/v1/article/list", Some(data)).await }) + pub async fn list_articles(&self, data: ListArticlesForm) -> MyResult> { + self.get("/api/v1/article/list", Some(data)).await } - pub fn register( + pub async fn register(&self, register_form: RegisterUserForm) -> MyResult { + let req = self + .client + .post(self.request_endpoint("/api/v1/account/register")) + .form(®ister_form); + send::(req).await + } + + pub async fn login(&self, login_form: LoginUserForm) -> MyResult { + let req = self + .client + .post(self.request_endpoint("/api/v1/account/login")) + .form(&login_form); + send::(req).await + } + + pub async fn create_article(&self, data: &CreateArticleForm) -> MyResult { + let req = self + .client + .post(self.request_endpoint("/api/v1/article")) + .form(data); + send(req).await + } + + pub async fn edit_article_with_conflict( &self, - register_form: RegisterUserForm, - ) -> impl Future> + Send + '_ { - SendWrapper::new(async move { - let req = self - .client - .post(self.request_endpoint("/api/v1/account/register")) - .form(®ister_form); - handle_json_res::(req).await + edit_form: &EditArticleForm, + ) -> MyResult> { + let req = self + .client + .patch(self.request_endpoint("/api/v1/article")) + .form(edit_form); + send(req).await + } + + pub async fn edit_article(&self, edit_form: &EditArticleForm) -> MyResult { + let edit_res = self.edit_article_with_conflict(edit_form).await?; + assert!(edit_res.is_none()); + + self.get_article(GetArticleForm { + title: None, + domain: None, + id: Some(edit_form.article_id), }) + .await } - pub fn login( + pub async fn notifications_list(&self) -> MyResult> { + let req = self + .client + .get(self.request_endpoint("/api/v1/user/notifications/list")); + send(req).await + } + + pub async fn notifications_count(&self) -> MyResult { + let req = self + .client + .get(self.request_endpoint("/api/v1/user/notifications/count")); + send(req).await + } + + pub async fn approve_article(&self, article_id: ArticleId, approve: bool) -> MyResult<()> { + let form = ApproveArticleForm { + article_id, + approve, + }; + let req = self + .client + .post(self.request_endpoint("/api/v1/article/approve")) + .form(&form); + send(req).await + } + + pub async fn delete_conflict(&self, conflict_id: ConflictId) -> MyResult<()> { + let form = DeleteConflictForm { conflict_id }; + let req = self + .client + .delete(self.request_endpoint("/api/v1/conflict")) + .form(&form); + send(req).await + } + + pub async fn search(&self, search_form: &SearchArticleForm) -> MyResult> { + self.get("/api/v1/search", Some(search_form)).await + } + + pub async fn get_local_instance(&self) -> MyResult { + self.get("/api/v1/instance", None::).await + } + + pub async fn get_instance(&self, get_form: &GetInstance) -> MyResult { + self.get("/api/v1/instance", Some(get_form)).await + } + + pub async fn list_instances(&self) -> MyResult> { + self.get("/api/v1/instance/list", None::).await + } + + pub async fn follow_instance_with_resolve( &self, - login_form: LoginUserForm, - ) -> impl Future> + Send + '_ { - SendWrapper::new(async move { - let req = self - .client - .post(self.request_endpoint("/api/v1/account/login")) - .form(&login_form); - handle_json_res::(req).await - }) + follow_instance: &str, + ) -> MyResult { + // fetch beta instance on alpha + let resolve_form = ResolveObject { + id: Url::parse(&format!("{}://{}", http_protocol_str(), follow_instance))?, + }; + let instance_resolved: DbInstance = self + .get("/api/v1/instance/resolve", Some(resolve_form)) + .await?; + + // send follow + let follow_form = FollowInstance { + id: instance_resolved.id, + }; + self.follow_instance(follow_form).await?; + Ok(instance_resolved) } - pub fn create_article( - &self, - data: CreateArticleForm, - ) -> impl Future> + Send + '_ { - SendWrapper::new(async move { - let req = self - .client - .post(self.request_endpoint("/api/v1/article")) - .form(&data); - handle_json_res(req).await - }) - } - - pub fn edit_article_with_conflict( - &self, - edit_form: EditArticleForm, - ) -> impl Future>> + Send + '_ { - SendWrapper::new(async move { - let req = self - .client - .patch(self.request_endpoint("/api/v1/article")) - .form(&edit_form); - handle_json_res(req).await - }) - } - - pub fn edit_article( - &self, - edit_form: EditArticleForm, - ) -> impl Future> + Send + '_ { - SendWrapper::new(async move { - let article_id = edit_form.article_id; - let edit_res = self.edit_article_with_conflict(edit_form).await?; - assert!(edit_res.is_none()); - - self.get_article(GetArticleForm { - title: None, - domain: None, - id: Some(article_id), - }) - .await - }) - } - - pub fn notifications_list( - &self, - ) -> impl Future>> + Send + '_ { - SendWrapper::new(async move { - let req = self - .client - .get(self.request_endpoint("/api/v1/user/notifications/list")); - handle_json_res(req).await - }) - } - - pub fn notifications_count(&self) -> impl Future> + Send + '_ { - SendWrapper::new(async move { - let req = self - .client - .get(self.request_endpoint("/api/v1/user/notifications/count")); - handle_json_res(req).await - }) - } - - pub fn approve_article( - &self, - article_id: ArticleId, - approve: bool, - ) -> impl Future> + Send + '_ { - SendWrapper::new(async move { - let form = ApproveArticleForm { - article_id, - approve, - }; - let req = self - .client - .post(self.request_endpoint("/api/v1/article/approve")) - .form(&form); - handle_json_res(req).await - }) - } - - pub fn delete_conflict( - &self, - conflict_id: ConflictId, - ) -> impl Future> + Send + '_ { - SendWrapper::new(async move { - let form = DeleteConflictForm { conflict_id }; - let req = self - .client - .delete(self.request_endpoint("/api/v1/conflict")) - .form(&form); - handle_json_res(req).await - }) - } - - pub fn search( - &self, - search_form: SearchArticleForm, - ) -> impl Future>> + Send + '_ { - SendWrapper::new(async move { self.get_query("/api/v1/search", Some(search_form)).await }) - } - - pub fn get_local_instance( - &self, - ) -> impl Future>> + Send + '_ { - SendWrapper::new(async move { self.get_query("/api/v1/instance", None::).await }) - } - - pub fn get_instance( - &self, - get_form: GetInstance, - ) -> impl Future> + Send + '_ { - SendWrapper::new(async move { self.get_query("/api/v1/instance", Some(get_form)).await }) - } - - pub fn list_instances(&self) -> impl Future>> + Send + '_ { - SendWrapper::new(async move { self.get_query("/api/v1/instance/list", None::).await }) - } - - pub fn follow_instance_with_resolve( - &self, - follow_instance: String, - ) -> impl Future> + Send + '_ { - SendWrapper::new(async move { - // fetch beta instance on alpha - let resolve_form = ResolveObject { - id: Url::parse(&format!("{}://{}", http_protocol_str(), follow_instance))?, - }; - let instance_resolved: DbInstance = self - .get_query("/api/v1/instance/resolve", Some(resolve_form)) - .await?; - - // send follow - let follow_form = FollowInstance { - id: instance_resolved.id, - }; - self.follow_instance(follow_form).await?; - Ok(instance_resolved) - }) - } - - pub fn follow_instance( - &self, - follow_form: FollowInstance, - ) -> impl Future> + Send + '_ { - SendWrapper::new(async move { - // cant use post helper because follow doesnt return json - let res = self - .client - .post(self.request_endpoint("/api/v1/instance/follow")) - .form(&follow_form) - .send() - .await?; - if res.status() == StatusCode::OK { - Ok(()) - } else { - Err(anyhow!("API error: {}", res.text().await?).into()) - } - }) - } - - pub fn site(&self) -> impl Future> + Send + '_ { - SendWrapper::new(async move { - let req = self.client.get(self.request_endpoint("/api/v1/site")); - handle_json_res(req).await - }) - } - - pub fn logout(&self) -> impl Future> + Send + '_ { - SendWrapper::new(async move { - self.client - .get(self.request_endpoint("/api/v1/account/logout")) - .send() - .await?; + pub async fn follow_instance(&self, follow_form: FollowInstance) -> MyResult<()> { + // cant use post helper because follow doesnt return json + let res = self + .client + .post(self.request_endpoint("/api/v1/instance/follow")) + .form(&follow_form) + .send() + .await?; + if res.status() == StatusCode::OK { Ok(()) - }) + } else { + Err(anyhow!("API error: {}", res.text().await?).into()) + } } - pub fn fork_article( - &self, - form: ForkArticleForm, - ) -> impl Future> + Send + '_ { - SendWrapper::new(async move { - let req = self - .client - .post(self.request_endpoint("/api/v1/article/fork")) - .form(&form); - Ok(handle_json_res(req).await.unwrap()) - }) + pub async fn site(&self) -> MyResult { + let req = self.client.get(self.request_endpoint("/api/v1/site")); + send(req).await } - pub fn protect_article( - &self, - params: ProtectArticleForm, - ) -> impl Future> + Send + '_ { - SendWrapper::new(async move { - let req = self - .client - .post(self.request_endpoint("/api/v1/article/protect")) - .form(¶ms); - handle_json_res(req).await - }) + pub async fn logout(&self) -> MyResult<()> { + self.client + .get(self.request_endpoint("/api/v1/account/logout")) + .send() + .await?; + Ok(()) } - pub fn resolve_article( - &self, - id: Url, - ) -> impl Future> + Send + '_ { - SendWrapper::new(async move { - let resolve_object = ResolveObject { id }; - self.get_query("/api/v1/article/resolve", Some(resolve_object)) - .await - }) + pub async fn fork_article(&self, form: &ForkArticleForm) -> MyResult { + let req = self + .client + .post(self.request_endpoint("/api/v1/article/fork")) + .form(form); + Ok(send(req).await.unwrap()) } - pub fn resolve_instance( - &self, - id: Url, - ) -> impl Future> + Send + '_ { - SendWrapper::new(async move { - let resolve_object = ResolveObject { id }; - self.get_query("/api/v1/instance/resolve", Some(resolve_object)) - .await - }) + pub async fn protect_article(&self, params: &ProtectArticleForm) -> MyResult { + let req = self + .client + .post(self.request_endpoint("/api/v1/article/protect")) + .form(params); + send(req).await } - pub fn get_user( - &self, - data: GetUserForm, - ) -> impl Future> + Send + '_ { - SendWrapper::new(async move { self.get_query("/api/v1/user", Some(data)).await }) + + pub async fn resolve_article(&self, id: Url) -> MyResult { + let resolve_object = ResolveObject { id }; + self.get("/api/v1/article/resolve", Some(resolve_object)) + .await + } + + pub async fn resolve_instance(&self, id: Url) -> MyResult { + let resolve_object = ResolveObject { id }; + self.get("/api/v1/instance/resolve", Some(resolve_object)) + .await + } + pub async fn get_user(&self, data: GetUserForm) -> MyResult { + self.get("/api/v1/user", Some(data)).await } fn request_endpoint(&self, path: &str) -> String { @@ -364,7 +256,7 @@ impl ApiClient { } } -async fn handle_json_res(mut req: RequestBuilder) -> MyResult +async fn send(#[allow(unused_mut)] mut req: RequestBuilder) -> MyResult where T: for<'de> Deserialize<'de>, {