jacquard_api/chat_bsky/group/
request_join.rs1#[allow(unused_imports)]
9use alloc::collections::BTreeMap;
10
11use crate::chat_bsky::convo::ConvoView;
12#[allow(unused_imports)]
13use core::marker::PhantomData;
14use jacquard_common::deps::smol_str::SmolStr;
15use jacquard_common::types::value::Data;
16use jacquard_common::{BosStr, CowStr, DefaultStr, FromStaticStr};
17use jacquard_derive::{IntoStatic, open_union};
18use serde::{Deserialize, Serialize};
19
20#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
21#[serde(
22 rename_all = "camelCase",
23 bound(deserialize = "S: Deserialize<'de> + BosStr")
24)]
25pub struct RequestJoin<S: BosStr = DefaultStr> {
26 pub code: S,
27 #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
28 pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
29}
30
31#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
32#[serde(
33 rename_all = "camelCase",
34 bound(deserialize = "S: Deserialize<'de> + BosStr")
35)]
36pub struct RequestJoinOutput<S: BosStr = DefaultStr> {
37 #[serde(skip_serializing_if = "Option::is_none")]
39 pub convo: Option<ConvoView<S>>,
40 pub status: RequestJoinOutputStatus<S>,
41 #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
42 pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
43}
44
45#[derive(Debug, Clone, PartialEq, Eq, Hash)]
46pub enum RequestJoinOutputStatus<S: BosStr = DefaultStr> {
47 Joined,
48 Pending,
49 Other(S),
50}
51
52impl<S: BosStr> RequestJoinOutputStatus<S> {
53 pub fn as_str(&self) -> &str {
54 match self {
55 Self::Joined => "joined",
56 Self::Pending => "pending",
57 Self::Other(s) => s.as_ref(),
58 }
59 }
60 pub fn from_value(s: S) -> Self {
62 match s.as_ref() {
63 "joined" => Self::Joined,
64 "pending" => Self::Pending,
65 _ => Self::Other(s),
66 }
67 }
68}
69
70impl<S: BosStr> core::fmt::Display for RequestJoinOutputStatus<S> {
71 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
72 write!(f, "{}", self.as_str())
73 }
74}
75
76impl<S: BosStr> AsRef<str> for RequestJoinOutputStatus<S> {
77 fn as_ref(&self) -> &str {
78 self.as_str()
79 }
80}
81
82impl<S: BosStr> Serialize for RequestJoinOutputStatus<S> {
83 fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
84 where
85 Ser: serde::Serializer,
86 {
87 serializer.serialize_str(self.as_str())
88 }
89}
90
91impl<'de, S: Deserialize<'de> + BosStr> Deserialize<'de> for RequestJoinOutputStatus<S> {
92 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
93 where
94 D: serde::Deserializer<'de>,
95 {
96 let s = S::deserialize(deserializer)?;
97 Ok(Self::from_value(s))
98 }
99}
100
101impl<S: BosStr + Default> Default for RequestJoinOutputStatus<S> {
102 fn default() -> Self {
103 Self::Other(Default::default())
104 }
105}
106
107impl<S: BosStr> jacquard_common::IntoStatic for RequestJoinOutputStatus<S>
108where
109 S: BosStr + jacquard_common::IntoStatic,
110 S::Output: BosStr,
111{
112 type Output = RequestJoinOutputStatus<S::Output>;
113 fn into_static(self) -> Self::Output {
114 match self {
115 RequestJoinOutputStatus::Joined => RequestJoinOutputStatus::Joined,
116 RequestJoinOutputStatus::Pending => RequestJoinOutputStatus::Pending,
117 RequestJoinOutputStatus::Other(v) => RequestJoinOutputStatus::Other(v.into_static()),
118 }
119 }
120}
121
122#[derive(
123 Serialize, Deserialize, Debug, Clone, PartialEq, Eq, thiserror::Error, miette::Diagnostic,
124)]
125#[serde(tag = "error", content = "message")]
126pub enum RequestJoinError {
127 #[serde(rename = "ConvoLocked")]
128 ConvoLocked(Option<SmolStr>),
129 #[serde(rename = "FollowRequired")]
130 FollowRequired(Option<SmolStr>),
131 #[serde(rename = "InvalidCode")]
132 InvalidCode(Option<SmolStr>),
133 #[serde(rename = "LinkDisabled")]
134 LinkDisabled(Option<SmolStr>),
135 #[serde(rename = "MemberLimitReached")]
136 MemberLimitReached(Option<SmolStr>),
137 #[serde(rename = "UserKicked")]
138 UserKicked(Option<SmolStr>),
139 #[serde(untagged)]
141 Other {
142 error: SmolStr,
143 message: Option<SmolStr>,
144 },
145}
146
147impl core::fmt::Display for RequestJoinError {
148 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
149 match self {
150 Self::ConvoLocked(msg) => {
151 write!(f, "ConvoLocked")?;
152 if let Some(msg) = msg {
153 write!(f, ": {}", msg)?;
154 }
155 Ok(())
156 }
157 Self::FollowRequired(msg) => {
158 write!(f, "FollowRequired")?;
159 if let Some(msg) = msg {
160 write!(f, ": {}", msg)?;
161 }
162 Ok(())
163 }
164 Self::InvalidCode(msg) => {
165 write!(f, "InvalidCode")?;
166 if let Some(msg) = msg {
167 write!(f, ": {}", msg)?;
168 }
169 Ok(())
170 }
171 Self::LinkDisabled(msg) => {
172 write!(f, "LinkDisabled")?;
173 if let Some(msg) = msg {
174 write!(f, ": {}", msg)?;
175 }
176 Ok(())
177 }
178 Self::MemberLimitReached(msg) => {
179 write!(f, "MemberLimitReached")?;
180 if let Some(msg) = msg {
181 write!(f, ": {}", msg)?;
182 }
183 Ok(())
184 }
185 Self::UserKicked(msg) => {
186 write!(f, "UserKicked")?;
187 if let Some(msg) = msg {
188 write!(f, ": {}", msg)?;
189 }
190 Ok(())
191 }
192 Self::Other { error, message } => {
193 write!(f, "{}", error)?;
194 if let Some(msg) = message {
195 write!(f, ": {}", msg)?;
196 }
197 Ok(())
198 }
199 }
200 }
201}
202
203pub struct RequestJoinResponse;
207impl jacquard_common::xrpc::XrpcResp for RequestJoinResponse {
208 const NSID: &'static str = "chat.bsky.group.requestJoin";
209 const ENCODING: &'static str = "application/json";
210 type Output<S: BosStr> = RequestJoinOutput<S>;
211 type Err = RequestJoinError;
212}
213
214impl<S: BosStr> jacquard_common::xrpc::XrpcRequest for RequestJoin<S> {
215 const NSID: &'static str = "chat.bsky.group.requestJoin";
216 const METHOD: jacquard_common::xrpc::XrpcMethod =
217 jacquard_common::xrpc::XrpcMethod::Procedure("application/json");
218 type Response = RequestJoinResponse;
219}
220
221pub struct RequestJoinRequest;
225impl jacquard_common::xrpc::XrpcEndpoint for RequestJoinRequest {
226 const PATH: &'static str = "/xrpc/chat.bsky.group.requestJoin";
227 const METHOD: jacquard_common::xrpc::XrpcMethod =
228 jacquard_common::xrpc::XrpcMethod::Procedure("application/json");
229 type Request<S: BosStr> = RequestJoin<S>;
230 type Response = RequestJoinResponse;
231}