Skip to main content

jacquard_api/app_bsky/graph/
list.rs

1// @generated by jacquard-lexicon. DO NOT EDIT.
2//
3// Lexicon: app.bsky.graph.list
4//
5// This file was automatically generated from Lexicon schemas.
6// Any manual changes will be overwritten on the next regeneration.
7
8#[allow(unused_imports)]
9use alloc::collections::BTreeMap;
10
11#[allow(unused_imports)]
12use core::marker::PhantomData;
13use jacquard_common::CowStr;
14
15#[allow(unused_imports)]
16use jacquard_common::deps::codegen::unicode_segmentation::UnicodeSegmentation;
17use jacquard_common::types::blob::BlobRef;
18use jacquard_common::types::collection::{Collection, RecordError};
19use jacquard_common::types::string::{AtUri, Cid, Datetime};
20use jacquard_common::types::uri::{RecordUri, UriError};
21use jacquard_common::xrpc::XrpcResp;
22use jacquard_derive::{IntoStatic, lexicon};
23use jacquard_lexicon::lexicon::LexiconDoc;
24use jacquard_lexicon::schema::LexiconSchema;
25
26#[allow(unused_imports)]
27use jacquard_lexicon::validation::{ConstraintError, ValidationPath};
28use serde::{Serialize, Deserialize};
29use crate::app_bsky::graph::ListPurpose;
30use crate::app_bsky::richtext::facet::Facet;
31use crate::com_atproto::label::SelfLabels;
32/// Record representing a list of accounts (actors). Scope includes both moderation-oriented lists and curration-oriented lists.
33
34#[lexicon]
35#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
36#[serde(rename_all = "camelCase", rename = "app.bsky.graph.list", tag = "$type")]
37pub struct List<'a> {
38    #[serde(skip_serializing_if = "Option::is_none")]
39    #[serde(borrow)]
40    pub avatar: Option<BlobRef<'a>>,
41    pub created_at: Datetime,
42    #[serde(skip_serializing_if = "Option::is_none")]
43    #[serde(borrow)]
44    pub description: Option<CowStr<'a>>,
45    #[serde(skip_serializing_if = "Option::is_none")]
46    #[serde(borrow)]
47    pub description_facets: Option<Vec<Facet<'a>>>,
48    #[serde(skip_serializing_if = "Option::is_none")]
49    #[serde(borrow)]
50    pub labels: Option<SelfLabels<'a>>,
51    ///Display name for list; can not be empty.
52    #[serde(borrow)]
53    pub name: CowStr<'a>,
54    ///Defines the purpose of the list (aka, moderation-oriented or curration-oriented)
55    #[serde(borrow)]
56    pub purpose: ListPurpose<'a>,
57}
58
59/// Typed wrapper for GetRecord response with this collection's record type.
60
61#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
62#[serde(rename_all = "camelCase")]
63pub struct ListGetRecordOutput<'a> {
64    #[serde(skip_serializing_if = "Option::is_none")]
65    #[serde(borrow)]
66    pub cid: Option<Cid<'a>>,
67    #[serde(borrow)]
68    pub uri: AtUri<'a>,
69    #[serde(borrow)]
70    pub value: List<'a>,
71}
72
73impl<'a> List<'a> {
74    pub fn uri(
75        uri: impl Into<CowStr<'a>>,
76    ) -> Result<RecordUri<'a, ListRecord>, UriError> {
77        RecordUri::try_from_uri(AtUri::new_cow(uri.into())?)
78    }
79}
80
81/// Marker type for deserializing records from this collection.
82
83#[derive(Debug, Serialize, Deserialize)]
84pub struct ListRecord;
85impl XrpcResp for ListRecord {
86    const NSID: &'static str = "app.bsky.graph.list";
87    const ENCODING: &'static str = "application/json";
88    type Output<'de> = ListGetRecordOutput<'de>;
89    type Err<'de> = RecordError<'de>;
90}
91
92impl From<ListGetRecordOutput<'_>> for List<'_> {
93    fn from(output: ListGetRecordOutput<'_>) -> Self {
94        use jacquard_common::IntoStatic;
95        output.value.into_static()
96    }
97}
98
99impl Collection for List<'_> {
100    const NSID: &'static str = "app.bsky.graph.list";
101    type Record = ListRecord;
102}
103
104impl Collection for ListRecord {
105    const NSID: &'static str = "app.bsky.graph.list";
106    type Record = ListRecord;
107}
108
109impl<'a> LexiconSchema for List<'a> {
110    fn nsid() -> &'static str {
111        "app.bsky.graph.list"
112    }
113    fn def_name() -> &'static str {
114        "main"
115    }
116    fn lexicon_doc() -> LexiconDoc<'static> {
117        lexicon_doc_app_bsky_graph_list()
118    }
119    fn validate(&self) -> Result<(), ConstraintError> {
120        if let Some(ref value) = self.avatar {
121            {
122                let size = value.blob().size;
123                if size > 1000000usize {
124                    return Err(ConstraintError::BlobTooLarge {
125                        path: ValidationPath::from_field("avatar"),
126                        max: 1000000usize,
127                        actual: size,
128                    });
129                }
130            }
131        }
132        if let Some(ref value) = self.avatar {
133            {
134                let mime = value.blob().mime_type.as_str();
135                let accepted: &[&str] = &["image/png", "image/jpeg"];
136                let matched = accepted
137                    .iter()
138                    .any(|pattern| {
139                        if *pattern == "*/*" {
140                            true
141                        } else if pattern.ends_with("/*") {
142                            let prefix = &pattern[..pattern.len() - 2];
143                            mime.starts_with(prefix)
144                                && mime.as_bytes().get(prefix.len()) == Some(&b'/')
145                        } else {
146                            mime == *pattern
147                        }
148                    });
149                if !matched {
150                    return Err(ConstraintError::BlobMimeTypeNotAccepted {
151                        path: ValidationPath::from_field("avatar"),
152                        accepted: vec![
153                            "image/png".to_string(), "image/jpeg".to_string()
154                        ],
155                        actual: mime.to_string(),
156                    });
157                }
158            }
159        }
160        if let Some(ref value) = self.description {
161            #[allow(unused_comparisons)]
162            if <str>::len(value.as_ref()) > 3000usize {
163                return Err(ConstraintError::MaxLength {
164                    path: ValidationPath::from_field("description"),
165                    max: 3000usize,
166                    actual: <str>::len(value.as_ref()),
167                });
168            }
169        }
170        if let Some(ref value) = self.description {
171            {
172                let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count();
173                if count > 300usize {
174                    return Err(ConstraintError::MaxGraphemes {
175                        path: ValidationPath::from_field("description"),
176                        max: 300usize,
177                        actual: count,
178                    });
179                }
180            }
181        }
182        {
183            let value = &self.name;
184            #[allow(unused_comparisons)]
185            if <str>::len(value.as_ref()) > 64usize {
186                return Err(ConstraintError::MaxLength {
187                    path: ValidationPath::from_field("name"),
188                    max: 64usize,
189                    actual: <str>::len(value.as_ref()),
190                });
191            }
192        }
193        {
194            let value = &self.name;
195            #[allow(unused_comparisons)]
196            if <str>::len(value.as_ref()) < 1usize {
197                return Err(ConstraintError::MinLength {
198                    path: ValidationPath::from_field("name"),
199                    min: 1usize,
200                    actual: <str>::len(value.as_ref()),
201                });
202            }
203        }
204        Ok(())
205    }
206}
207
208pub mod list_state {
209
210    pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
211    #[allow(unused)]
212    use ::core::marker::PhantomData;
213    mod sealed {
214        pub trait Sealed {}
215    }
216    /// State trait tracking which required fields have been set
217    pub trait State: sealed::Sealed {
218        type CreatedAt;
219        type Name;
220        type Purpose;
221    }
222    /// Empty state - all required fields are unset
223    pub struct Empty(());
224    impl sealed::Sealed for Empty {}
225    impl State for Empty {
226        type CreatedAt = Unset;
227        type Name = Unset;
228        type Purpose = Unset;
229    }
230    ///State transition - sets the `created_at` field to Set
231    pub struct SetCreatedAt<S: State = Empty>(PhantomData<fn() -> S>);
232    impl<S: State> sealed::Sealed for SetCreatedAt<S> {}
233    impl<S: State> State for SetCreatedAt<S> {
234        type CreatedAt = Set<members::created_at>;
235        type Name = S::Name;
236        type Purpose = S::Purpose;
237    }
238    ///State transition - sets the `name` field to Set
239    pub struct SetName<S: State = Empty>(PhantomData<fn() -> S>);
240    impl<S: State> sealed::Sealed for SetName<S> {}
241    impl<S: State> State for SetName<S> {
242        type CreatedAt = S::CreatedAt;
243        type Name = Set<members::name>;
244        type Purpose = S::Purpose;
245    }
246    ///State transition - sets the `purpose` field to Set
247    pub struct SetPurpose<S: State = Empty>(PhantomData<fn() -> S>);
248    impl<S: State> sealed::Sealed for SetPurpose<S> {}
249    impl<S: State> State for SetPurpose<S> {
250        type CreatedAt = S::CreatedAt;
251        type Name = S::Name;
252        type Purpose = Set<members::purpose>;
253    }
254    /// Marker types for field names
255    #[allow(non_camel_case_types)]
256    pub mod members {
257        ///Marker type for the `created_at` field
258        pub struct created_at(());
259        ///Marker type for the `name` field
260        pub struct name(());
261        ///Marker type for the `purpose` field
262        pub struct purpose(());
263    }
264}
265
266/// Builder for constructing an instance of this type
267pub struct ListBuilder<'a, S: list_state::State> {
268    _state: PhantomData<fn() -> S>,
269    _fields: (
270        Option<BlobRef<'a>>,
271        Option<Datetime>,
272        Option<CowStr<'a>>,
273        Option<Vec<Facet<'a>>>,
274        Option<SelfLabels<'a>>,
275        Option<CowStr<'a>>,
276        Option<ListPurpose<'a>>,
277    ),
278    _lifetime: PhantomData<&'a ()>,
279}
280
281impl<'a> List<'a> {
282    /// Create a new builder for this type
283    pub fn new() -> ListBuilder<'a, list_state::Empty> {
284        ListBuilder::new()
285    }
286}
287
288impl<'a> ListBuilder<'a, list_state::Empty> {
289    /// Create a new builder with all fields unset
290    pub fn new() -> Self {
291        ListBuilder {
292            _state: PhantomData,
293            _fields: (None, None, None, None, None, None, None),
294            _lifetime: PhantomData,
295        }
296    }
297}
298
299impl<'a, S: list_state::State> ListBuilder<'a, S> {
300    /// Set the `avatar` field (optional)
301    pub fn avatar(mut self, value: impl Into<Option<BlobRef<'a>>>) -> Self {
302        self._fields.0 = value.into();
303        self
304    }
305    /// Set the `avatar` field to an Option value (optional)
306    pub fn maybe_avatar(mut self, value: Option<BlobRef<'a>>) -> Self {
307        self._fields.0 = value;
308        self
309    }
310}
311
312impl<'a, S> ListBuilder<'a, S>
313where
314    S: list_state::State,
315    S::CreatedAt: list_state::IsUnset,
316{
317    /// Set the `createdAt` field (required)
318    pub fn created_at(
319        mut self,
320        value: impl Into<Datetime>,
321    ) -> ListBuilder<'a, list_state::SetCreatedAt<S>> {
322        self._fields.1 = Option::Some(value.into());
323        ListBuilder {
324            _state: PhantomData,
325            _fields: self._fields,
326            _lifetime: PhantomData,
327        }
328    }
329}
330
331impl<'a, S: list_state::State> ListBuilder<'a, S> {
332    /// Set the `description` field (optional)
333    pub fn description(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
334        self._fields.2 = value.into();
335        self
336    }
337    /// Set the `description` field to an Option value (optional)
338    pub fn maybe_description(mut self, value: Option<CowStr<'a>>) -> Self {
339        self._fields.2 = value;
340        self
341    }
342}
343
344impl<'a, S: list_state::State> ListBuilder<'a, S> {
345    /// Set the `descriptionFacets` field (optional)
346    pub fn description_facets(
347        mut self,
348        value: impl Into<Option<Vec<Facet<'a>>>>,
349    ) -> Self {
350        self._fields.3 = value.into();
351        self
352    }
353    /// Set the `descriptionFacets` field to an Option value (optional)
354    pub fn maybe_description_facets(mut self, value: Option<Vec<Facet<'a>>>) -> Self {
355        self._fields.3 = value;
356        self
357    }
358}
359
360impl<'a, S: list_state::State> ListBuilder<'a, S> {
361    /// Set the `labels` field (optional)
362    pub fn labels(mut self, value: impl Into<Option<SelfLabels<'a>>>) -> Self {
363        self._fields.4 = value.into();
364        self
365    }
366    /// Set the `labels` field to an Option value (optional)
367    pub fn maybe_labels(mut self, value: Option<SelfLabels<'a>>) -> Self {
368        self._fields.4 = value;
369        self
370    }
371}
372
373impl<'a, S> ListBuilder<'a, S>
374where
375    S: list_state::State,
376    S::Name: list_state::IsUnset,
377{
378    /// Set the `name` field (required)
379    pub fn name(
380        mut self,
381        value: impl Into<CowStr<'a>>,
382    ) -> ListBuilder<'a, list_state::SetName<S>> {
383        self._fields.5 = Option::Some(value.into());
384        ListBuilder {
385            _state: PhantomData,
386            _fields: self._fields,
387            _lifetime: PhantomData,
388        }
389    }
390}
391
392impl<'a, S> ListBuilder<'a, S>
393where
394    S: list_state::State,
395    S::Purpose: list_state::IsUnset,
396{
397    /// Set the `purpose` field (required)
398    pub fn purpose(
399        mut self,
400        value: impl Into<ListPurpose<'a>>,
401    ) -> ListBuilder<'a, list_state::SetPurpose<S>> {
402        self._fields.6 = Option::Some(value.into());
403        ListBuilder {
404            _state: PhantomData,
405            _fields: self._fields,
406            _lifetime: PhantomData,
407        }
408    }
409}
410
411impl<'a, S> ListBuilder<'a, S>
412where
413    S: list_state::State,
414    S::CreatedAt: list_state::IsSet,
415    S::Name: list_state::IsSet,
416    S::Purpose: list_state::IsSet,
417{
418    /// Build the final struct
419    pub fn build(self) -> List<'a> {
420        List {
421            avatar: self._fields.0,
422            created_at: self._fields.1.unwrap(),
423            description: self._fields.2,
424            description_facets: self._fields.3,
425            labels: self._fields.4,
426            name: self._fields.5.unwrap(),
427            purpose: self._fields.6.unwrap(),
428            extra_data: Default::default(),
429        }
430    }
431    /// Build the final struct with custom extra_data
432    pub fn build_with_data(
433        self,
434        extra_data: BTreeMap<
435            jacquard_common::deps::smol_str::SmolStr,
436            jacquard_common::types::value::Data<'a>,
437        >,
438    ) -> List<'a> {
439        List {
440            avatar: self._fields.0,
441            created_at: self._fields.1.unwrap(),
442            description: self._fields.2,
443            description_facets: self._fields.3,
444            labels: self._fields.4,
445            name: self._fields.5.unwrap(),
446            purpose: self._fields.6.unwrap(),
447            extra_data: Some(extra_data),
448        }
449    }
450}
451
452fn lexicon_doc_app_bsky_graph_list() -> LexiconDoc<'static> {
453    #[allow(unused_imports)]
454    use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType};
455    use jacquard_lexicon::lexicon::*;
456    use alloc::collections::BTreeMap;
457    LexiconDoc {
458        lexicon: Lexicon::Lexicon1,
459        id: CowStr::new_static("app.bsky.graph.list"),
460        defs: {
461            let mut map = BTreeMap::new();
462            map.insert(
463                SmolStr::new_static("main"),
464                LexUserType::Record(LexRecord {
465                    description: Some(
466                        CowStr::new_static(
467                            "Record representing a list of accounts (actors). Scope includes both moderation-oriented lists and curration-oriented lists.",
468                        ),
469                    ),
470                    key: Some(CowStr::new_static("tid")),
471                    record: LexRecordRecord::Object(LexObject {
472                        required: Some(
473                            vec![
474                                SmolStr::new_static("name"), SmolStr::new_static("purpose"),
475                                SmolStr::new_static("createdAt")
476                            ],
477                        ),
478                        properties: {
479                            #[allow(unused_mut)]
480                            let mut map = BTreeMap::new();
481                            map.insert(
482                                SmolStr::new_static("avatar"),
483                                LexObjectProperty::Blob(LexBlob { ..Default::default() }),
484                            );
485                            map.insert(
486                                SmolStr::new_static("createdAt"),
487                                LexObjectProperty::String(LexString {
488                                    format: Some(LexStringFormat::Datetime),
489                                    ..Default::default()
490                                }),
491                            );
492                            map.insert(
493                                SmolStr::new_static("description"),
494                                LexObjectProperty::String(LexString {
495                                    max_length: Some(3000usize),
496                                    max_graphemes: Some(300usize),
497                                    ..Default::default()
498                                }),
499                            );
500                            map.insert(
501                                SmolStr::new_static("descriptionFacets"),
502                                LexObjectProperty::Array(LexArray {
503                                    items: LexArrayItem::Ref(LexRef {
504                                        r#ref: CowStr::new_static("app.bsky.richtext.facet"),
505                                        ..Default::default()
506                                    }),
507                                    ..Default::default()
508                                }),
509                            );
510                            map.insert(
511                                SmolStr::new_static("labels"),
512                                LexObjectProperty::Union(LexRefUnion {
513                                    refs: vec![
514                                        CowStr::new_static("com.atproto.label.defs#selfLabels")
515                                    ],
516                                    ..Default::default()
517                                }),
518                            );
519                            map.insert(
520                                SmolStr::new_static("name"),
521                                LexObjectProperty::String(LexString {
522                                    description: Some(
523                                        CowStr::new_static(
524                                            "Display name for list; can not be empty.",
525                                        ),
526                                    ),
527                                    min_length: Some(1usize),
528                                    max_length: Some(64usize),
529                                    ..Default::default()
530                                }),
531                            );
532                            map.insert(
533                                SmolStr::new_static("purpose"),
534                                LexObjectProperty::Ref(LexRef {
535                                    r#ref: CowStr::new_static(
536                                        "app.bsky.graph.defs#listPurpose",
537                                    ),
538                                    ..Default::default()
539                                }),
540                            );
541                            map
542                        },
543                        ..Default::default()
544                    }),
545                    ..Default::default()
546                }),
547            );
548            map
549        },
550        ..Default::default()
551    }
552}