1#[allow(unused_imports)]
9use alloc::collections::BTreeMap;
10
11#[allow(unused_imports)]
12use core::marker::PhantomData;
13use jacquard_common::{BosStr, CowStr, DefaultStr, FromStaticStr};
14
15#[allow(unused_imports)]
16use jacquard_common::deps::codegen::unicode_segmentation::UnicodeSegmentation;
17use jacquard_common::deps::smol_str::SmolStr;
18use jacquard_common::types::string::{Datetime, Did};
19use jacquard_common::types::value::Data;
20use jacquard_derive::{IntoStatic, open_union};
21use jacquard_lexicon::lexicon::LexiconDoc;
22use jacquard_lexicon::schema::LexiconSchema;
23
24use crate::com_atproto::admin::RepoRef;
25use crate::com_atproto::moderation::ReasonType;
26use crate::com_atproto::moderation::create_report;
27use crate::com_atproto::repo::strong_ref::StrongRef;
28#[allow(unused_imports)]
29use jacquard_lexicon::validation::{ConstraintError, ValidationPath};
30use serde::{Deserialize, Serialize};
31
32#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
33#[serde(
34 rename_all = "camelCase",
35 bound(deserialize = "S: Deserialize<'de> + BosStr")
36)]
37pub struct CreateReport<S: BosStr = DefaultStr> {
38 #[serde(skip_serializing_if = "Option::is_none")]
39 pub mod_tool: Option<create_report::ModTool<S>>,
40 #[serde(skip_serializing_if = "Option::is_none")]
42 pub reason: Option<S>,
43 pub reason_type: ReasonType<S>,
45 pub subject: CreateReportSubject<S>,
46 #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
47 pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
48}
49
50#[open_union]
51#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
52#[serde(tag = "$type", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
53pub enum CreateReportSubject<S: BosStr = DefaultStr> {
54 #[serde(rename = "com.atproto.admin.defs#repoRef")]
55 RepoRef(Box<RepoRef<S>>),
56 #[serde(rename = "com.atproto.repo.strongRef")]
57 StrongRef(Box<StrongRef<S>>),
58}
59
60#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
61#[serde(
62 rename_all = "camelCase",
63 bound(deserialize = "S: Deserialize<'de> + BosStr")
64)]
65pub struct CreateReportOutput<S: BosStr = DefaultStr> {
66 pub created_at: Datetime,
67 pub id: i64,
68 #[serde(skip_serializing_if = "Option::is_none")]
69 pub reason: Option<S>,
70 pub reason_type: ReasonType<S>,
71 pub reported_by: Did<S>,
72 pub subject: CreateReportOutputSubject<S>,
73 #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
74 pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
75}
76
77#[open_union]
78#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
79#[serde(tag = "$type", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
80pub enum CreateReportOutputSubject<S: BosStr = DefaultStr> {
81 #[serde(rename = "com.atproto.admin.defs#repoRef")]
82 RepoRef(Box<RepoRef<S>>),
83 #[serde(rename = "com.atproto.repo.strongRef")]
84 StrongRef(Box<StrongRef<S>>),
85}
86
87#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
90#[serde(
91 rename_all = "camelCase",
92 bound(deserialize = "S: Deserialize<'de> + BosStr")
93)]
94pub struct ModTool<S: BosStr = DefaultStr> {
95 #[serde(skip_serializing_if = "Option::is_none")]
97 pub meta: Option<Data<S>>,
98 pub name: S,
100 #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
101 pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
102}
103
104pub struct CreateReportResponse;
108impl jacquard_common::xrpc::XrpcResp for CreateReportResponse {
109 const NSID: &'static str = "com.atproto.moderation.createReport";
110 const ENCODING: &'static str = "application/json";
111 type Output<S: BosStr> = CreateReportOutput<S>;
112 type Err = jacquard_common::xrpc::GenericError;
113}
114
115impl<S: BosStr> jacquard_common::xrpc::XrpcRequest for CreateReport<S> {
116 const NSID: &'static str = "com.atproto.moderation.createReport";
117 const METHOD: jacquard_common::xrpc::XrpcMethod =
118 jacquard_common::xrpc::XrpcMethod::Procedure("application/json");
119 type Response = CreateReportResponse;
120}
121
122pub struct CreateReportRequest;
126impl jacquard_common::xrpc::XrpcEndpoint for CreateReportRequest {
127 const PATH: &'static str = "/xrpc/com.atproto.moderation.createReport";
128 const METHOD: jacquard_common::xrpc::XrpcMethod =
129 jacquard_common::xrpc::XrpcMethod::Procedure("application/json");
130 type Request<S: BosStr> = CreateReport<S>;
131 type Response = CreateReportResponse;
132}
133
134impl<S: BosStr> LexiconSchema for ModTool<S> {
135 fn nsid() -> &'static str {
136 "com.atproto.moderation.createReport"
137 }
138 fn def_name() -> &'static str {
139 "modTool"
140 }
141 fn lexicon_doc() -> LexiconDoc<'static> {
142 lexicon_doc_com_atproto_moderation_createReport()
143 }
144 fn validate(&self) -> Result<(), ConstraintError> {
145 Ok(())
146 }
147}
148
149pub mod create_report_state {
150
151 pub use crate::builder_types::{IsSet, IsUnset, Set, Unset};
152 #[allow(unused)]
153 use ::core::marker::PhantomData;
154 mod sealed {
155 pub trait Sealed {}
156 }
157 pub trait State: sealed::Sealed {
159 type ReasonType;
160 type Subject;
161 }
162 pub struct Empty(());
164 impl sealed::Sealed for Empty {}
165 impl State for Empty {
166 type ReasonType = Unset;
167 type Subject = Unset;
168 }
169 pub struct SetReasonType<St: State = Empty>(PhantomData<fn() -> St>);
171 impl<St: State> sealed::Sealed for SetReasonType<St> {}
172 impl<St: State> State for SetReasonType<St> {
173 type ReasonType = Set<members::reason_type>;
174 type Subject = St::Subject;
175 }
176 pub struct SetSubject<St: State = Empty>(PhantomData<fn() -> St>);
178 impl<St: State> sealed::Sealed for SetSubject<St> {}
179 impl<St: State> State for SetSubject<St> {
180 type ReasonType = St::ReasonType;
181 type Subject = Set<members::subject>;
182 }
183 #[allow(non_camel_case_types)]
185 pub mod members {
186 pub struct reason_type(());
188 pub struct subject(());
190 }
191}
192
193pub struct CreateReportBuilder<St: create_report_state::State, S: BosStr = DefaultStr> {
195 _state: PhantomData<fn() -> St>,
196 _fields: (
197 Option<create_report::ModTool<S>>,
198 Option<S>,
199 Option<ReasonType<S>>,
200 Option<CreateReportSubject<S>>,
201 ),
202 _type: PhantomData<fn() -> S>,
203}
204
205impl CreateReport<DefaultStr> {
206 pub fn new() -> CreateReportBuilder<create_report_state::Empty, DefaultStr> {
208 CreateReportBuilder::new()
209 }
210}
211
212impl<S: BosStr> CreateReport<S> {
213 pub fn builder() -> CreateReportBuilder<create_report_state::Empty, S> {
215 CreateReportBuilder::builder()
216 }
217}
218
219impl CreateReportBuilder<create_report_state::Empty, DefaultStr> {
220 pub fn new() -> Self {
222 CreateReportBuilder {
223 _state: PhantomData,
224 _fields: (None, None, None, None),
225 _type: PhantomData,
226 }
227 }
228}
229
230impl<S: BosStr> CreateReportBuilder<create_report_state::Empty, S> {
231 pub fn builder() -> Self {
233 CreateReportBuilder {
234 _state: PhantomData,
235 _fields: (None, None, None, None),
236 _type: PhantomData,
237 }
238 }
239}
240
241impl<St: create_report_state::State, S: BosStr> CreateReportBuilder<St, S> {
242 pub fn mod_tool(mut self, value: impl Into<Option<create_report::ModTool<S>>>) -> Self {
244 self._fields.0 = value.into();
245 self
246 }
247 pub fn maybe_mod_tool(mut self, value: Option<create_report::ModTool<S>>) -> Self {
249 self._fields.0 = value;
250 self
251 }
252}
253
254impl<St: create_report_state::State, S: BosStr> CreateReportBuilder<St, S> {
255 pub fn reason(mut self, value: impl Into<Option<S>>) -> Self {
257 self._fields.1 = value.into();
258 self
259 }
260 pub fn maybe_reason(mut self, value: Option<S>) -> Self {
262 self._fields.1 = value;
263 self
264 }
265}
266
267impl<St, S: BosStr> CreateReportBuilder<St, S>
268where
269 St: create_report_state::State,
270 St::ReasonType: create_report_state::IsUnset,
271{
272 pub fn reason_type(
274 mut self,
275 value: impl Into<ReasonType<S>>,
276 ) -> CreateReportBuilder<create_report_state::SetReasonType<St>, S> {
277 self._fields.2 = Option::Some(value.into());
278 CreateReportBuilder {
279 _state: PhantomData,
280 _fields: self._fields,
281 _type: PhantomData,
282 }
283 }
284}
285
286impl<St, S: BosStr> CreateReportBuilder<St, S>
287where
288 St: create_report_state::State,
289 St::Subject: create_report_state::IsUnset,
290{
291 pub fn subject(
293 mut self,
294 value: impl Into<CreateReportSubject<S>>,
295 ) -> CreateReportBuilder<create_report_state::SetSubject<St>, S> {
296 self._fields.3 = Option::Some(value.into());
297 CreateReportBuilder {
298 _state: PhantomData,
299 _fields: self._fields,
300 _type: PhantomData,
301 }
302 }
303}
304
305impl<St, S: BosStr> CreateReportBuilder<St, S>
306where
307 St: create_report_state::State,
308 St::ReasonType: create_report_state::IsSet,
309 St::Subject: create_report_state::IsSet,
310{
311 pub fn build(self) -> CreateReport<S> {
313 CreateReport {
314 mod_tool: self._fields.0,
315 reason: self._fields.1,
316 reason_type: self._fields.2.unwrap(),
317 subject: self._fields.3.unwrap(),
318 extra_data: Default::default(),
319 }
320 }
321 pub fn build_with_data(self, extra_data: BTreeMap<SmolStr, Data<S>>) -> CreateReport<S> {
323 CreateReport {
324 mod_tool: self._fields.0,
325 reason: self._fields.1,
326 reason_type: self._fields.2.unwrap(),
327 subject: self._fields.3.unwrap(),
328 extra_data: Some(extra_data),
329 }
330 }
331}
332
333fn lexicon_doc_com_atproto_moderation_createReport() -> LexiconDoc<'static> {
334 use alloc::collections::BTreeMap;
335 #[allow(unused_imports)]
336 use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType};
337 use jacquard_lexicon::lexicon::*;
338 LexiconDoc {
339 lexicon: Lexicon::Lexicon1,
340 id: CowStr::new_static("com.atproto.moderation.createReport"),
341 defs: {
342 let mut map = BTreeMap::new();
343 map.insert(
344 SmolStr::new_static("main"),
345 LexUserType::XrpcProcedure(LexXrpcProcedure {
346 input: Some(LexXrpcBody {
347 encoding: CowStr::new_static("application/json"),
348 schema: Some(LexXrpcBodySchema::Object(LexObject {
349 required: Some(vec![
350 SmolStr::new_static("reasonType"),
351 SmolStr::new_static("subject"),
352 ]),
353 properties: {
354 #[allow(unused_mut)]
355 let mut map = BTreeMap::new();
356 map.insert(
357 SmolStr::new_static("modTool"),
358 LexObjectProperty::Ref(LexRef {
359 r#ref: CowStr::new_static("#modTool"),
360 ..Default::default()
361 }),
362 );
363 map.insert(
364 SmolStr::new_static("reason"),
365 LexObjectProperty::String(LexString {
366 description: Some(CowStr::new_static(
367 "Additional context about the content and violation.",
368 )),
369 max_length: Some(20000usize),
370 max_graphemes: Some(2000usize),
371 ..Default::default()
372 }),
373 );
374 map.insert(
375 SmolStr::new_static("reasonType"),
376 LexObjectProperty::Ref(LexRef {
377 r#ref: CowStr::new_static(
378 "com.atproto.moderation.defs#reasonType",
379 ),
380 ..Default::default()
381 }),
382 );
383 map.insert(
384 SmolStr::new_static("subject"),
385 LexObjectProperty::Union(LexRefUnion {
386 refs: vec![
387 CowStr::new_static("com.atproto.admin.defs#repoRef"),
388 CowStr::new_static("com.atproto.repo.strongRef"),
389 ],
390 ..Default::default()
391 }),
392 );
393 map
394 },
395 ..Default::default()
396 })),
397 ..Default::default()
398 }),
399 ..Default::default()
400 }),
401 );
402 map.insert(
403 SmolStr::new_static("modTool"),
404 LexUserType::Object(LexObject {
405 description: Some(
406 CowStr::new_static(
407 "Moderation tool information for tracing the source of the action",
408 ),
409 ),
410 required: Some(vec![SmolStr::new_static("name")]),
411 properties: {
412 #[allow(unused_mut)]
413 let mut map = BTreeMap::new();
414 map.insert(
415 SmolStr::new_static("meta"),
416 LexObjectProperty::Unknown(LexUnknown {
417 ..Default::default()
418 }),
419 );
420 map.insert(
421 SmolStr::new_static("name"),
422 LexObjectProperty::String(LexString {
423 description: Some(
424 CowStr::new_static(
425 "Name/identifier of the source (e.g., 'bsky-app/android', 'bsky-web/chrome')",
426 ),
427 ),
428 ..Default::default()
429 }),
430 );
431 map
432 },
433 ..Default::default()
434 }),
435 );
436 map
437 },
438 ..Default::default()
439 }
440}