Skip to main content

jacquard_api/blog_pckt/
post.rs

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