jacquard_api/network_slices/
tools.rs1pub mod bug;
10pub mod document;
11pub mod richtext;
12
13
14#[allow(unused_imports)]
15use alloc::collections::BTreeMap;
16
17#[allow(unused_imports)]
18use core::marker::PhantomData;
19use jacquard_common::{CowStr, BosStr, DefaultStr, FromStaticStr};
20
21#[allow(unused_imports)]
22use jacquard_common::deps::codegen::unicode_segmentation::UnicodeSegmentation;
23use jacquard_common::deps::smol_str::SmolStr;
24use jacquard_common::types::blob::BlobRef;
25use jacquard_common::types::value::Data;
26use jacquard_derive::IntoStatic;
27use jacquard_lexicon::lexicon::LexiconDoc;
28use jacquard_lexicon::schema::LexiconSchema;
29
30#[allow(unused_imports)]
31use jacquard_lexicon::validation::{ConstraintError, ValidationPath};
32use serde::{Serialize, Deserialize};
33use crate::network_slices::tools;
34
35#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
36#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
37pub struct Image<S: BosStr = DefaultStr> {
38 pub alt: S,
40 pub image: BlobRef<S>,
41 #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
42 pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
43}
44
45
46#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
47#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
48pub struct Images<S: BosStr = DefaultStr> {
49 pub images: Vec<tools::Image<S>>,
50 #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
51 pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
52}
53
54impl<S: BosStr> LexiconSchema for Image<S> {
55 fn nsid() -> &'static str {
56 "network.slices.tools.defs"
57 }
58 fn def_name() -> &'static str {
59 "image"
60 }
61 fn lexicon_doc() -> LexiconDoc<'static> {
62 lexicon_doc_network_slices_tools_defs()
63 }
64 fn validate(&self) -> Result<(), ConstraintError> {
65 {
66 let value = &self.image;
67 {
68 let size = value.blob().size;
69 if size > 1000000usize {
70 return Err(ConstraintError::BlobTooLarge {
71 path: ValidationPath::from_field("image"),
72 max: 1000000usize,
73 actual: size,
74 });
75 }
76 }
77 }
78 {
79 let value = &self.image;
80 {
81 let mime = value.blob().mime_type.as_str();
82 let accepted: &[&str] = &["image/*"];
83 let matched = accepted
84 .iter()
85 .any(|pattern| {
86 if *pattern == "*/*" {
87 true
88 } else if pattern.ends_with("/*") {
89 let prefix = &pattern[..pattern.len() - 2];
90 mime.starts_with(prefix)
91 && mime.as_bytes().get(prefix.len()) == Some(&b'/')
92 } else {
93 mime == *pattern
94 }
95 });
96 if !matched {
97 return Err(ConstraintError::BlobMimeTypeNotAccepted {
98 path: ValidationPath::from_field("image"),
99 accepted: vec!["image/*".to_string()],
100 actual: mime.to_string(),
101 });
102 }
103 }
104 }
105 Ok(())
106 }
107}
108
109impl<S: BosStr> LexiconSchema for Images<S> {
110 fn nsid() -> &'static str {
111 "network.slices.tools.defs"
112 }
113 fn def_name() -> &'static str {
114 "images"
115 }
116 fn lexicon_doc() -> LexiconDoc<'static> {
117 lexicon_doc_network_slices_tools_defs()
118 }
119 fn validate(&self) -> Result<(), ConstraintError> {
120 {
121 let value = &self.images;
122 #[allow(unused_comparisons)]
123 if value.len() > 4usize {
124 return Err(ConstraintError::MaxLength {
125 path: ValidationPath::from_field("images"),
126 max: 4usize,
127 actual: value.len(),
128 });
129 }
130 }
131 Ok(())
132 }
133}
134
135pub mod image_state {
136
137 pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
138 #[allow(unused)]
139 use ::core::marker::PhantomData;
140 mod sealed {
141 pub trait Sealed {}
142 }
143 pub trait State: sealed::Sealed {
145 type Alt;
146 type Image;
147 }
148 pub struct Empty(());
150 impl sealed::Sealed for Empty {}
151 impl State for Empty {
152 type Alt = Unset;
153 type Image = Unset;
154 }
155 pub struct SetAlt<St: State = Empty>(PhantomData<fn() -> St>);
157 impl<St: State> sealed::Sealed for SetAlt<St> {}
158 impl<St: State> State for SetAlt<St> {
159 type Alt = Set<members::alt>;
160 type Image = St::Image;
161 }
162 pub struct SetImage<St: State = Empty>(PhantomData<fn() -> St>);
164 impl<St: State> sealed::Sealed for SetImage<St> {}
165 impl<St: State> State for SetImage<St> {
166 type Alt = St::Alt;
167 type Image = Set<members::image>;
168 }
169 #[allow(non_camel_case_types)]
171 pub mod members {
172 pub struct alt(());
174 pub struct image(());
176 }
177}
178
179pub struct ImageBuilder<St: image_state::State, S: BosStr = DefaultStr> {
181 _state: PhantomData<fn() -> St>,
182 _fields: (Option<S>, Option<BlobRef<S>>),
183 _type: PhantomData<fn() -> S>,
184}
185
186impl Image<DefaultStr> {
187 pub fn new() -> ImageBuilder<image_state::Empty, DefaultStr> {
189 ImageBuilder::new()
190 }
191}
192
193impl<S: BosStr> Image<S> {
194 pub fn builder() -> ImageBuilder<image_state::Empty, S> {
196 ImageBuilder::builder()
197 }
198}
199
200impl ImageBuilder<image_state::Empty, DefaultStr> {
201 pub fn new() -> Self {
203 ImageBuilder {
204 _state: PhantomData,
205 _fields: (None, None),
206 _type: PhantomData,
207 }
208 }
209}
210
211impl<S: BosStr> ImageBuilder<image_state::Empty, S> {
212 pub fn builder() -> Self {
214 ImageBuilder {
215 _state: PhantomData,
216 _fields: (None, None),
217 _type: PhantomData,
218 }
219 }
220}
221
222impl<St, S: BosStr> ImageBuilder<St, S>
223where
224 St: image_state::State,
225 St::Alt: image_state::IsUnset,
226{
227 pub fn alt(
229 mut self,
230 value: impl Into<S>,
231 ) -> ImageBuilder<image_state::SetAlt<St>, S> {
232 self._fields.0 = Option::Some(value.into());
233 ImageBuilder {
234 _state: PhantomData,
235 _fields: self._fields,
236 _type: PhantomData,
237 }
238 }
239}
240
241impl<St, S: BosStr> ImageBuilder<St, S>
242where
243 St: image_state::State,
244 St::Image: image_state::IsUnset,
245{
246 pub fn image(
248 mut self,
249 value: impl Into<BlobRef<S>>,
250 ) -> ImageBuilder<image_state::SetImage<St>, S> {
251 self._fields.1 = Option::Some(value.into());
252 ImageBuilder {
253 _state: PhantomData,
254 _fields: self._fields,
255 _type: PhantomData,
256 }
257 }
258}
259
260impl<St, S: BosStr> ImageBuilder<St, S>
261where
262 St: image_state::State,
263 St::Alt: image_state::IsSet,
264 St::Image: image_state::IsSet,
265{
266 pub fn build(self) -> Image<S> {
268 Image {
269 alt: self._fields.0.unwrap(),
270 image: self._fields.1.unwrap(),
271 extra_data: Default::default(),
272 }
273 }
274 pub fn build_with_data(self, extra_data: BTreeMap<SmolStr, Data<S>>) -> Image<S> {
276 Image {
277 alt: self._fields.0.unwrap(),
278 image: self._fields.1.unwrap(),
279 extra_data: Some(extra_data),
280 }
281 }
282}
283
284fn lexicon_doc_network_slices_tools_defs() -> LexiconDoc<'static> {
285 #[allow(unused_imports)]
286 use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType};
287 use jacquard_lexicon::lexicon::*;
288 use alloc::collections::BTreeMap;
289 LexiconDoc {
290 lexicon: Lexicon::Lexicon1,
291 id: CowStr::new_static("network.slices.tools.defs"),
292 defs: {
293 let mut map = BTreeMap::new();
294 map.insert(
295 SmolStr::new_static("image"),
296 LexUserType::Object(LexObject {
297 required: Some(
298 vec![SmolStr::new_static("image"), SmolStr::new_static("alt")],
299 ),
300 properties: {
301 #[allow(unused_mut)]
302 let mut map = BTreeMap::new();
303 map.insert(
304 SmolStr::new_static("alt"),
305 LexObjectProperty::String(LexString {
306 description: Some(
307 CowStr::new_static(
308 "Alt text description of the image, for accessibility",
309 ),
310 ),
311 ..Default::default()
312 }),
313 );
314 map.insert(
315 SmolStr::new_static("image"),
316 LexObjectProperty::Blob(LexBlob { ..Default::default() }),
317 );
318 map
319 },
320 ..Default::default()
321 }),
322 );
323 map.insert(
324 SmolStr::new_static("images"),
325 LexUserType::Object(LexObject {
326 required: Some(vec![SmolStr::new_static("images")]),
327 properties: {
328 #[allow(unused_mut)]
329 let mut map = BTreeMap::new();
330 map.insert(
331 SmolStr::new_static("images"),
332 LexObjectProperty::Array(LexArray {
333 items: LexArrayItem::Ref(LexRef {
334 r#ref: CowStr::new_static("#image"),
335 ..Default::default()
336 }),
337 max_length: Some(4usize),
338 ..Default::default()
339 }),
340 );
341 map
342 },
343 ..Default::default()
344 }),
345 );
346 map
347 },
348 ..Default::default()
349 }
350}
351
352pub mod images_state {
353
354 pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
355 #[allow(unused)]
356 use ::core::marker::PhantomData;
357 mod sealed {
358 pub trait Sealed {}
359 }
360 pub trait State: sealed::Sealed {
362 type Images;
363 }
364 pub struct Empty(());
366 impl sealed::Sealed for Empty {}
367 impl State for Empty {
368 type Images = Unset;
369 }
370 pub struct SetImages<St: State = Empty>(PhantomData<fn() -> St>);
372 impl<St: State> sealed::Sealed for SetImages<St> {}
373 impl<St: State> State for SetImages<St> {
374 type Images = Set<members::images>;
375 }
376 #[allow(non_camel_case_types)]
378 pub mod members {
379 pub struct images(());
381 }
382}
383
384pub struct ImagesBuilder<St: images_state::State, S: BosStr = DefaultStr> {
386 _state: PhantomData<fn() -> St>,
387 _fields: (Option<Vec<tools::Image<S>>>,),
388 _type: PhantomData<fn() -> S>,
389}
390
391impl Images<DefaultStr> {
392 pub fn new() -> ImagesBuilder<images_state::Empty, DefaultStr> {
394 ImagesBuilder::new()
395 }
396}
397
398impl<S: BosStr> Images<S> {
399 pub fn builder() -> ImagesBuilder<images_state::Empty, S> {
401 ImagesBuilder::builder()
402 }
403}
404
405impl ImagesBuilder<images_state::Empty, DefaultStr> {
406 pub fn new() -> Self {
408 ImagesBuilder {
409 _state: PhantomData,
410 _fields: (None,),
411 _type: PhantomData,
412 }
413 }
414}
415
416impl<S: BosStr> ImagesBuilder<images_state::Empty, S> {
417 pub fn builder() -> Self {
419 ImagesBuilder {
420 _state: PhantomData,
421 _fields: (None,),
422 _type: PhantomData,
423 }
424 }
425}
426
427impl<St, S: BosStr> ImagesBuilder<St, S>
428where
429 St: images_state::State,
430 St::Images: images_state::IsUnset,
431{
432 pub fn images(
434 mut self,
435 value: impl Into<Vec<tools::Image<S>>>,
436 ) -> ImagesBuilder<images_state::SetImages<St>, S> {
437 self._fields.0 = Option::Some(value.into());
438 ImagesBuilder {
439 _state: PhantomData,
440 _fields: self._fields,
441 _type: PhantomData,
442 }
443 }
444}
445
446impl<St, S: BosStr> ImagesBuilder<St, S>
447where
448 St: images_state::State,
449 St::Images: images_state::IsSet,
450{
451 pub fn build(self) -> Images<S> {
453 Images {
454 images: self._fields.0.unwrap(),
455 extra_data: Default::default(),
456 }
457 }
458 pub fn build_with_data(self, extra_data: BTreeMap<SmolStr, Data<S>>) -> Images<S> {
460 Images {
461 images: self._fields.0.unwrap(),
462 extra_data: Some(extra_data),
463 }
464 }
465}