jacquard_api/pub_leaflet/blocks/
website.rs1#[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::string::UriValue;
19use jacquard_derive::{IntoStatic, lexicon};
20use jacquard_lexicon::lexicon::LexiconDoc;
21use jacquard_lexicon::schema::LexiconSchema;
22
23#[allow(unused_imports)]
24use jacquard_lexicon::validation::{ConstraintError, ValidationPath};
25use serde::{Serialize, Deserialize};
26
27#[lexicon]
28#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
29#[serde(rename_all = "camelCase")]
30pub struct Website<'a> {
31 #[serde(skip_serializing_if = "Option::is_none")]
32 #[serde(borrow)]
33 pub description: Option<CowStr<'a>>,
34 #[serde(skip_serializing_if = "Option::is_none")]
35 #[serde(borrow)]
36 pub preview_image: Option<BlobRef<'a>>,
37 #[serde(borrow)]
38 pub src: UriValue<'a>,
39 #[serde(skip_serializing_if = "Option::is_none")]
40 #[serde(borrow)]
41 pub title: Option<CowStr<'a>>,
42}
43
44impl<'a> LexiconSchema for Website<'a> {
45 fn nsid() -> &'static str {
46 "pub.leaflet.blocks.website"
47 }
48 fn def_name() -> &'static str {
49 "main"
50 }
51 fn lexicon_doc() -> LexiconDoc<'static> {
52 lexicon_doc_pub_leaflet_blocks_website()
53 }
54 fn validate(&self) -> Result<(), ConstraintError> {
55 if let Some(ref value) = self.preview_image {
56 {
57 let size = value.blob().size;
58 if size > 1000000usize {
59 return Err(ConstraintError::BlobTooLarge {
60 path: ValidationPath::from_field("preview_image"),
61 max: 1000000usize,
62 actual: size,
63 });
64 }
65 }
66 }
67 if let Some(ref value) = self.preview_image {
68 {
69 let mime = value.blob().mime_type.as_str();
70 let accepted: &[&str] = &["image/*"];
71 let matched = accepted
72 .iter()
73 .any(|pattern| {
74 if *pattern == "*/*" {
75 true
76 } else if pattern.ends_with("/*") {
77 let prefix = &pattern[..pattern.len() - 2];
78 mime.starts_with(prefix)
79 && mime.as_bytes().get(prefix.len()) == Some(&b'/')
80 } else {
81 mime == *pattern
82 }
83 });
84 if !matched {
85 return Err(ConstraintError::BlobMimeTypeNotAccepted {
86 path: ValidationPath::from_field("preview_image"),
87 accepted: vec!["image/*".to_string()],
88 actual: mime.to_string(),
89 });
90 }
91 }
92 }
93 Ok(())
94 }
95}
96
97pub mod website_state {
98
99 pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
100 #[allow(unused)]
101 use ::core::marker::PhantomData;
102 mod sealed {
103 pub trait Sealed {}
104 }
105 pub trait State: sealed::Sealed {
107 type Src;
108 }
109 pub struct Empty(());
111 impl sealed::Sealed for Empty {}
112 impl State for Empty {
113 type Src = Unset;
114 }
115 pub struct SetSrc<S: State = Empty>(PhantomData<fn() -> S>);
117 impl<S: State> sealed::Sealed for SetSrc<S> {}
118 impl<S: State> State for SetSrc<S> {
119 type Src = Set<members::src>;
120 }
121 #[allow(non_camel_case_types)]
123 pub mod members {
124 pub struct src(());
126 }
127}
128
129pub struct WebsiteBuilder<'a, S: website_state::State> {
131 _state: PhantomData<fn() -> S>,
132 _fields: (
133 Option<CowStr<'a>>,
134 Option<BlobRef<'a>>,
135 Option<UriValue<'a>>,
136 Option<CowStr<'a>>,
137 ),
138 _lifetime: PhantomData<&'a ()>,
139}
140
141impl<'a> Website<'a> {
142 pub fn new() -> WebsiteBuilder<'a, website_state::Empty> {
144 WebsiteBuilder::new()
145 }
146}
147
148impl<'a> WebsiteBuilder<'a, website_state::Empty> {
149 pub fn new() -> Self {
151 WebsiteBuilder {
152 _state: PhantomData,
153 _fields: (None, None, None, None),
154 _lifetime: PhantomData,
155 }
156 }
157}
158
159impl<'a, S: website_state::State> WebsiteBuilder<'a, S> {
160 pub fn description(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
162 self._fields.0 = value.into();
163 self
164 }
165 pub fn maybe_description(mut self, value: Option<CowStr<'a>>) -> Self {
167 self._fields.0 = value;
168 self
169 }
170}
171
172impl<'a, S: website_state::State> WebsiteBuilder<'a, S> {
173 pub fn preview_image(mut self, value: impl Into<Option<BlobRef<'a>>>) -> Self {
175 self._fields.1 = value.into();
176 self
177 }
178 pub fn maybe_preview_image(mut self, value: Option<BlobRef<'a>>) -> Self {
180 self._fields.1 = value;
181 self
182 }
183}
184
185impl<'a, S> WebsiteBuilder<'a, S>
186where
187 S: website_state::State,
188 S::Src: website_state::IsUnset,
189{
190 pub fn src(
192 mut self,
193 value: impl Into<UriValue<'a>>,
194 ) -> WebsiteBuilder<'a, website_state::SetSrc<S>> {
195 self._fields.2 = Option::Some(value.into());
196 WebsiteBuilder {
197 _state: PhantomData,
198 _fields: self._fields,
199 _lifetime: PhantomData,
200 }
201 }
202}
203
204impl<'a, S: website_state::State> WebsiteBuilder<'a, S> {
205 pub fn title(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
207 self._fields.3 = value.into();
208 self
209 }
210 pub fn maybe_title(mut self, value: Option<CowStr<'a>>) -> Self {
212 self._fields.3 = value;
213 self
214 }
215}
216
217impl<'a, S> WebsiteBuilder<'a, S>
218where
219 S: website_state::State,
220 S::Src: website_state::IsSet,
221{
222 pub fn build(self) -> Website<'a> {
224 Website {
225 description: self._fields.0,
226 preview_image: self._fields.1,
227 src: self._fields.2.unwrap(),
228 title: self._fields.3,
229 extra_data: Default::default(),
230 }
231 }
232 pub fn build_with_data(
234 self,
235 extra_data: BTreeMap<
236 jacquard_common::deps::smol_str::SmolStr,
237 jacquard_common::types::value::Data<'a>,
238 >,
239 ) -> Website<'a> {
240 Website {
241 description: self._fields.0,
242 preview_image: self._fields.1,
243 src: self._fields.2.unwrap(),
244 title: self._fields.3,
245 extra_data: Some(extra_data),
246 }
247 }
248}
249
250fn lexicon_doc_pub_leaflet_blocks_website() -> LexiconDoc<'static> {
251 #[allow(unused_imports)]
252 use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType};
253 use jacquard_lexicon::lexicon::*;
254 use alloc::collections::BTreeMap;
255 LexiconDoc {
256 lexicon: Lexicon::Lexicon1,
257 id: CowStr::new_static("pub.leaflet.blocks.website"),
258 defs: {
259 let mut map = BTreeMap::new();
260 map.insert(
261 SmolStr::new_static("main"),
262 LexUserType::Object(LexObject {
263 required: Some(vec![SmolStr::new_static("src")]),
264 properties: {
265 #[allow(unused_mut)]
266 let mut map = BTreeMap::new();
267 map.insert(
268 SmolStr::new_static("description"),
269 LexObjectProperty::String(LexString { ..Default::default() }),
270 );
271 map.insert(
272 SmolStr::new_static("previewImage"),
273 LexObjectProperty::Blob(LexBlob { ..Default::default() }),
274 );
275 map.insert(
276 SmolStr::new_static("src"),
277 LexObjectProperty::String(LexString {
278 format: Some(LexStringFormat::Uri),
279 ..Default::default()
280 }),
281 );
282 map.insert(
283 SmolStr::new_static("title"),
284 LexObjectProperty::String(LexString { ..Default::default() }),
285 );
286 map
287 },
288 ..Default::default()
289 }),
290 );
291 map
292 },
293 ..Default::default()
294 }
295}