Skip to main content

jacquard_api/app_bsky/feed/
threadgate.rs

1// @generated by jacquard-lexicon. DO NOT EDIT.
2//
3// Lexicon: app.bsky.feed.threadgate
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::collection::{Collection, RecordError};
19use jacquard_common::types::string::{AtUri, Cid, Datetime};
20use jacquard_common::types::uri::{RecordUri, UriError};
21use jacquard_common::types::value::Data;
22use jacquard_common::xrpc::XrpcResp;
23use jacquard_derive::{IntoStatic, lexicon, open_union};
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::app_bsky::feed::threadgate;
31/// Allow replies from actors who follow you.
32
33#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
34#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
35pub struct FollowerRule<S: BosStr = DefaultStr> {
36    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
37    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
38}
39
40/// Allow replies from actors you follow.
41
42#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
43#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
44pub struct FollowingRule<S: BosStr = DefaultStr> {
45    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
46    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
47}
48
49/// Allow replies from actors on a list.
50
51#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
52#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
53pub struct ListRule<S: BosStr = DefaultStr> {
54    pub list: AtUri<S>,
55    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
56    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
57}
58
59/// Record defining interaction gating rules for a thread (aka, reply controls). The record key (rkey) of the threadgate record must match the record key of the thread's root post, and that record must be in the same repository.
60
61#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
62#[serde(
63    rename_all = "camelCase",
64    rename = "app.bsky.feed.threadgate",
65    tag = "$type",
66    bound(deserialize = "S: Deserialize<'de> + BosStr")
67)]
68pub struct Threadgate<S: BosStr = DefaultStr> {
69    ///List of rules defining who can reply to this post. If value is an empty array, no one can reply. If value is undefined, anyone can reply.
70    #[serde(skip_serializing_if = "Option::is_none")]
71    pub allow: Option<Vec<ThreadgateAllowItem<S>>>,
72    pub created_at: Datetime,
73    ///List of hidden reply URIs.
74    #[serde(skip_serializing_if = "Option::is_none")]
75    pub hidden_replies: Option<Vec<AtUri<S>>>,
76    ///Reference (AT-URI) to the post record.
77    pub post: AtUri<S>,
78    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
79    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
80}
81
82
83#[open_union]
84#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
85#[serde(tag = "$type", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
86pub enum ThreadgateAllowItem<S: BosStr = DefaultStr> {
87    #[serde(rename = "app.bsky.feed.threadgate#mentionRule")]
88    MentionRule(Box<threadgate::MentionRule<S>>),
89    #[serde(rename = "app.bsky.feed.threadgate#followerRule")]
90    FollowerRule(Box<threadgate::FollowerRule<S>>),
91    #[serde(rename = "app.bsky.feed.threadgate#followingRule")]
92    FollowingRule(Box<threadgate::FollowingRule<S>>),
93    #[serde(rename = "app.bsky.feed.threadgate#listRule")]
94    ListRule(Box<threadgate::ListRule<S>>),
95}
96
97/// Typed wrapper for GetRecord response with this collection's record type.
98
99#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
100#[serde(rename_all = "camelCase")]
101pub struct ThreadgateGetRecordOutput<S: BosStr = DefaultStr> {
102    #[serde(skip_serializing_if = "Option::is_none")]
103    pub cid: Option<Cid<S>>,
104    pub uri: AtUri<S>,
105    pub value: Threadgate<S>,
106}
107
108/// Allow replies from actors mentioned in your post.
109
110#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
111#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
112pub struct MentionRule<S: BosStr = DefaultStr> {
113    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
114    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
115}
116
117impl<S: BosStr> Threadgate<S> {
118    pub fn uri(uri: S) -> Result<RecordUri<S, ThreadgateRecord>, UriError> {
119        RecordUri::try_from_uri(AtUri::new(uri)?)
120    }
121}
122
123impl<S: BosStr> LexiconSchema for FollowerRule<S> {
124    fn nsid() -> &'static str {
125        "app.bsky.feed.threadgate"
126    }
127    fn def_name() -> &'static str {
128        "followerRule"
129    }
130    fn lexicon_doc() -> LexiconDoc<'static> {
131        lexicon_doc_app_bsky_feed_threadgate()
132    }
133    fn validate(&self) -> Result<(), ConstraintError> {
134        Ok(())
135    }
136}
137
138impl<S: BosStr> LexiconSchema for FollowingRule<S> {
139    fn nsid() -> &'static str {
140        "app.bsky.feed.threadgate"
141    }
142    fn def_name() -> &'static str {
143        "followingRule"
144    }
145    fn lexicon_doc() -> LexiconDoc<'static> {
146        lexicon_doc_app_bsky_feed_threadgate()
147    }
148    fn validate(&self) -> Result<(), ConstraintError> {
149        Ok(())
150    }
151}
152
153impl<S: BosStr> LexiconSchema for ListRule<S> {
154    fn nsid() -> &'static str {
155        "app.bsky.feed.threadgate"
156    }
157    fn def_name() -> &'static str {
158        "listRule"
159    }
160    fn lexicon_doc() -> LexiconDoc<'static> {
161        lexicon_doc_app_bsky_feed_threadgate()
162    }
163    fn validate(&self) -> Result<(), ConstraintError> {
164        Ok(())
165    }
166}
167
168/// Marker type for deserializing records from this collection.
169
170#[derive(Debug, Serialize, Deserialize)]
171pub struct ThreadgateRecord;
172impl XrpcResp for ThreadgateRecord {
173    const NSID: &'static str = "app.bsky.feed.threadgate";
174    const ENCODING: &'static str = "application/json";
175    type Output<S: BosStr> = ThreadgateGetRecordOutput<S>;
176    type Err = RecordError;
177}
178
179impl<S: BosStr> From<ThreadgateGetRecordOutput<S>> for Threadgate<S> {
180    fn from(output: ThreadgateGetRecordOutput<S>) -> Self {
181        output.value
182    }
183}
184
185impl<S: BosStr> Collection for Threadgate<S> {
186    const NSID: &'static str = "app.bsky.feed.threadgate";
187    type Record = ThreadgateRecord;
188}
189
190impl Collection for ThreadgateRecord {
191    const NSID: &'static str = "app.bsky.feed.threadgate";
192    type Record = ThreadgateRecord;
193}
194
195impl<S: BosStr> LexiconSchema for Threadgate<S> {
196    fn nsid() -> &'static str {
197        "app.bsky.feed.threadgate"
198    }
199    fn def_name() -> &'static str {
200        "main"
201    }
202    fn lexicon_doc() -> LexiconDoc<'static> {
203        lexicon_doc_app_bsky_feed_threadgate()
204    }
205    fn validate(&self) -> Result<(), ConstraintError> {
206        if let Some(ref value) = self.allow {
207            #[allow(unused_comparisons)]
208            if value.len() > 5usize {
209                return Err(ConstraintError::MaxLength {
210                    path: ValidationPath::from_field("allow"),
211                    max: 5usize,
212                    actual: value.len(),
213                });
214            }
215        }
216        if let Some(ref value) = self.hidden_replies {
217            #[allow(unused_comparisons)]
218            if value.len() > 300usize {
219                return Err(ConstraintError::MaxLength {
220                    path: ValidationPath::from_field("hidden_replies"),
221                    max: 300usize,
222                    actual: value.len(),
223                });
224            }
225        }
226        Ok(())
227    }
228}
229
230impl<S: BosStr> LexiconSchema for MentionRule<S> {
231    fn nsid() -> &'static str {
232        "app.bsky.feed.threadgate"
233    }
234    fn def_name() -> &'static str {
235        "mentionRule"
236    }
237    fn lexicon_doc() -> LexiconDoc<'static> {
238        lexicon_doc_app_bsky_feed_threadgate()
239    }
240    fn validate(&self) -> Result<(), ConstraintError> {
241        Ok(())
242    }
243}
244
245fn lexicon_doc_app_bsky_feed_threadgate() -> LexiconDoc<'static> {
246    #[allow(unused_imports)]
247    use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType};
248    use jacquard_lexicon::lexicon::*;
249    use alloc::collections::BTreeMap;
250    LexiconDoc {
251        lexicon: Lexicon::Lexicon1,
252        id: CowStr::new_static("app.bsky.feed.threadgate"),
253        defs: {
254            let mut map = BTreeMap::new();
255            map.insert(
256                SmolStr::new_static("followerRule"),
257                LexUserType::Object(LexObject {
258                    description: Some(
259                        CowStr::new_static("Allow replies from actors who follow you."),
260                    ),
261                    properties: {
262                        #[allow(unused_mut)]
263                        let mut map = BTreeMap::new();
264                        map
265                    },
266                    ..Default::default()
267                }),
268            );
269            map.insert(
270                SmolStr::new_static("followingRule"),
271                LexUserType::Object(LexObject {
272                    description: Some(
273                        CowStr::new_static("Allow replies from actors you follow."),
274                    ),
275                    properties: {
276                        #[allow(unused_mut)]
277                        let mut map = BTreeMap::new();
278                        map
279                    },
280                    ..Default::default()
281                }),
282            );
283            map.insert(
284                SmolStr::new_static("listRule"),
285                LexUserType::Object(LexObject {
286                    description: Some(
287                        CowStr::new_static("Allow replies from actors on a list."),
288                    ),
289                    required: Some(vec![SmolStr::new_static("list")]),
290                    properties: {
291                        #[allow(unused_mut)]
292                        let mut map = BTreeMap::new();
293                        map.insert(
294                            SmolStr::new_static("list"),
295                            LexObjectProperty::String(LexString {
296                                format: Some(LexStringFormat::AtUri),
297                                ..Default::default()
298                            }),
299                        );
300                        map
301                    },
302                    ..Default::default()
303                }),
304            );
305            map.insert(
306                SmolStr::new_static("main"),
307                LexUserType::Record(LexRecord {
308                    description: Some(
309                        CowStr::new_static(
310                            "Record defining interaction gating rules for a thread (aka, reply controls). The record key (rkey) of the threadgate record must match the record key of the thread's root post, and that record must be in the same repository.",
311                        ),
312                    ),
313                    key: Some(CowStr::new_static("tid")),
314                    record: LexRecordRecord::Object(LexObject {
315                        required: Some(
316                            vec![
317                                SmolStr::new_static("post"),
318                                SmolStr::new_static("createdAt")
319                            ],
320                        ),
321                        properties: {
322                            #[allow(unused_mut)]
323                            let mut map = BTreeMap::new();
324                            map.insert(
325                                SmolStr::new_static("allow"),
326                                LexObjectProperty::Array(LexArray {
327                                    description: Some(
328                                        CowStr::new_static(
329                                            "List of rules defining who can reply to this post. If value is an empty array, no one can reply. If value is undefined, anyone can reply.",
330                                        ),
331                                    ),
332                                    items: LexArrayItem::Union(LexRefUnion {
333                                        refs: vec![
334                                            CowStr::new_static("#mentionRule"),
335                                            CowStr::new_static("#followerRule"),
336                                            CowStr::new_static("#followingRule"),
337                                            CowStr::new_static("#listRule")
338                                        ],
339                                        ..Default::default()
340                                    }),
341                                    max_length: Some(5usize),
342                                    ..Default::default()
343                                }),
344                            );
345                            map.insert(
346                                SmolStr::new_static("createdAt"),
347                                LexObjectProperty::String(LexString {
348                                    format: Some(LexStringFormat::Datetime),
349                                    ..Default::default()
350                                }),
351                            );
352                            map.insert(
353                                SmolStr::new_static("hiddenReplies"),
354                                LexObjectProperty::Array(LexArray {
355                                    description: Some(
356                                        CowStr::new_static("List of hidden reply URIs."),
357                                    ),
358                                    items: LexArrayItem::String(LexString {
359                                        format: Some(LexStringFormat::AtUri),
360                                        ..Default::default()
361                                    }),
362                                    max_length: Some(300usize),
363                                    ..Default::default()
364                                }),
365                            );
366                            map.insert(
367                                SmolStr::new_static("post"),
368                                LexObjectProperty::String(LexString {
369                                    description: Some(
370                                        CowStr::new_static("Reference (AT-URI) to the post record."),
371                                    ),
372                                    format: Some(LexStringFormat::AtUri),
373                                    ..Default::default()
374                                }),
375                            );
376                            map
377                        },
378                        ..Default::default()
379                    }),
380                    ..Default::default()
381                }),
382            );
383            map.insert(
384                SmolStr::new_static("mentionRule"),
385                LexUserType::Object(LexObject {
386                    description: Some(
387                        CowStr::new_static(
388                            "Allow replies from actors mentioned in your post.",
389                        ),
390                    ),
391                    properties: {
392                        #[allow(unused_mut)]
393                        let mut map = BTreeMap::new();
394                        map
395                    },
396                    ..Default::default()
397                }),
398            );
399            map
400        },
401        ..Default::default()
402    }
403}
404
405pub mod list_rule_state {
406
407    pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
408    #[allow(unused)]
409    use ::core::marker::PhantomData;
410    mod sealed {
411        pub trait Sealed {}
412    }
413    /// State trait tracking which required fields have been set
414    pub trait State: sealed::Sealed {
415        type List;
416    }
417    /// Empty state - all required fields are unset
418    pub struct Empty(());
419    impl sealed::Sealed for Empty {}
420    impl State for Empty {
421        type List = Unset;
422    }
423    ///State transition - sets the `list` field to Set
424    pub struct SetList<St: State = Empty>(PhantomData<fn() -> St>);
425    impl<St: State> sealed::Sealed for SetList<St> {}
426    impl<St: State> State for SetList<St> {
427        type List = Set<members::list>;
428    }
429    /// Marker types for field names
430    #[allow(non_camel_case_types)]
431    pub mod members {
432        ///Marker type for the `list` field
433        pub struct list(());
434    }
435}
436
437/// Builder for constructing an instance of this type.
438pub struct ListRuleBuilder<St: list_rule_state::State, S: BosStr = DefaultStr> {
439    _state: PhantomData<fn() -> St>,
440    _fields: (Option<AtUri<S>>,),
441    _type: PhantomData<fn() -> S>,
442}
443
444impl ListRule<DefaultStr> {
445    /// Create a new builder for this type, using the default string type (DefaultStr = SmolStr) if needed
446    pub fn new() -> ListRuleBuilder<list_rule_state::Empty, DefaultStr> {
447        ListRuleBuilder::new()
448    }
449}
450
451impl<S: BosStr> ListRule<S> {
452    /// Create a new builder for this type
453    pub fn builder() -> ListRuleBuilder<list_rule_state::Empty, S> {
454        ListRuleBuilder::builder()
455    }
456}
457
458impl ListRuleBuilder<list_rule_state::Empty, DefaultStr> {
459    /// Create a new builder with all fields unset, using the default string type, if needed
460    pub fn new() -> Self {
461        ListRuleBuilder {
462            _state: PhantomData,
463            _fields: (None,),
464            _type: PhantomData,
465        }
466    }
467}
468
469impl<S: BosStr> ListRuleBuilder<list_rule_state::Empty, S> {
470    /// Create a new builder with all fields unset
471    pub fn builder() -> Self {
472        ListRuleBuilder {
473            _state: PhantomData,
474            _fields: (None,),
475            _type: PhantomData,
476        }
477    }
478}
479
480impl<St, S: BosStr> ListRuleBuilder<St, S>
481where
482    St: list_rule_state::State,
483    St::List: list_rule_state::IsUnset,
484{
485    /// Set the `list` field (required)
486    pub fn list(
487        mut self,
488        value: impl Into<AtUri<S>>,
489    ) -> ListRuleBuilder<list_rule_state::SetList<St>, S> {
490        self._fields.0 = Option::Some(value.into());
491        ListRuleBuilder {
492            _state: PhantomData,
493            _fields: self._fields,
494            _type: PhantomData,
495        }
496    }
497}
498
499impl<St, S: BosStr> ListRuleBuilder<St, S>
500where
501    St: list_rule_state::State,
502    St::List: list_rule_state::IsSet,
503{
504    /// Build the final struct.
505    pub fn build(self) -> ListRule<S> {
506        ListRule {
507            list: self._fields.0.unwrap(),
508            extra_data: Default::default(),
509        }
510    }
511    /// Build the final struct with custom extra_data.
512    pub fn build_with_data(self, extra_data: BTreeMap<SmolStr, Data<S>>) -> ListRule<S> {
513        ListRule {
514            list: self._fields.0.unwrap(),
515            extra_data: Some(extra_data),
516        }
517    }
518}
519
520pub mod threadgate_state {
521
522    pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
523    #[allow(unused)]
524    use ::core::marker::PhantomData;
525    mod sealed {
526        pub trait Sealed {}
527    }
528    /// State trait tracking which required fields have been set
529    pub trait State: sealed::Sealed {
530        type CreatedAt;
531        type Post;
532    }
533    /// Empty state - all required fields are unset
534    pub struct Empty(());
535    impl sealed::Sealed for Empty {}
536    impl State for Empty {
537        type CreatedAt = Unset;
538        type Post = Unset;
539    }
540    ///State transition - sets the `created_at` field to Set
541    pub struct SetCreatedAt<St: State = Empty>(PhantomData<fn() -> St>);
542    impl<St: State> sealed::Sealed for SetCreatedAt<St> {}
543    impl<St: State> State for SetCreatedAt<St> {
544        type CreatedAt = Set<members::created_at>;
545        type Post = St::Post;
546    }
547    ///State transition - sets the `post` field to Set
548    pub struct SetPost<St: State = Empty>(PhantomData<fn() -> St>);
549    impl<St: State> sealed::Sealed for SetPost<St> {}
550    impl<St: State> State for SetPost<St> {
551        type CreatedAt = St::CreatedAt;
552        type Post = Set<members::post>;
553    }
554    /// Marker types for field names
555    #[allow(non_camel_case_types)]
556    pub mod members {
557        ///Marker type for the `created_at` field
558        pub struct created_at(());
559        ///Marker type for the `post` field
560        pub struct post(());
561    }
562}
563
564/// Builder for constructing an instance of this type.
565pub struct ThreadgateBuilder<St: threadgate_state::State, S: BosStr = DefaultStr> {
566    _state: PhantomData<fn() -> St>,
567    _fields: (
568        Option<Vec<ThreadgateAllowItem<S>>>,
569        Option<Datetime>,
570        Option<Vec<AtUri<S>>>,
571        Option<AtUri<S>>,
572    ),
573    _type: PhantomData<fn() -> S>,
574}
575
576impl Threadgate<DefaultStr> {
577    /// Create a new builder for this type, using the default string type (DefaultStr = SmolStr) if needed
578    pub fn new() -> ThreadgateBuilder<threadgate_state::Empty, DefaultStr> {
579        ThreadgateBuilder::new()
580    }
581}
582
583impl<S: BosStr> Threadgate<S> {
584    /// Create a new builder for this type
585    pub fn builder() -> ThreadgateBuilder<threadgate_state::Empty, S> {
586        ThreadgateBuilder::builder()
587    }
588}
589
590impl ThreadgateBuilder<threadgate_state::Empty, DefaultStr> {
591    /// Create a new builder with all fields unset, using the default string type, if needed
592    pub fn new() -> Self {
593        ThreadgateBuilder {
594            _state: PhantomData,
595            _fields: (None, None, None, None),
596            _type: PhantomData,
597        }
598    }
599}
600
601impl<S: BosStr> ThreadgateBuilder<threadgate_state::Empty, S> {
602    /// Create a new builder with all fields unset
603    pub fn builder() -> Self {
604        ThreadgateBuilder {
605            _state: PhantomData,
606            _fields: (None, None, None, None),
607            _type: PhantomData,
608        }
609    }
610}
611
612impl<St: threadgate_state::State, S: BosStr> ThreadgateBuilder<St, S> {
613    /// Set the `allow` field (optional)
614    pub fn allow(
615        mut self,
616        value: impl Into<Option<Vec<ThreadgateAllowItem<S>>>>,
617    ) -> Self {
618        self._fields.0 = value.into();
619        self
620    }
621    /// Set the `allow` field to an Option value (optional)
622    pub fn maybe_allow(mut self, value: Option<Vec<ThreadgateAllowItem<S>>>) -> Self {
623        self._fields.0 = value;
624        self
625    }
626}
627
628impl<St, S: BosStr> ThreadgateBuilder<St, S>
629where
630    St: threadgate_state::State,
631    St::CreatedAt: threadgate_state::IsUnset,
632{
633    /// Set the `createdAt` field (required)
634    pub fn created_at(
635        mut self,
636        value: impl Into<Datetime>,
637    ) -> ThreadgateBuilder<threadgate_state::SetCreatedAt<St>, S> {
638        self._fields.1 = Option::Some(value.into());
639        ThreadgateBuilder {
640            _state: PhantomData,
641            _fields: self._fields,
642            _type: PhantomData,
643        }
644    }
645}
646
647impl<St: threadgate_state::State, S: BosStr> ThreadgateBuilder<St, S> {
648    /// Set the `hiddenReplies` field (optional)
649    pub fn hidden_replies(mut self, value: impl Into<Option<Vec<AtUri<S>>>>) -> Self {
650        self._fields.2 = value.into();
651        self
652    }
653    /// Set the `hiddenReplies` field to an Option value (optional)
654    pub fn maybe_hidden_replies(mut self, value: Option<Vec<AtUri<S>>>) -> Self {
655        self._fields.2 = value;
656        self
657    }
658}
659
660impl<St, S: BosStr> ThreadgateBuilder<St, S>
661where
662    St: threadgate_state::State,
663    St::Post: threadgate_state::IsUnset,
664{
665    /// Set the `post` field (required)
666    pub fn post(
667        mut self,
668        value: impl Into<AtUri<S>>,
669    ) -> ThreadgateBuilder<threadgate_state::SetPost<St>, S> {
670        self._fields.3 = Option::Some(value.into());
671        ThreadgateBuilder {
672            _state: PhantomData,
673            _fields: self._fields,
674            _type: PhantomData,
675        }
676    }
677}
678
679impl<St, S: BosStr> ThreadgateBuilder<St, S>
680where
681    St: threadgate_state::State,
682    St::CreatedAt: threadgate_state::IsSet,
683    St::Post: threadgate_state::IsSet,
684{
685    /// Build the final struct.
686    pub fn build(self) -> Threadgate<S> {
687        Threadgate {
688            allow: self._fields.0,
689            created_at: self._fields.1.unwrap(),
690            hidden_replies: self._fields.2,
691            post: self._fields.3.unwrap(),
692            extra_data: Default::default(),
693        }
694    }
695    /// Build the final struct with custom extra_data.
696    pub fn build_with_data(
697        self,
698        extra_data: BTreeMap<SmolStr, Data<S>>,
699    ) -> Threadgate<S> {
700        Threadgate {
701            allow: self._fields.0,
702            created_at: self._fields.1.unwrap(),
703            hidden_replies: self._fields.2,
704            post: self._fields.3.unwrap(),
705            extra_data: Some(extra_data),
706        }
707    }
708}