Skip to main content

jacquard_api/site_standard/
document.rs

1// @generated by jacquard-lexicon. DO NOT EDIT.
2//
3// Lexicon: site.standard.document
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::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::com_atproto::repo::strong_ref::StrongRef;
30use crate::pub_leaflet::content::Content;
31use crate::pub_leaflet::publication::Preferences;
32use crate::pub_leaflet::publication::Theme;
33
34#[lexicon]
35#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
36#[serde(rename_all = "camelCase", rename = "site.standard.document", tag = "$type")]
37pub struct Document<'a> {
38    #[serde(skip_serializing_if = "Option::is_none")]
39    #[serde(borrow)]
40    pub bsky_post_ref: Option<StrongRef<'a>>,
41    #[serde(skip_serializing_if = "Option::is_none")]
42    #[serde(borrow)]
43    pub content: Option<Content<'a>>,
44    #[serde(skip_serializing_if = "Option::is_none")]
45    #[serde(borrow)]
46    pub cover_image: Option<BlobRef<'a>>,
47    #[serde(skip_serializing_if = "Option::is_none")]
48    #[serde(borrow)]
49    pub description: Option<CowStr<'a>>,
50    ///combine with the publication url or the document site to construct a full url to the document
51    #[serde(skip_serializing_if = "Option::is_none")]
52    #[serde(borrow)]
53    pub path: Option<CowStr<'a>>,
54    #[serde(skip_serializing_if = "Option::is_none")]
55    #[serde(borrow)]
56    pub preferences: Option<Preferences<'a>>,
57    pub published_at: Datetime,
58    ///URI to the site or publication this document belongs to. Supports both AT-URIs (at://did/collection/rkey) for publication references and HTTPS URLs (https://example.com) for standalone documents or external sites.
59    #[serde(borrow)]
60    pub site: UriValue<'a>,
61    #[serde(skip_serializing_if = "Option::is_none")]
62    #[serde(borrow)]
63    pub tags: Option<Vec<CowStr<'a>>>,
64    #[serde(skip_serializing_if = "Option::is_none")]
65    #[serde(borrow)]
66    pub text_content: Option<CowStr<'a>>,
67    ///Theme for standalone documents. For documents in publications, theme is inherited from the publication.
68    #[serde(skip_serializing_if = "Option::is_none")]
69    #[serde(borrow)]
70    pub theme: Option<Theme<'a>>,
71    #[serde(borrow)]
72    pub title: CowStr<'a>,
73    #[serde(skip_serializing_if = "Option::is_none")]
74    pub updated_at: Option<Datetime>,
75}
76
77/// Typed wrapper for GetRecord response with this collection's record type.
78
79#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
80#[serde(rename_all = "camelCase")]
81pub struct DocumentGetRecordOutput<'a> {
82    #[serde(skip_serializing_if = "Option::is_none")]
83    #[serde(borrow)]
84    pub cid: Option<Cid<'a>>,
85    #[serde(borrow)]
86    pub uri: AtUri<'a>,
87    #[serde(borrow)]
88    pub value: Document<'a>,
89}
90
91impl<'a> Document<'a> {
92    pub fn uri(
93        uri: impl Into<CowStr<'a>>,
94    ) -> Result<RecordUri<'a, DocumentRecord>, UriError> {
95        RecordUri::try_from_uri(AtUri::new_cow(uri.into())?)
96    }
97}
98
99/// Marker type for deserializing records from this collection.
100
101#[derive(Debug, Serialize, Deserialize)]
102pub struct DocumentRecord;
103impl XrpcResp for DocumentRecord {
104    const NSID: &'static str = "site.standard.document";
105    const ENCODING: &'static str = "application/json";
106    type Output<'de> = DocumentGetRecordOutput<'de>;
107    type Err<'de> = RecordError<'de>;
108}
109
110impl From<DocumentGetRecordOutput<'_>> for Document<'_> {
111    fn from(output: DocumentGetRecordOutput<'_>) -> Self {
112        use jacquard_common::IntoStatic;
113        output.value.into_static()
114    }
115}
116
117impl Collection for Document<'_> {
118    const NSID: &'static str = "site.standard.document";
119    type Record = DocumentRecord;
120}
121
122impl Collection for DocumentRecord {
123    const NSID: &'static str = "site.standard.document";
124    type Record = DocumentRecord;
125}
126
127impl<'a> LexiconSchema for Document<'a> {
128    fn nsid() -> &'static str {
129        "site.standard.document"
130    }
131    fn def_name() -> &'static str {
132        "main"
133    }
134    fn lexicon_doc() -> LexiconDoc<'static> {
135        lexicon_doc_site_standard_document()
136    }
137    fn validate(&self) -> Result<(), ConstraintError> {
138        if let Some(ref value) = self.cover_image {
139            {
140                let size = value.blob().size;
141                if size > 1000000usize {
142                    return Err(ConstraintError::BlobTooLarge {
143                        path: ValidationPath::from_field("cover_image"),
144                        max: 1000000usize,
145                        actual: size,
146                    });
147                }
148            }
149        }
150        if let Some(ref value) = self.cover_image {
151            {
152                let mime = value.blob().mime_type.as_str();
153                let accepted: &[&str] = &["image/*"];
154                let matched = accepted
155                    .iter()
156                    .any(|pattern| {
157                        if *pattern == "*/*" {
158                            true
159                        } else if pattern.ends_with("/*") {
160                            let prefix = &pattern[..pattern.len() - 2];
161                            mime.starts_with(prefix)
162                                && mime.as_bytes().get(prefix.len()) == Some(&b'/')
163                        } else {
164                            mime == *pattern
165                        }
166                    });
167                if !matched {
168                    return Err(ConstraintError::BlobMimeTypeNotAccepted {
169                        path: ValidationPath::from_field("cover_image"),
170                        accepted: vec!["image/*".to_string()],
171                        actual: mime.to_string(),
172                    });
173                }
174            }
175        }
176        if let Some(ref value) = self.description {
177            #[allow(unused_comparisons)]
178            if <str>::len(value.as_ref()) > 30000usize {
179                return Err(ConstraintError::MaxLength {
180                    path: ValidationPath::from_field("description"),
181                    max: 30000usize,
182                    actual: <str>::len(value.as_ref()),
183                });
184            }
185        }
186        if let Some(ref value) = self.description {
187            {
188                let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count();
189                if count > 3000usize {
190                    return Err(ConstraintError::MaxGraphemes {
191                        path: ValidationPath::from_field("description"),
192                        max: 3000usize,
193                        actual: count,
194                    });
195                }
196            }
197        }
198        {
199            let value = &self.title;
200            #[allow(unused_comparisons)]
201            if <str>::len(value.as_ref()) > 5000usize {
202                return Err(ConstraintError::MaxLength {
203                    path: ValidationPath::from_field("title"),
204                    max: 5000usize,
205                    actual: <str>::len(value.as_ref()),
206                });
207            }
208        }
209        {
210            let value = &self.title;
211            {
212                let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count();
213                if count > 500usize {
214                    return Err(ConstraintError::MaxGraphemes {
215                        path: ValidationPath::from_field("title"),
216                        max: 500usize,
217                        actual: count,
218                    });
219                }
220            }
221        }
222        Ok(())
223    }
224}
225
226pub mod document_state {
227
228    pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
229    #[allow(unused)]
230    use ::core::marker::PhantomData;
231    mod sealed {
232        pub trait Sealed {}
233    }
234    /// State trait tracking which required fields have been set
235    pub trait State: sealed::Sealed {
236        type Title;
237        type PublishedAt;
238        type Site;
239    }
240    /// Empty state - all required fields are unset
241    pub struct Empty(());
242    impl sealed::Sealed for Empty {}
243    impl State for Empty {
244        type Title = Unset;
245        type PublishedAt = Unset;
246        type Site = Unset;
247    }
248    ///State transition - sets the `title` field to Set
249    pub struct SetTitle<S: State = Empty>(PhantomData<fn() -> S>);
250    impl<S: State> sealed::Sealed for SetTitle<S> {}
251    impl<S: State> State for SetTitle<S> {
252        type Title = Set<members::title>;
253        type PublishedAt = S::PublishedAt;
254        type Site = S::Site;
255    }
256    ///State transition - sets the `published_at` field to Set
257    pub struct SetPublishedAt<S: State = Empty>(PhantomData<fn() -> S>);
258    impl<S: State> sealed::Sealed for SetPublishedAt<S> {}
259    impl<S: State> State for SetPublishedAt<S> {
260        type Title = S::Title;
261        type PublishedAt = Set<members::published_at>;
262        type Site = S::Site;
263    }
264    ///State transition - sets the `site` field to Set
265    pub struct SetSite<S: State = Empty>(PhantomData<fn() -> S>);
266    impl<S: State> sealed::Sealed for SetSite<S> {}
267    impl<S: State> State for SetSite<S> {
268        type Title = S::Title;
269        type PublishedAt = S::PublishedAt;
270        type Site = Set<members::site>;
271    }
272    /// Marker types for field names
273    #[allow(non_camel_case_types)]
274    pub mod members {
275        ///Marker type for the `title` field
276        pub struct title(());
277        ///Marker type for the `published_at` field
278        pub struct published_at(());
279        ///Marker type for the `site` field
280        pub struct site(());
281    }
282}
283
284/// Builder for constructing an instance of this type
285pub struct DocumentBuilder<'a, S: document_state::State> {
286    _state: PhantomData<fn() -> S>,
287    _fields: (
288        Option<StrongRef<'a>>,
289        Option<Content<'a>>,
290        Option<BlobRef<'a>>,
291        Option<CowStr<'a>>,
292        Option<CowStr<'a>>,
293        Option<Preferences<'a>>,
294        Option<Datetime>,
295        Option<UriValue<'a>>,
296        Option<Vec<CowStr<'a>>>,
297        Option<CowStr<'a>>,
298        Option<Theme<'a>>,
299        Option<CowStr<'a>>,
300        Option<Datetime>,
301    ),
302    _lifetime: PhantomData<&'a ()>,
303}
304
305impl<'a> Document<'a> {
306    /// Create a new builder for this type
307    pub fn new() -> DocumentBuilder<'a, document_state::Empty> {
308        DocumentBuilder::new()
309    }
310}
311
312impl<'a> DocumentBuilder<'a, document_state::Empty> {
313    /// Create a new builder with all fields unset
314    pub fn new() -> Self {
315        DocumentBuilder {
316            _state: PhantomData,
317            _fields: (
318                None,
319                None,
320                None,
321                None,
322                None,
323                None,
324                None,
325                None,
326                None,
327                None,
328                None,
329                None,
330                None,
331            ),
332            _lifetime: PhantomData,
333        }
334    }
335}
336
337impl<'a, S: document_state::State> DocumentBuilder<'a, S> {
338    /// Set the `bskyPostRef` field (optional)
339    pub fn bsky_post_ref(mut self, value: impl Into<Option<StrongRef<'a>>>) -> Self {
340        self._fields.0 = value.into();
341        self
342    }
343    /// Set the `bskyPostRef` field to an Option value (optional)
344    pub fn maybe_bsky_post_ref(mut self, value: Option<StrongRef<'a>>) -> Self {
345        self._fields.0 = value;
346        self
347    }
348}
349
350impl<'a, S: document_state::State> DocumentBuilder<'a, S> {
351    /// Set the `content` field (optional)
352    pub fn content(mut self, value: impl Into<Option<Content<'a>>>) -> Self {
353        self._fields.1 = value.into();
354        self
355    }
356    /// Set the `content` field to an Option value (optional)
357    pub fn maybe_content(mut self, value: Option<Content<'a>>) -> Self {
358        self._fields.1 = value;
359        self
360    }
361}
362
363impl<'a, S: document_state::State> DocumentBuilder<'a, S> {
364    /// Set the `coverImage` field (optional)
365    pub fn cover_image(mut self, value: impl Into<Option<BlobRef<'a>>>) -> Self {
366        self._fields.2 = value.into();
367        self
368    }
369    /// Set the `coverImage` field to an Option value (optional)
370    pub fn maybe_cover_image(mut self, value: Option<BlobRef<'a>>) -> Self {
371        self._fields.2 = value;
372        self
373    }
374}
375
376impl<'a, S: document_state::State> DocumentBuilder<'a, S> {
377    /// Set the `description` field (optional)
378    pub fn description(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
379        self._fields.3 = value.into();
380        self
381    }
382    /// Set the `description` field to an Option value (optional)
383    pub fn maybe_description(mut self, value: Option<CowStr<'a>>) -> Self {
384        self._fields.3 = value;
385        self
386    }
387}
388
389impl<'a, S: document_state::State> DocumentBuilder<'a, S> {
390    /// Set the `path` field (optional)
391    pub fn path(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
392        self._fields.4 = value.into();
393        self
394    }
395    /// Set the `path` field to an Option value (optional)
396    pub fn maybe_path(mut self, value: Option<CowStr<'a>>) -> Self {
397        self._fields.4 = value;
398        self
399    }
400}
401
402impl<'a, S: document_state::State> DocumentBuilder<'a, S> {
403    /// Set the `preferences` field (optional)
404    pub fn preferences(mut self, value: impl Into<Option<Preferences<'a>>>) -> Self {
405        self._fields.5 = value.into();
406        self
407    }
408    /// Set the `preferences` field to an Option value (optional)
409    pub fn maybe_preferences(mut self, value: Option<Preferences<'a>>) -> Self {
410        self._fields.5 = value;
411        self
412    }
413}
414
415impl<'a, S> DocumentBuilder<'a, S>
416where
417    S: document_state::State,
418    S::PublishedAt: document_state::IsUnset,
419{
420    /// Set the `publishedAt` field (required)
421    pub fn published_at(
422        mut self,
423        value: impl Into<Datetime>,
424    ) -> DocumentBuilder<'a, document_state::SetPublishedAt<S>> {
425        self._fields.6 = Option::Some(value.into());
426        DocumentBuilder {
427            _state: PhantomData,
428            _fields: self._fields,
429            _lifetime: PhantomData,
430        }
431    }
432}
433
434impl<'a, S> DocumentBuilder<'a, S>
435where
436    S: document_state::State,
437    S::Site: document_state::IsUnset,
438{
439    /// Set the `site` field (required)
440    pub fn site(
441        mut self,
442        value: impl Into<UriValue<'a>>,
443    ) -> DocumentBuilder<'a, document_state::SetSite<S>> {
444        self._fields.7 = Option::Some(value.into());
445        DocumentBuilder {
446            _state: PhantomData,
447            _fields: self._fields,
448            _lifetime: PhantomData,
449        }
450    }
451}
452
453impl<'a, S: document_state::State> DocumentBuilder<'a, S> {
454    /// Set the `tags` field (optional)
455    pub fn tags(mut self, value: impl Into<Option<Vec<CowStr<'a>>>>) -> Self {
456        self._fields.8 = value.into();
457        self
458    }
459    /// Set the `tags` field to an Option value (optional)
460    pub fn maybe_tags(mut self, value: Option<Vec<CowStr<'a>>>) -> Self {
461        self._fields.8 = value;
462        self
463    }
464}
465
466impl<'a, S: document_state::State> DocumentBuilder<'a, S> {
467    /// Set the `textContent` field (optional)
468    pub fn text_content(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
469        self._fields.9 = value.into();
470        self
471    }
472    /// Set the `textContent` field to an Option value (optional)
473    pub fn maybe_text_content(mut self, value: Option<CowStr<'a>>) -> Self {
474        self._fields.9 = value;
475        self
476    }
477}
478
479impl<'a, S: document_state::State> DocumentBuilder<'a, S> {
480    /// Set the `theme` field (optional)
481    pub fn theme(mut self, value: impl Into<Option<Theme<'a>>>) -> Self {
482        self._fields.10 = value.into();
483        self
484    }
485    /// Set the `theme` field to an Option value (optional)
486    pub fn maybe_theme(mut self, value: Option<Theme<'a>>) -> Self {
487        self._fields.10 = value;
488        self
489    }
490}
491
492impl<'a, S> DocumentBuilder<'a, S>
493where
494    S: document_state::State,
495    S::Title: document_state::IsUnset,
496{
497    /// Set the `title` field (required)
498    pub fn title(
499        mut self,
500        value: impl Into<CowStr<'a>>,
501    ) -> DocumentBuilder<'a, document_state::SetTitle<S>> {
502        self._fields.11 = Option::Some(value.into());
503        DocumentBuilder {
504            _state: PhantomData,
505            _fields: self._fields,
506            _lifetime: PhantomData,
507        }
508    }
509}
510
511impl<'a, S: document_state::State> DocumentBuilder<'a, S> {
512    /// Set the `updatedAt` field (optional)
513    pub fn updated_at(mut self, value: impl Into<Option<Datetime>>) -> Self {
514        self._fields.12 = value.into();
515        self
516    }
517    /// Set the `updatedAt` field to an Option value (optional)
518    pub fn maybe_updated_at(mut self, value: Option<Datetime>) -> Self {
519        self._fields.12 = value;
520        self
521    }
522}
523
524impl<'a, S> DocumentBuilder<'a, S>
525where
526    S: document_state::State,
527    S::Title: document_state::IsSet,
528    S::PublishedAt: document_state::IsSet,
529    S::Site: document_state::IsSet,
530{
531    /// Build the final struct
532    pub fn build(self) -> Document<'a> {
533        Document {
534            bsky_post_ref: self._fields.0,
535            content: self._fields.1,
536            cover_image: self._fields.2,
537            description: self._fields.3,
538            path: self._fields.4,
539            preferences: self._fields.5,
540            published_at: self._fields.6.unwrap(),
541            site: self._fields.7.unwrap(),
542            tags: self._fields.8,
543            text_content: self._fields.9,
544            theme: self._fields.10,
545            title: self._fields.11.unwrap(),
546            updated_at: self._fields.12,
547            extra_data: Default::default(),
548        }
549    }
550    /// Build the final struct with custom extra_data
551    pub fn build_with_data(
552        self,
553        extra_data: BTreeMap<
554            jacquard_common::deps::smol_str::SmolStr,
555            jacquard_common::types::value::Data<'a>,
556        >,
557    ) -> Document<'a> {
558        Document {
559            bsky_post_ref: self._fields.0,
560            content: self._fields.1,
561            cover_image: self._fields.2,
562            description: self._fields.3,
563            path: self._fields.4,
564            preferences: self._fields.5,
565            published_at: self._fields.6.unwrap(),
566            site: self._fields.7.unwrap(),
567            tags: self._fields.8,
568            text_content: self._fields.9,
569            theme: self._fields.10,
570            title: self._fields.11.unwrap(),
571            updated_at: self._fields.12,
572            extra_data: Some(extra_data),
573        }
574    }
575}
576
577fn lexicon_doc_site_standard_document() -> LexiconDoc<'static> {
578    #[allow(unused_imports)]
579    use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType};
580    use jacquard_lexicon::lexicon::*;
581    use alloc::collections::BTreeMap;
582    LexiconDoc {
583        lexicon: Lexicon::Lexicon1,
584        id: CowStr::new_static("site.standard.document"),
585        defs: {
586            let mut map = BTreeMap::new();
587            map.insert(
588                SmolStr::new_static("main"),
589                LexUserType::Record(LexRecord {
590                    key: Some(CowStr::new_static("tid")),
591                    record: LexRecordRecord::Object(LexObject {
592                        required: Some(
593                            vec![
594                                SmolStr::new_static("site"), SmolStr::new_static("title"),
595                                SmolStr::new_static("publishedAt")
596                            ],
597                        ),
598                        properties: {
599                            #[allow(unused_mut)]
600                            let mut map = BTreeMap::new();
601                            map.insert(
602                                SmolStr::new_static("bskyPostRef"),
603                                LexObjectProperty::Ref(LexRef {
604                                    r#ref: CowStr::new_static("com.atproto.repo.strongRef"),
605                                    ..Default::default()
606                                }),
607                            );
608                            map.insert(
609                                SmolStr::new_static("content"),
610                                LexObjectProperty::Union(LexRefUnion {
611                                    refs: vec![CowStr::new_static("pub.leaflet.content")],
612                                    closed: Some(false),
613                                    ..Default::default()
614                                }),
615                            );
616                            map.insert(
617                                SmolStr::new_static("coverImage"),
618                                LexObjectProperty::Blob(LexBlob { ..Default::default() }),
619                            );
620                            map.insert(
621                                SmolStr::new_static("description"),
622                                LexObjectProperty::String(LexString {
623                                    max_length: Some(30000usize),
624                                    max_graphemes: Some(3000usize),
625                                    ..Default::default()
626                                }),
627                            );
628                            map.insert(
629                                SmolStr::new_static("path"),
630                                LexObjectProperty::String(LexString {
631                                    description: Some(
632                                        CowStr::new_static(
633                                            "combine with the publication url or the document site to construct a full url to the document",
634                                        ),
635                                    ),
636                                    ..Default::default()
637                                }),
638                            );
639                            map.insert(
640                                SmolStr::new_static("preferences"),
641                                LexObjectProperty::Union(LexRefUnion {
642                                    refs: vec![
643                                        CowStr::new_static("pub.leaflet.publication#preferences")
644                                    ],
645                                    closed: Some(false),
646                                    ..Default::default()
647                                }),
648                            );
649                            map.insert(
650                                SmolStr::new_static("publishedAt"),
651                                LexObjectProperty::String(LexString {
652                                    format: Some(LexStringFormat::Datetime),
653                                    ..Default::default()
654                                }),
655                            );
656                            map.insert(
657                                SmolStr::new_static("site"),
658                                LexObjectProperty::String(LexString {
659                                    description: Some(
660                                        CowStr::new_static(
661                                            "URI to the site or publication this document belongs to. Supports both AT-URIs (at://did/collection/rkey) for publication references and HTTPS URLs (https://example.com) for standalone documents or external sites.",
662                                        ),
663                                    ),
664                                    format: Some(LexStringFormat::Uri),
665                                    ..Default::default()
666                                }),
667                            );
668                            map.insert(
669                                SmolStr::new_static("tags"),
670                                LexObjectProperty::Array(LexArray {
671                                    items: LexArrayItem::String(LexString {
672                                        max_length: Some(100usize),
673                                        max_graphemes: Some(50usize),
674                                        ..Default::default()
675                                    }),
676                                    ..Default::default()
677                                }),
678                            );
679                            map.insert(
680                                SmolStr::new_static("textContent"),
681                                LexObjectProperty::String(LexString {
682                                    ..Default::default()
683                                }),
684                            );
685                            map.insert(
686                                SmolStr::new_static("theme"),
687                                LexObjectProperty::Ref(LexRef {
688                                    r#ref: CowStr::new_static("pub.leaflet.publication#theme"),
689                                    ..Default::default()
690                                }),
691                            );
692                            map.insert(
693                                SmolStr::new_static("title"),
694                                LexObjectProperty::String(LexString {
695                                    max_length: Some(5000usize),
696                                    max_graphemes: Some(500usize),
697                                    ..Default::default()
698                                }),
699                            );
700                            map.insert(
701                                SmolStr::new_static("updatedAt"),
702                                LexObjectProperty::String(LexString {
703                                    format: Some(LexStringFormat::Datetime),
704                                    ..Default::default()
705                                }),
706                            );
707                            map
708                        },
709                        ..Default::default()
710                    }),
711                    ..Default::default()
712                }),
713            );
714            map
715        },
716        ..Default::default()
717    }
718}