Skip to main content

jacquard_api/sh_weaver/graph/
list.rs

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