Skip to main content

jacquard_api/net_anisota/feed/
list.rs

1// @generated by jacquard-lexicon. DO NOT EDIT.
2//
3// Lexicon: net.anisota.feed.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};
29/// A list of posts for curation, bookmarking, or organization
30
31#[lexicon]
32#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
33#[serde(rename_all = "camelCase", rename = "net.anisota.feed.list", tag = "$type")]
34pub struct List<'a> {
35    ///Optional avatar image for the list
36    #[serde(skip_serializing_if = "Option::is_none")]
37    #[serde(borrow)]
38    pub avatar: Option<BlobRef<'a>>,
39    ///When the list was created
40    pub created_at: Datetime,
41    ///Optional description of the list
42    #[serde(skip_serializing_if = "Option::is_none")]
43    #[serde(borrow)]
44    pub description: Option<CowStr<'a>>,
45    ///Display name for the list
46    #[serde(borrow)]
47    pub name: CowStr<'a>,
48    ///Tags for categorizing the list
49    #[serde(skip_serializing_if = "Option::is_none")]
50    #[serde(borrow)]
51    pub tags: Option<Vec<CowStr<'a>>>,
52}
53
54/// Typed wrapper for GetRecord response with this collection's record type.
55
56#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
57#[serde(rename_all = "camelCase")]
58pub struct ListGetRecordOutput<'a> {
59    #[serde(skip_serializing_if = "Option::is_none")]
60    #[serde(borrow)]
61    pub cid: Option<Cid<'a>>,
62    #[serde(borrow)]
63    pub uri: AtUri<'a>,
64    #[serde(borrow)]
65    pub value: List<'a>,
66}
67
68impl<'a> List<'a> {
69    pub fn uri(
70        uri: impl Into<CowStr<'a>>,
71    ) -> Result<RecordUri<'a, ListRecord>, UriError> {
72        RecordUri::try_from_uri(AtUri::new_cow(uri.into())?)
73    }
74}
75
76/// Marker type for deserializing records from this collection.
77
78#[derive(Debug, Serialize, Deserialize)]
79pub struct ListRecord;
80impl XrpcResp for ListRecord {
81    const NSID: &'static str = "net.anisota.feed.list";
82    const ENCODING: &'static str = "application/json";
83    type Output<'de> = ListGetRecordOutput<'de>;
84    type Err<'de> = RecordError<'de>;
85}
86
87impl From<ListGetRecordOutput<'_>> for List<'_> {
88    fn from(output: ListGetRecordOutput<'_>) -> Self {
89        use jacquard_common::IntoStatic;
90        output.value.into_static()
91    }
92}
93
94impl Collection for List<'_> {
95    const NSID: &'static str = "net.anisota.feed.list";
96    type Record = ListRecord;
97}
98
99impl Collection for ListRecord {
100    const NSID: &'static str = "net.anisota.feed.list";
101    type Record = ListRecord;
102}
103
104impl<'a> LexiconSchema for List<'a> {
105    fn nsid() -> &'static str {
106        "net.anisota.feed.list"
107    }
108    fn def_name() -> &'static str {
109        "main"
110    }
111    fn lexicon_doc() -> LexiconDoc<'static> {
112        lexicon_doc_net_anisota_feed_list()
113    }
114    fn validate(&self) -> Result<(), ConstraintError> {
115        if let Some(ref value) = self.avatar {
116            {
117                let size = value.blob().size;
118                if size > 1000000usize {
119                    return Err(ConstraintError::BlobTooLarge {
120                        path: ValidationPath::from_field("avatar"),
121                        max: 1000000usize,
122                        actual: size,
123                    });
124                }
125            }
126        }
127        if let Some(ref value) = self.avatar {
128            {
129                let mime = value.blob().mime_type.as_str();
130                let accepted: &[&str] = &["image/png", "image/jpeg"];
131                let matched = accepted
132                    .iter()
133                    .any(|pattern| {
134                        if *pattern == "*/*" {
135                            true
136                        } else if pattern.ends_with("/*") {
137                            let prefix = &pattern[..pattern.len() - 2];
138                            mime.starts_with(prefix)
139                                && mime.as_bytes().get(prefix.len()) == Some(&b'/')
140                        } else {
141                            mime == *pattern
142                        }
143                    });
144                if !matched {
145                    return Err(ConstraintError::BlobMimeTypeNotAccepted {
146                        path: ValidationPath::from_field("avatar"),
147                        accepted: vec![
148                            "image/png".to_string(), "image/jpeg".to_string()
149                        ],
150                        actual: mime.to_string(),
151                    });
152                }
153            }
154        }
155        if let Some(ref value) = self.description {
156            #[allow(unused_comparisons)]
157            if <str>::len(value.as_ref()) > 300usize {
158                return Err(ConstraintError::MaxLength {
159                    path: ValidationPath::from_field("description"),
160                    max: 300usize,
161                    actual: <str>::len(value.as_ref()),
162                });
163            }
164        }
165        {
166            let value = &self.name;
167            #[allow(unused_comparisons)]
168            if <str>::len(value.as_ref()) > 64usize {
169                return Err(ConstraintError::MaxLength {
170                    path: ValidationPath::from_field("name"),
171                    max: 64usize,
172                    actual: <str>::len(value.as_ref()),
173                });
174            }
175        }
176        if let Some(ref value) = self.tags {
177            #[allow(unused_comparisons)]
178            if value.len() > 10usize {
179                return Err(ConstraintError::MaxLength {
180                    path: ValidationPath::from_field("tags"),
181                    max: 10usize,
182                    actual: value.len(),
183                });
184            }
185        }
186        Ok(())
187    }
188}
189
190pub mod list_state {
191
192    pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
193    #[allow(unused)]
194    use ::core::marker::PhantomData;
195    mod sealed {
196        pub trait Sealed {}
197    }
198    /// State trait tracking which required fields have been set
199    pub trait State: sealed::Sealed {
200        type CreatedAt;
201        type Name;
202    }
203    /// Empty state - all required fields are unset
204    pub struct Empty(());
205    impl sealed::Sealed for Empty {}
206    impl State for Empty {
207        type CreatedAt = Unset;
208        type Name = Unset;
209    }
210    ///State transition - sets the `created_at` field to Set
211    pub struct SetCreatedAt<S: State = Empty>(PhantomData<fn() -> S>);
212    impl<S: State> sealed::Sealed for SetCreatedAt<S> {}
213    impl<S: State> State for SetCreatedAt<S> {
214        type CreatedAt = Set<members::created_at>;
215        type Name = S::Name;
216    }
217    ///State transition - sets the `name` field to Set
218    pub struct SetName<S: State = Empty>(PhantomData<fn() -> S>);
219    impl<S: State> sealed::Sealed for SetName<S> {}
220    impl<S: State> State for SetName<S> {
221        type CreatedAt = S::CreatedAt;
222        type Name = Set<members::name>;
223    }
224    /// Marker types for field names
225    #[allow(non_camel_case_types)]
226    pub mod members {
227        ///Marker type for the `created_at` field
228        pub struct created_at(());
229        ///Marker type for the `name` field
230        pub struct name(());
231    }
232}
233
234/// Builder for constructing an instance of this type
235pub struct ListBuilder<'a, S: list_state::State> {
236    _state: PhantomData<fn() -> S>,
237    _fields: (
238        Option<BlobRef<'a>>,
239        Option<Datetime>,
240        Option<CowStr<'a>>,
241        Option<CowStr<'a>>,
242        Option<Vec<CowStr<'a>>>,
243    ),
244    _lifetime: PhantomData<&'a ()>,
245}
246
247impl<'a> List<'a> {
248    /// Create a new builder for this type
249    pub fn new() -> ListBuilder<'a, list_state::Empty> {
250        ListBuilder::new()
251    }
252}
253
254impl<'a> ListBuilder<'a, list_state::Empty> {
255    /// Create a new builder with all fields unset
256    pub fn new() -> Self {
257        ListBuilder {
258            _state: PhantomData,
259            _fields: (None, None, None, None, None),
260            _lifetime: PhantomData,
261        }
262    }
263}
264
265impl<'a, S: list_state::State> ListBuilder<'a, S> {
266    /// Set the `avatar` field (optional)
267    pub fn avatar(mut self, value: impl Into<Option<BlobRef<'a>>>) -> Self {
268        self._fields.0 = value.into();
269        self
270    }
271    /// Set the `avatar` field to an Option value (optional)
272    pub fn maybe_avatar(mut self, value: Option<BlobRef<'a>>) -> Self {
273        self._fields.0 = value;
274        self
275    }
276}
277
278impl<'a, S> ListBuilder<'a, S>
279where
280    S: list_state::State,
281    S::CreatedAt: list_state::IsUnset,
282{
283    /// Set the `createdAt` field (required)
284    pub fn created_at(
285        mut self,
286        value: impl Into<Datetime>,
287    ) -> ListBuilder<'a, list_state::SetCreatedAt<S>> {
288        self._fields.1 = Option::Some(value.into());
289        ListBuilder {
290            _state: PhantomData,
291            _fields: self._fields,
292            _lifetime: PhantomData,
293        }
294    }
295}
296
297impl<'a, S: list_state::State> ListBuilder<'a, S> {
298    /// Set the `description` field (optional)
299    pub fn description(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
300        self._fields.2 = value.into();
301        self
302    }
303    /// Set the `description` field to an Option value (optional)
304    pub fn maybe_description(mut self, value: Option<CowStr<'a>>) -> Self {
305        self._fields.2 = value;
306        self
307    }
308}
309
310impl<'a, S> ListBuilder<'a, S>
311where
312    S: list_state::State,
313    S::Name: list_state::IsUnset,
314{
315    /// Set the `name` field (required)
316    pub fn name(
317        mut self,
318        value: impl Into<CowStr<'a>>,
319    ) -> ListBuilder<'a, list_state::SetName<S>> {
320        self._fields.3 = Option::Some(value.into());
321        ListBuilder {
322            _state: PhantomData,
323            _fields: self._fields,
324            _lifetime: PhantomData,
325        }
326    }
327}
328
329impl<'a, S: list_state::State> ListBuilder<'a, S> {
330    /// Set the `tags` field (optional)
331    pub fn tags(mut self, value: impl Into<Option<Vec<CowStr<'a>>>>) -> Self {
332        self._fields.4 = value.into();
333        self
334    }
335    /// Set the `tags` field to an Option value (optional)
336    pub fn maybe_tags(mut self, value: Option<Vec<CowStr<'a>>>) -> Self {
337        self._fields.4 = value;
338        self
339    }
340}
341
342impl<'a, S> ListBuilder<'a, S>
343where
344    S: list_state::State,
345    S::CreatedAt: list_state::IsSet,
346    S::Name: list_state::IsSet,
347{
348    /// Build the final struct
349    pub fn build(self) -> List<'a> {
350        List {
351            avatar: self._fields.0,
352            created_at: self._fields.1.unwrap(),
353            description: self._fields.2,
354            name: self._fields.3.unwrap(),
355            tags: self._fields.4,
356            extra_data: Default::default(),
357        }
358    }
359    /// Build the final struct with custom extra_data
360    pub fn build_with_data(
361        self,
362        extra_data: BTreeMap<
363            jacquard_common::deps::smol_str::SmolStr,
364            jacquard_common::types::value::Data<'a>,
365        >,
366    ) -> List<'a> {
367        List {
368            avatar: self._fields.0,
369            created_at: self._fields.1.unwrap(),
370            description: self._fields.2,
371            name: self._fields.3.unwrap(),
372            tags: self._fields.4,
373            extra_data: Some(extra_data),
374        }
375    }
376}
377
378fn lexicon_doc_net_anisota_feed_list() -> LexiconDoc<'static> {
379    #[allow(unused_imports)]
380    use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType};
381    use jacquard_lexicon::lexicon::*;
382    use alloc::collections::BTreeMap;
383    LexiconDoc {
384        lexicon: Lexicon::Lexicon1,
385        id: CowStr::new_static("net.anisota.feed.list"),
386        defs: {
387            let mut map = BTreeMap::new();
388            map.insert(
389                SmolStr::new_static("main"),
390                LexUserType::Record(LexRecord {
391                    description: Some(
392                        CowStr::new_static(
393                            "A list of posts for curation, bookmarking, or organization",
394                        ),
395                    ),
396                    key: Some(CowStr::new_static("tid")),
397                    record: LexRecordRecord::Object(LexObject {
398                        required: Some(
399                            vec![
400                                SmolStr::new_static("name"),
401                                SmolStr::new_static("createdAt")
402                            ],
403                        ),
404                        properties: {
405                            #[allow(unused_mut)]
406                            let mut map = BTreeMap::new();
407                            map.insert(
408                                SmolStr::new_static("avatar"),
409                                LexObjectProperty::Blob(LexBlob { ..Default::default() }),
410                            );
411                            map.insert(
412                                SmolStr::new_static("createdAt"),
413                                LexObjectProperty::String(LexString {
414                                    description: Some(
415                                        CowStr::new_static("When the list was created"),
416                                    ),
417                                    format: Some(LexStringFormat::Datetime),
418                                    ..Default::default()
419                                }),
420                            );
421                            map.insert(
422                                SmolStr::new_static("description"),
423                                LexObjectProperty::String(LexString {
424                                    description: Some(
425                                        CowStr::new_static("Optional description of the list"),
426                                    ),
427                                    max_length: Some(300usize),
428                                    ..Default::default()
429                                }),
430                            );
431                            map.insert(
432                                SmolStr::new_static("name"),
433                                LexObjectProperty::String(LexString {
434                                    description: Some(
435                                        CowStr::new_static("Display name for the list"),
436                                    ),
437                                    max_length: Some(64usize),
438                                    ..Default::default()
439                                }),
440                            );
441                            map.insert(
442                                SmolStr::new_static("tags"),
443                                LexObjectProperty::Array(LexArray {
444                                    description: Some(
445                                        CowStr::new_static("Tags for categorizing the list"),
446                                    ),
447                                    items: LexArrayItem::String(LexString {
448                                        max_length: Some(32usize),
449                                        ..Default::default()
450                                    }),
451                                    max_length: Some(10usize),
452                                    ..Default::default()
453                                }),
454                            );
455                            map
456                        },
457                        ..Default::default()
458                    }),
459                    ..Default::default()
460                }),
461            );
462            map
463        },
464        ..Default::default()
465    }
466}