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