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::{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::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
28use crate::app_bsky::graph::ListPurpose;
29use crate::app_bsky::richtext::facet::Facet;
30use crate::com_atproto::label::SelfLabels;
31#[allow(unused_imports)]
32use jacquard_lexicon::validation::{ConstraintError, ValidationPath};
33use serde::{Deserialize, Serialize};
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.iter().any(|pattern| {
133                    if *pattern == "*/*" {
134                        true
135                    } else if pattern.ends_with("/*") {
136                        let prefix = &pattern[..pattern.len() - 2];
137                        mime.starts_with(prefix) && mime.as_bytes().get(prefix.len()) == Some(&b'/')
138                    } else {
139                        mime == *pattern
140                    }
141                });
142                if !matched {
143                    return Err(ConstraintError::BlobMimeTypeNotAccepted {
144                        path: ValidationPath::from_field("avatar"),
145                        accepted: vec!["image/png".to_string(), "image/jpeg".to_string()],
146                        actual: mime.to_string(),
147                    });
148                }
149            }
150        }
151        if let Some(ref value) = self.description {
152            #[allow(unused_comparisons)]
153            if <str>::len(value.as_ref()) > 3000usize {
154                return Err(ConstraintError::MaxLength {
155                    path: ValidationPath::from_field("description"),
156                    max: 3000usize,
157                    actual: <str>::len(value.as_ref()),
158                });
159            }
160        }
161        if let Some(ref value) = self.description {
162            {
163                let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count();
164                if count > 300usize {
165                    return Err(ConstraintError::MaxGraphemes {
166                        path: ValidationPath::from_field("description"),
167                        max: 300usize,
168                        actual: count,
169                    });
170                }
171            }
172        }
173        {
174            let value = &self.name;
175            #[allow(unused_comparisons)]
176            if <str>::len(value.as_ref()) > 64usize {
177                return Err(ConstraintError::MaxLength {
178                    path: ValidationPath::from_field("name"),
179                    max: 64usize,
180                    actual: <str>::len(value.as_ref()),
181                });
182            }
183        }
184        {
185            let value = &self.name;
186            #[allow(unused_comparisons)]
187            if <str>::len(value.as_ref()) < 1usize {
188                return Err(ConstraintError::MinLength {
189                    path: ValidationPath::from_field("name"),
190                    min: 1usize,
191                    actual: <str>::len(value.as_ref()),
192                });
193            }
194        }
195        Ok(())
196    }
197}
198
199pub mod list_state {
200
201    pub use crate::builder_types::{IsSet, IsUnset, Set, Unset};
202    #[allow(unused)]
203    use ::core::marker::PhantomData;
204    mod sealed {
205        pub trait Sealed {}
206    }
207    /// State trait tracking which required fields have been set
208    pub trait State: sealed::Sealed {
209        type CreatedAt;
210        type Name;
211        type Purpose;
212    }
213    /// Empty state - all required fields are unset
214    pub struct Empty(());
215    impl sealed::Sealed for Empty {}
216    impl State for Empty {
217        type CreatedAt = Unset;
218        type Name = Unset;
219        type Purpose = Unset;
220    }
221    ///State transition - sets the `created_at` field to Set
222    pub struct SetCreatedAt<St: State = Empty>(PhantomData<fn() -> St>);
223    impl<St: State> sealed::Sealed for SetCreatedAt<St> {}
224    impl<St: State> State for SetCreatedAt<St> {
225        type CreatedAt = Set<members::created_at>;
226        type Name = St::Name;
227        type Purpose = St::Purpose;
228    }
229    ///State transition - sets the `name` field to Set
230    pub struct SetName<St: State = Empty>(PhantomData<fn() -> St>);
231    impl<St: State> sealed::Sealed for SetName<St> {}
232    impl<St: State> State for SetName<St> {
233        type CreatedAt = St::CreatedAt;
234        type Name = Set<members::name>;
235        type Purpose = St::Purpose;
236    }
237    ///State transition - sets the `purpose` field to Set
238    pub struct SetPurpose<St: State = Empty>(PhantomData<fn() -> St>);
239    impl<St: State> sealed::Sealed for SetPurpose<St> {}
240    impl<St: State> State for SetPurpose<St> {
241        type CreatedAt = St::CreatedAt;
242        type Name = St::Name;
243        type Purpose = Set<members::purpose>;
244    }
245    /// Marker types for field names
246    #[allow(non_camel_case_types)]
247    pub mod members {
248        ///Marker type for the `created_at` field
249        pub struct created_at(());
250        ///Marker type for the `name` field
251        pub struct name(());
252        ///Marker type for the `purpose` field
253        pub struct purpose(());
254    }
255}
256
257/// Builder for constructing an instance of this type.
258pub struct ListBuilder<St: list_state::State, S: BosStr = DefaultStr> {
259    _state: PhantomData<fn() -> St>,
260    _fields: (
261        Option<BlobRef<S>>,
262        Option<Datetime>,
263        Option<S>,
264        Option<Vec<Facet<S>>>,
265        Option<SelfLabels<S>>,
266        Option<S>,
267        Option<ListPurpose<S>>,
268    ),
269    _type: PhantomData<fn() -> S>,
270}
271
272impl List<DefaultStr> {
273    /// Create a new builder for this type, using the default string type (DefaultStr = SmolStr) if needed
274    pub fn new() -> ListBuilder<list_state::Empty, DefaultStr> {
275        ListBuilder::new()
276    }
277}
278
279impl<S: BosStr> List<S> {
280    /// Create a new builder for this type
281    pub fn builder() -> ListBuilder<list_state::Empty, S> {
282        ListBuilder::builder()
283    }
284}
285
286impl ListBuilder<list_state::Empty, DefaultStr> {
287    /// Create a new builder with all fields unset, using the default string type, if needed
288    pub fn new() -> Self {
289        ListBuilder {
290            _state: PhantomData,
291            _fields: (None, None, None, None, None, None, None),
292            _type: PhantomData,
293        }
294    }
295}
296
297impl<S: BosStr> ListBuilder<list_state::Empty, S> {
298    /// Create a new builder with all fields unset
299    pub fn builder() -> Self {
300        ListBuilder {
301            _state: PhantomData,
302            _fields: (None, None, None, None, None, None, None),
303            _type: PhantomData,
304        }
305    }
306}
307
308impl<St: list_state::State, S: BosStr> ListBuilder<St, S> {
309    /// Set the `avatar` field (optional)
310    pub fn avatar(mut self, value: impl Into<Option<BlobRef<S>>>) -> Self {
311        self._fields.0 = value.into();
312        self
313    }
314    /// Set the `avatar` field to an Option value (optional)
315    pub fn maybe_avatar(mut self, value: Option<BlobRef<S>>) -> Self {
316        self._fields.0 = value;
317        self
318    }
319}
320
321impl<St, S: BosStr> ListBuilder<St, S>
322where
323    St: list_state::State,
324    St::CreatedAt: list_state::IsUnset,
325{
326    /// Set the `createdAt` field (required)
327    pub fn created_at(
328        mut self,
329        value: impl Into<Datetime>,
330    ) -> ListBuilder<list_state::SetCreatedAt<St>, S> {
331        self._fields.1 = Option::Some(value.into());
332        ListBuilder {
333            _state: PhantomData,
334            _fields: self._fields,
335            _type: PhantomData,
336        }
337    }
338}
339
340impl<St: list_state::State, S: BosStr> ListBuilder<St, S> {
341    /// Set the `description` field (optional)
342    pub fn description(mut self, value: impl Into<Option<S>>) -> Self {
343        self._fields.2 = value.into();
344        self
345    }
346    /// Set the `description` field to an Option value (optional)
347    pub fn maybe_description(mut self, value: Option<S>) -> Self {
348        self._fields.2 = value;
349        self
350    }
351}
352
353impl<St: list_state::State, S: BosStr> ListBuilder<St, S> {
354    /// Set the `descriptionFacets` field (optional)
355    pub fn description_facets(mut self, value: impl Into<Option<Vec<Facet<S>>>>) -> Self {
356        self._fields.3 = value.into();
357        self
358    }
359    /// Set the `descriptionFacets` field to an Option value (optional)
360    pub fn maybe_description_facets(mut self, value: Option<Vec<Facet<S>>>) -> Self {
361        self._fields.3 = value;
362        self
363    }
364}
365
366impl<St: list_state::State, S: BosStr> ListBuilder<St, S> {
367    /// Set the `labels` field (optional)
368    pub fn labels(mut self, value: impl Into<Option<SelfLabels<S>>>) -> Self {
369        self._fields.4 = value.into();
370        self
371    }
372    /// Set the `labels` field to an Option value (optional)
373    pub fn maybe_labels(mut self, value: Option<SelfLabels<S>>) -> Self {
374        self._fields.4 = value;
375        self
376    }
377}
378
379impl<St, S: BosStr> ListBuilder<St, S>
380where
381    St: list_state::State,
382    St::Name: list_state::IsUnset,
383{
384    /// Set the `name` field (required)
385    pub fn name(mut self, value: impl Into<S>) -> ListBuilder<list_state::SetName<St>, S> {
386        self._fields.5 = Option::Some(value.into());
387        ListBuilder {
388            _state: PhantomData,
389            _fields: self._fields,
390            _type: PhantomData,
391        }
392    }
393}
394
395impl<St, S: BosStr> ListBuilder<St, S>
396where
397    St: list_state::State,
398    St::Purpose: list_state::IsUnset,
399{
400    /// Set the `purpose` field (required)
401    pub fn purpose(
402        mut self,
403        value: impl Into<ListPurpose<S>>,
404    ) -> ListBuilder<list_state::SetPurpose<St>, S> {
405        self._fields.6 = Option::Some(value.into());
406        ListBuilder {
407            _state: PhantomData,
408            _fields: self._fields,
409            _type: PhantomData,
410        }
411    }
412}
413
414impl<St, S: BosStr> ListBuilder<St, S>
415where
416    St: list_state::State,
417    St::CreatedAt: list_state::IsSet,
418    St::Name: list_state::IsSet,
419    St::Purpose: list_state::IsSet,
420{
421    /// Build the final struct.
422    pub fn build(self) -> List<S> {
423        List {
424            avatar: self._fields.0,
425            created_at: self._fields.1.unwrap(),
426            description: self._fields.2,
427            description_facets: self._fields.3,
428            labels: self._fields.4,
429            name: self._fields.5.unwrap(),
430            purpose: self._fields.6.unwrap(),
431            extra_data: Default::default(),
432        }
433    }
434    /// Build the final struct with custom extra_data.
435    pub fn build_with_data(self, extra_data: BTreeMap<SmolStr, Data<S>>) -> List<S> {
436        List {
437            avatar: self._fields.0,
438            created_at: self._fields.1.unwrap(),
439            description: self._fields.2,
440            description_facets: self._fields.3,
441            labels: self._fields.4,
442            name: self._fields.5.unwrap(),
443            purpose: self._fields.6.unwrap(),
444            extra_data: Some(extra_data),
445        }
446    }
447}
448
449fn lexicon_doc_app_bsky_graph_list() -> LexiconDoc<'static> {
450    use alloc::collections::BTreeMap;
451    #[allow(unused_imports)]
452    use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType};
453    use jacquard_lexicon::lexicon::*;
454    LexiconDoc {
455        lexicon: Lexicon::Lexicon1,
456        id: CowStr::new_static("app.bsky.graph.list"),
457        defs: {
458            let mut map = BTreeMap::new();
459            map.insert(
460                SmolStr::new_static("main"),
461                LexUserType::Record(LexRecord {
462                    description: Some(
463                        CowStr::new_static(
464                            "Record representing a list of accounts (actors). Scope includes both moderation-oriented lists and curration-oriented lists.",
465                        ),
466                    ),
467                    key: Some(CowStr::new_static("tid")),
468                    record: LexRecordRecord::Object(LexObject {
469                        required: Some(
470                            vec![
471                                SmolStr::new_static("name"), SmolStr::new_static("purpose"),
472                                SmolStr::new_static("createdAt")
473                            ],
474                        ),
475                        properties: {
476                            #[allow(unused_mut)]
477                            let mut map = BTreeMap::new();
478                            map.insert(
479                                SmolStr::new_static("avatar"),
480                                LexObjectProperty::Blob(LexBlob { ..Default::default() }),
481                            );
482                            map.insert(
483                                SmolStr::new_static("createdAt"),
484                                LexObjectProperty::String(LexString {
485                                    format: Some(LexStringFormat::Datetime),
486                                    ..Default::default()
487                                }),
488                            );
489                            map.insert(
490                                SmolStr::new_static("description"),
491                                LexObjectProperty::String(LexString {
492                                    max_length: Some(3000usize),
493                                    max_graphemes: Some(300usize),
494                                    ..Default::default()
495                                }),
496                            );
497                            map.insert(
498                                SmolStr::new_static("descriptionFacets"),
499                                LexObjectProperty::Array(LexArray {
500                                    items: LexArrayItem::Ref(LexRef {
501                                        r#ref: CowStr::new_static("app.bsky.richtext.facet"),
502                                        ..Default::default()
503                                    }),
504                                    ..Default::default()
505                                }),
506                            );
507                            map.insert(
508                                SmolStr::new_static("labels"),
509                                LexObjectProperty::Union(LexRefUnion {
510                                    refs: vec![
511                                        CowStr::new_static("com.atproto.label.defs#selfLabels")
512                                    ],
513                                    ..Default::default()
514                                }),
515                            );
516                            map.insert(
517                                SmolStr::new_static("name"),
518                                LexObjectProperty::String(LexString {
519                                    description: Some(
520                                        CowStr::new_static(
521                                            "Display name for list; can not be empty.",
522                                        ),
523                                    ),
524                                    min_length: Some(1usize),
525                                    max_length: Some(64usize),
526                                    ..Default::default()
527                                }),
528                            );
529                            map.insert(
530                                SmolStr::new_static("purpose"),
531                                LexObjectProperty::Ref(LexRef {
532                                    r#ref: CowStr::new_static(
533                                        "app.bsky.graph.defs#listPurpose",
534                                    ),
535                                    ..Default::default()
536                                }),
537                            );
538                            map
539                        },
540                        ..Default::default()
541                    }),
542                    ..Default::default()
543                }),
544            );
545            map
546        },
547        ..Default::default()
548    }
549}