1pub mod get_actor_metadata;
10pub mod get_convo;
11pub mod get_convo_members;
12pub mod get_convos;
13pub mod get_message_context;
14
15#[cfg(feature = "streaming")]
16pub mod subscribe_mod_events;
17pub mod update_actor_access;
18
19#[allow(unused_imports)]
20use alloc::collections::BTreeMap;
21
22#[allow(unused_imports)]
23use core::marker::PhantomData;
24use jacquard_common::{BosStr, CowStr, DefaultStr, FromStaticStr};
25
26#[allow(unused_imports)]
27use jacquard_common::deps::codegen::unicode_segmentation::UnicodeSegmentation;
28use jacquard_common::deps::smol_str::SmolStr;
29use jacquard_common::types::string::Datetime;
30use jacquard_common::types::value::Data;
31use jacquard_derive::{IntoStatic, open_union};
32use jacquard_lexicon::lexicon::LexiconDoc;
33use jacquard_lexicon::schema::LexiconSchema;
34
35use crate::chat_bsky::convo::ConvoLockStatus;
36use crate::chat_bsky::group::JoinLinkView;
37use crate::chat_bsky::moderation;
38#[allow(unused_imports)]
39use jacquard_lexicon::validation::{ConstraintError, ValidationPath};
40use serde::{Deserialize, Serialize};
41#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
44#[serde(
45 rename_all = "camelCase",
46 bound(deserialize = "S: Deserialize<'de> + BosStr")
47)]
48pub struct ConvoView<S: BosStr = DefaultStr> {
49 pub id: S,
50 #[serde(skip_serializing_if = "Option::is_none")]
52 pub kind: Option<ConvoViewKind<S>>,
53 pub rev: S,
54 #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
55 pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
56}
57
58#[open_union]
59#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
60#[serde(tag = "$type", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
61pub enum ConvoViewKind<S: BosStr = DefaultStr> {
62 #[serde(rename = "chat.bsky.moderation.defs#directConvo")]
63 DirectConvo(Box<moderation::DirectConvo<S>>),
64 #[serde(rename = "chat.bsky.moderation.defs#groupConvo")]
65 GroupConvo(Box<moderation::GroupConvo<S>>),
66}
67
68#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
71#[serde(
72 rename_all = "camelCase",
73 bound(deserialize = "S: Deserialize<'de> + BosStr")
74)]
75pub struct DirectConvo<S: BosStr = DefaultStr> {
76 #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
77 pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
78}
79
80#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
83#[serde(
84 rename_all = "camelCase",
85 bound(deserialize = "S: Deserialize<'de> + BosStr")
86)]
87pub struct GroupConvo<S: BosStr = DefaultStr> {
88 pub created_at: Datetime,
89 #[serde(skip_serializing_if = "Option::is_none")]
90 pub join_link: Option<JoinLinkView<S>>,
91 pub join_request_count: i64,
93 pub lock_status: ConvoLockStatus<S>,
95 pub member_count: i64,
97 pub member_limit: i64,
99 pub name: S,
101 #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
102 pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
103}
104
105impl<S: BosStr> LexiconSchema for ConvoView<S> {
106 fn nsid() -> &'static str {
107 "chat.bsky.moderation.defs"
108 }
109 fn def_name() -> &'static str {
110 "convoView"
111 }
112 fn lexicon_doc() -> LexiconDoc<'static> {
113 lexicon_doc_chat_bsky_moderation_defs()
114 }
115 fn validate(&self) -> Result<(), ConstraintError> {
116 Ok(())
117 }
118}
119
120impl<S: BosStr> LexiconSchema for DirectConvo<S> {
121 fn nsid() -> &'static str {
122 "chat.bsky.moderation.defs"
123 }
124 fn def_name() -> &'static str {
125 "directConvo"
126 }
127 fn lexicon_doc() -> LexiconDoc<'static> {
128 lexicon_doc_chat_bsky_moderation_defs()
129 }
130 fn validate(&self) -> Result<(), ConstraintError> {
131 Ok(())
132 }
133}
134
135impl<S: BosStr> LexiconSchema for GroupConvo<S> {
136 fn nsid() -> &'static str {
137 "chat.bsky.moderation.defs"
138 }
139 fn def_name() -> &'static str {
140 "groupConvo"
141 }
142 fn lexicon_doc() -> LexiconDoc<'static> {
143 lexicon_doc_chat_bsky_moderation_defs()
144 }
145 fn validate(&self) -> Result<(), ConstraintError> {
146 {
147 let value = &self.name;
148 #[allow(unused_comparisons)]
149 if <str>::len(value.as_ref()) > 500usize {
150 return Err(ConstraintError::MaxLength {
151 path: ValidationPath::from_field("name"),
152 max: 500usize,
153 actual: <str>::len(value.as_ref()),
154 });
155 }
156 }
157 {
158 let value = &self.name;
159 {
160 let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count();
161 if count > 50usize {
162 return Err(ConstraintError::MaxGraphemes {
163 path: ValidationPath::from_field("name"),
164 max: 50usize,
165 actual: count,
166 });
167 }
168 }
169 }
170 Ok(())
171 }
172}
173
174fn lexicon_doc_chat_bsky_moderation_defs() -> LexiconDoc<'static> {
175 use alloc::collections::BTreeMap;
176 #[allow(unused_imports)]
177 use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType};
178 use jacquard_lexicon::lexicon::*;
179 LexiconDoc {
180 lexicon: Lexicon::Lexicon1,
181 id: CowStr::new_static("chat.bsky.moderation.defs"),
182 defs: {
183 let mut map = BTreeMap::new();
184 map.insert(
185 SmolStr::new_static("convoView"),
186 LexUserType::Object(LexObject {
187 description: Some(
188 CowStr::new_static(
189 "A view of a conversation for moderation purposes. Unlike chat.bsky.convo.defs#convoView, it does not include viewer-specific data (such as muted, unreadCount, status, lastMessage, lastReaction), since the requester is a moderator and not a member of the conversation. The member list is not included; use chat.bsky.moderation.getConvoMembers to list members.",
190 ),
191 ),
192 required: Some(
193 vec![SmolStr::new_static("id"), SmolStr::new_static("rev")],
194 ),
195 properties: {
196 #[allow(unused_mut)]
197 let mut map = BTreeMap::new();
198 map.insert(
199 SmolStr::new_static("id"),
200 LexObjectProperty::String(LexString { ..Default::default() }),
201 );
202 map.insert(
203 SmolStr::new_static("kind"),
204 LexObjectProperty::Union(LexRefUnion {
205 description: Some(
206 CowStr::new_static(
207 "Union field that has data specific to different kinds of convos.",
208 ),
209 ),
210 refs: vec![
211 CowStr::new_static("#directConvo"),
212 CowStr::new_static("#groupConvo")
213 ],
214 ..Default::default()
215 }),
216 );
217 map.insert(
218 SmolStr::new_static("rev"),
219 LexObjectProperty::String(LexString { ..Default::default() }),
220 );
221 map
222 },
223 ..Default::default()
224 }),
225 );
226 map.insert(
227 SmolStr::new_static("directConvo"),
228 LexUserType::Object(LexObject {
229 description: Some(CowStr::new_static(
230 "Data specific to a direct conversation, for moderation purposes.",
231 )),
232 properties: {
233 #[allow(unused_mut)]
234 let mut map = BTreeMap::new();
235 map
236 },
237 ..Default::default()
238 }),
239 );
240 map.insert(
241 SmolStr::new_static("groupConvo"),
242 LexUserType::Object(LexObject {
243 description: Some(
244 CowStr::new_static(
245 "Data specific to a group conversation, for moderation purposes. Unlike chat.bsky.convo.defs#groupConvo, it does not include viewer-specific data (such as unreadJoinRequestCount), since the requester is a moderator and not a member of the conversation.",
246 ),
247 ),
248 required: Some(
249 vec![
250 SmolStr::new_static("createdAt"),
251 SmolStr::new_static("joinRequestCount"),
252 SmolStr::new_static("lockStatus"),
253 SmolStr::new_static("memberCount"),
254 SmolStr::new_static("memberLimit"),
255 SmolStr::new_static("name")
256 ],
257 ),
258 properties: {
259 #[allow(unused_mut)]
260 let mut map = BTreeMap::new();
261 map.insert(
262 SmolStr::new_static("createdAt"),
263 LexObjectProperty::String(LexString {
264 format: Some(LexStringFormat::Datetime),
265 ..Default::default()
266 }),
267 );
268 map.insert(
269 SmolStr::new_static("joinLink"),
270 LexObjectProperty::Ref(LexRef {
271 r#ref: CowStr::new_static(
272 "chat.bsky.group.defs#joinLinkView",
273 ),
274 ..Default::default()
275 }),
276 );
277 map.insert(
278 SmolStr::new_static("joinRequestCount"),
279 LexObjectProperty::Integer(LexInteger {
280 ..Default::default()
281 }),
282 );
283 map.insert(
284 SmolStr::new_static("lockStatus"),
285 LexObjectProperty::Ref(LexRef {
286 r#ref: CowStr::new_static(
287 "chat.bsky.convo.defs#convoLockStatus",
288 ),
289 ..Default::default()
290 }),
291 );
292 map.insert(
293 SmolStr::new_static("memberCount"),
294 LexObjectProperty::Integer(LexInteger {
295 ..Default::default()
296 }),
297 );
298 map.insert(
299 SmolStr::new_static("memberLimit"),
300 LexObjectProperty::Integer(LexInteger {
301 ..Default::default()
302 }),
303 );
304 map.insert(
305 SmolStr::new_static("name"),
306 LexObjectProperty::String(LexString {
307 description: Some(
308 CowStr::new_static(
309 "The display name of the group conversation.",
310 ),
311 ),
312 max_length: Some(500usize),
313 max_graphemes: Some(50usize),
314 ..Default::default()
315 }),
316 );
317 map
318 },
319 ..Default::default()
320 }),
321 );
322 map
323 },
324 ..Default::default()
325 }
326}
327
328pub mod group_convo_state {
329
330 pub use crate::builder_types::{IsSet, IsUnset, Set, Unset};
331 #[allow(unused)]
332 use ::core::marker::PhantomData;
333 mod sealed {
334 pub trait Sealed {}
335 }
336 pub trait State: sealed::Sealed {
338 type CreatedAt;
339 type JoinRequestCount;
340 type LockStatus;
341 type MemberCount;
342 type MemberLimit;
343 type Name;
344 }
345 pub struct Empty(());
347 impl sealed::Sealed for Empty {}
348 impl State for Empty {
349 type CreatedAt = Unset;
350 type JoinRequestCount = Unset;
351 type LockStatus = Unset;
352 type MemberCount = Unset;
353 type MemberLimit = Unset;
354 type Name = Unset;
355 }
356 pub struct SetCreatedAt<St: State = Empty>(PhantomData<fn() -> St>);
358 impl<St: State> sealed::Sealed for SetCreatedAt<St> {}
359 impl<St: State> State for SetCreatedAt<St> {
360 type CreatedAt = Set<members::created_at>;
361 type JoinRequestCount = St::JoinRequestCount;
362 type LockStatus = St::LockStatus;
363 type MemberCount = St::MemberCount;
364 type MemberLimit = St::MemberLimit;
365 type Name = St::Name;
366 }
367 pub struct SetJoinRequestCount<St: State = Empty>(PhantomData<fn() -> St>);
369 impl<St: State> sealed::Sealed for SetJoinRequestCount<St> {}
370 impl<St: State> State for SetJoinRequestCount<St> {
371 type CreatedAt = St::CreatedAt;
372 type JoinRequestCount = Set<members::join_request_count>;
373 type LockStatus = St::LockStatus;
374 type MemberCount = St::MemberCount;
375 type MemberLimit = St::MemberLimit;
376 type Name = St::Name;
377 }
378 pub struct SetLockStatus<St: State = Empty>(PhantomData<fn() -> St>);
380 impl<St: State> sealed::Sealed for SetLockStatus<St> {}
381 impl<St: State> State for SetLockStatus<St> {
382 type CreatedAt = St::CreatedAt;
383 type JoinRequestCount = St::JoinRequestCount;
384 type LockStatus = Set<members::lock_status>;
385 type MemberCount = St::MemberCount;
386 type MemberLimit = St::MemberLimit;
387 type Name = St::Name;
388 }
389 pub struct SetMemberCount<St: State = Empty>(PhantomData<fn() -> St>);
391 impl<St: State> sealed::Sealed for SetMemberCount<St> {}
392 impl<St: State> State for SetMemberCount<St> {
393 type CreatedAt = St::CreatedAt;
394 type JoinRequestCount = St::JoinRequestCount;
395 type LockStatus = St::LockStatus;
396 type MemberCount = Set<members::member_count>;
397 type MemberLimit = St::MemberLimit;
398 type Name = St::Name;
399 }
400 pub struct SetMemberLimit<St: State = Empty>(PhantomData<fn() -> St>);
402 impl<St: State> sealed::Sealed for SetMemberLimit<St> {}
403 impl<St: State> State for SetMemberLimit<St> {
404 type CreatedAt = St::CreatedAt;
405 type JoinRequestCount = St::JoinRequestCount;
406 type LockStatus = St::LockStatus;
407 type MemberCount = St::MemberCount;
408 type MemberLimit = Set<members::member_limit>;
409 type Name = St::Name;
410 }
411 pub struct SetName<St: State = Empty>(PhantomData<fn() -> St>);
413 impl<St: State> sealed::Sealed for SetName<St> {}
414 impl<St: State> State for SetName<St> {
415 type CreatedAt = St::CreatedAt;
416 type JoinRequestCount = St::JoinRequestCount;
417 type LockStatus = St::LockStatus;
418 type MemberCount = St::MemberCount;
419 type MemberLimit = St::MemberLimit;
420 type Name = Set<members::name>;
421 }
422 #[allow(non_camel_case_types)]
424 pub mod members {
425 pub struct created_at(());
427 pub struct join_request_count(());
429 pub struct lock_status(());
431 pub struct member_count(());
433 pub struct member_limit(());
435 pub struct name(());
437 }
438}
439
440pub struct GroupConvoBuilder<St: group_convo_state::State, S: BosStr = DefaultStr> {
442 _state: PhantomData<fn() -> St>,
443 _fields: (
444 Option<Datetime>,
445 Option<JoinLinkView<S>>,
446 Option<i64>,
447 Option<ConvoLockStatus<S>>,
448 Option<i64>,
449 Option<i64>,
450 Option<S>,
451 ),
452 _type: PhantomData<fn() -> S>,
453}
454
455impl GroupConvo<DefaultStr> {
456 pub fn new() -> GroupConvoBuilder<group_convo_state::Empty, DefaultStr> {
458 GroupConvoBuilder::new()
459 }
460}
461
462impl<S: BosStr> GroupConvo<S> {
463 pub fn builder() -> GroupConvoBuilder<group_convo_state::Empty, S> {
465 GroupConvoBuilder::builder()
466 }
467}
468
469impl GroupConvoBuilder<group_convo_state::Empty, DefaultStr> {
470 pub fn new() -> Self {
472 GroupConvoBuilder {
473 _state: PhantomData,
474 _fields: (None, None, None, None, None, None, None),
475 _type: PhantomData,
476 }
477 }
478}
479
480impl<S: BosStr> GroupConvoBuilder<group_convo_state::Empty, S> {
481 pub fn builder() -> Self {
483 GroupConvoBuilder {
484 _state: PhantomData,
485 _fields: (None, None, None, None, None, None, None),
486 _type: PhantomData,
487 }
488 }
489}
490
491impl<St, S: BosStr> GroupConvoBuilder<St, S>
492where
493 St: group_convo_state::State,
494 St::CreatedAt: group_convo_state::IsUnset,
495{
496 pub fn created_at(
498 mut self,
499 value: impl Into<Datetime>,
500 ) -> GroupConvoBuilder<group_convo_state::SetCreatedAt<St>, S> {
501 self._fields.0 = Option::Some(value.into());
502 GroupConvoBuilder {
503 _state: PhantomData,
504 _fields: self._fields,
505 _type: PhantomData,
506 }
507 }
508}
509
510impl<St: group_convo_state::State, S: BosStr> GroupConvoBuilder<St, S> {
511 pub fn join_link(mut self, value: impl Into<Option<JoinLinkView<S>>>) -> Self {
513 self._fields.1 = value.into();
514 self
515 }
516 pub fn maybe_join_link(mut self, value: Option<JoinLinkView<S>>) -> Self {
518 self._fields.1 = value;
519 self
520 }
521}
522
523impl<St, S: BosStr> GroupConvoBuilder<St, S>
524where
525 St: group_convo_state::State,
526 St::JoinRequestCount: group_convo_state::IsUnset,
527{
528 pub fn join_request_count(
530 mut self,
531 value: impl Into<i64>,
532 ) -> GroupConvoBuilder<group_convo_state::SetJoinRequestCount<St>, S> {
533 self._fields.2 = Option::Some(value.into());
534 GroupConvoBuilder {
535 _state: PhantomData,
536 _fields: self._fields,
537 _type: PhantomData,
538 }
539 }
540}
541
542impl<St, S: BosStr> GroupConvoBuilder<St, S>
543where
544 St: group_convo_state::State,
545 St::LockStatus: group_convo_state::IsUnset,
546{
547 pub fn lock_status(
549 mut self,
550 value: impl Into<ConvoLockStatus<S>>,
551 ) -> GroupConvoBuilder<group_convo_state::SetLockStatus<St>, S> {
552 self._fields.3 = Option::Some(value.into());
553 GroupConvoBuilder {
554 _state: PhantomData,
555 _fields: self._fields,
556 _type: PhantomData,
557 }
558 }
559}
560
561impl<St, S: BosStr> GroupConvoBuilder<St, S>
562where
563 St: group_convo_state::State,
564 St::MemberCount: group_convo_state::IsUnset,
565{
566 pub fn member_count(
568 mut self,
569 value: impl Into<i64>,
570 ) -> GroupConvoBuilder<group_convo_state::SetMemberCount<St>, S> {
571 self._fields.4 = Option::Some(value.into());
572 GroupConvoBuilder {
573 _state: PhantomData,
574 _fields: self._fields,
575 _type: PhantomData,
576 }
577 }
578}
579
580impl<St, S: BosStr> GroupConvoBuilder<St, S>
581where
582 St: group_convo_state::State,
583 St::MemberLimit: group_convo_state::IsUnset,
584{
585 pub fn member_limit(
587 mut self,
588 value: impl Into<i64>,
589 ) -> GroupConvoBuilder<group_convo_state::SetMemberLimit<St>, S> {
590 self._fields.5 = Option::Some(value.into());
591 GroupConvoBuilder {
592 _state: PhantomData,
593 _fields: self._fields,
594 _type: PhantomData,
595 }
596 }
597}
598
599impl<St, S: BosStr> GroupConvoBuilder<St, S>
600where
601 St: group_convo_state::State,
602 St::Name: group_convo_state::IsUnset,
603{
604 pub fn name(
606 mut self,
607 value: impl Into<S>,
608 ) -> GroupConvoBuilder<group_convo_state::SetName<St>, S> {
609 self._fields.6 = Option::Some(value.into());
610 GroupConvoBuilder {
611 _state: PhantomData,
612 _fields: self._fields,
613 _type: PhantomData,
614 }
615 }
616}
617
618impl<St, S: BosStr> GroupConvoBuilder<St, S>
619where
620 St: group_convo_state::State,
621 St::CreatedAt: group_convo_state::IsSet,
622 St::JoinRequestCount: group_convo_state::IsSet,
623 St::LockStatus: group_convo_state::IsSet,
624 St::MemberCount: group_convo_state::IsSet,
625 St::MemberLimit: group_convo_state::IsSet,
626 St::Name: group_convo_state::IsSet,
627{
628 pub fn build(self) -> GroupConvo<S> {
630 GroupConvo {
631 created_at: self._fields.0.unwrap(),
632 join_link: self._fields.1,
633 join_request_count: self._fields.2.unwrap(),
634 lock_status: self._fields.3.unwrap(),
635 member_count: self._fields.4.unwrap(),
636 member_limit: self._fields.5.unwrap(),
637 name: self._fields.6.unwrap(),
638 extra_data: Default::default(),
639 }
640 }
641 pub fn build_with_data(self, extra_data: BTreeMap<SmolStr, Data<S>>) -> GroupConvo<S> {
643 GroupConvo {
644 created_at: self._fields.0.unwrap(),
645 join_link: self._fields.1,
646 join_request_count: self._fields.2.unwrap(),
647 lock_status: self._fields.3.unwrap(),
648 member_count: self._fields.4.unwrap(),
649 member_limit: self._fields.5.unwrap(),
650 name: self._fields.6.unwrap(),
651 extra_data: Some(extra_data),
652 }
653 }
654}