1pub mod entry;
9pub mod get_author_posts;
10pub mod get_entry_metadata_by_name;
11pub mod get_mentions_by_entry;
12pub mod notify_of_new_entry;
13
14
15#[allow(unused_imports)]
16use alloc::collections::BTreeMap;
17
18#[allow(unused_imports)]
19use core::marker::PhantomData;
20use jacquard_common::CowStr;
21
22#[allow(unused_imports)]
23use jacquard_common::deps::codegen::unicode_segmentation::UnicodeSegmentation;
24use jacquard_common::types::blob::BlobRef;
25use jacquard_common::types::string::{AtUri, Datetime, UriValue};
26use jacquard_derive::{IntoStatic, lexicon};
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};
33
34#[lexicon]
35#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
36#[serde(rename_all = "camelCase")]
37pub struct BlobMetadata<'a> {
38 #[serde(borrow)]
39 pub blobref: BlobRef<'a>,
40 #[serde(skip_serializing_if = "Option::is_none")]
41 #[serde(borrow)]
42 pub name: Option<CowStr<'a>>,
43}
44
45
46#[lexicon]
47#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
48#[serde(rename_all = "camelCase")]
49pub struct BlogEntry<'a> {
50 #[serde(borrow)]
51 pub content: CowStr<'a>,
52 #[serde(skip_serializing_if = "Option::is_none")]
53 pub created_at: Option<Datetime>,
54}
55
56
57#[lexicon]
58#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
59#[serde(rename_all = "camelCase")]
60pub struct Comment<'a> {
61 #[serde(borrow)]
62 pub content: CowStr<'a>,
63 #[serde(borrow)]
64 pub entry_uri: AtUri<'a>,
65}
66
67
68#[lexicon]
69#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
70#[serde(rename_all = "camelCase")]
71pub struct Ogp<'a> {
72 #[serde(skip_serializing_if = "Option::is_none")]
73 pub height: Option<i64>,
74 #[serde(borrow)]
75 pub url: UriValue<'a>,
76 #[serde(skip_serializing_if = "Option::is_none")]
77 pub width: Option<i64>,
78}
79
80impl<'a> LexiconSchema for BlobMetadata<'a> {
81 fn nsid() -> &'static str {
82 "com.whtwnd.blog.defs"
83 }
84 fn def_name() -> &'static str {
85 "blobMetadata"
86 }
87 fn lexicon_doc() -> LexiconDoc<'static> {
88 lexicon_doc_com_whtwnd_blog_defs()
89 }
90 fn validate(&self) -> Result<(), ConstraintError> {
91 {
92 let value = &self.blobref;
93 {
94 let mime = value.blob().mime_type.as_str();
95 let accepted: &[&str] = &["*/*"];
96 let matched = accepted
97 .iter()
98 .any(|pattern| {
99 if *pattern == "*/*" {
100 true
101 } else if pattern.ends_with("/*") {
102 let prefix = &pattern[..pattern.len() - 2];
103 mime.starts_with(prefix)
104 && mime.as_bytes().get(prefix.len()) == Some(&b'/')
105 } else {
106 mime == *pattern
107 }
108 });
109 if !matched {
110 return Err(ConstraintError::BlobMimeTypeNotAccepted {
111 path: ValidationPath::from_field("blobref"),
112 accepted: vec!["*/*".to_string()],
113 actual: mime.to_string(),
114 });
115 }
116 }
117 }
118 Ok(())
119 }
120}
121
122impl<'a> LexiconSchema for BlogEntry<'a> {
123 fn nsid() -> &'static str {
124 "com.whtwnd.blog.defs"
125 }
126 fn def_name() -> &'static str {
127 "blogEntry"
128 }
129 fn lexicon_doc() -> LexiconDoc<'static> {
130 lexicon_doc_com_whtwnd_blog_defs()
131 }
132 fn validate(&self) -> Result<(), ConstraintError> {
133 {
134 let value = &self.content;
135 #[allow(unused_comparisons)]
136 if <str>::len(value.as_ref()) > 100000usize {
137 return Err(ConstraintError::MaxLength {
138 path: ValidationPath::from_field("content"),
139 max: 100000usize,
140 actual: <str>::len(value.as_ref()),
141 });
142 }
143 }
144 Ok(())
145 }
146}
147
148impl<'a> LexiconSchema for Comment<'a> {
149 fn nsid() -> &'static str {
150 "com.whtwnd.blog.defs"
151 }
152 fn def_name() -> &'static str {
153 "comment"
154 }
155 fn lexicon_doc() -> LexiconDoc<'static> {
156 lexicon_doc_com_whtwnd_blog_defs()
157 }
158 fn validate(&self) -> Result<(), ConstraintError> {
159 {
160 let value = &self.content;
161 #[allow(unused_comparisons)]
162 if <str>::len(value.as_ref()) > 1000usize {
163 return Err(ConstraintError::MaxLength {
164 path: ValidationPath::from_field("content"),
165 max: 1000usize,
166 actual: <str>::len(value.as_ref()),
167 });
168 }
169 }
170 Ok(())
171 }
172}
173
174impl<'a> LexiconSchema for Ogp<'a> {
175 fn nsid() -> &'static str {
176 "com.whtwnd.blog.defs"
177 }
178 fn def_name() -> &'static str {
179 "ogp"
180 }
181 fn lexicon_doc() -> LexiconDoc<'static> {
182 lexicon_doc_com_whtwnd_blog_defs()
183 }
184 fn validate(&self) -> Result<(), ConstraintError> {
185 Ok(())
186 }
187}
188
189pub mod blob_metadata_state {
190
191 pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
192 #[allow(unused)]
193 use ::core::marker::PhantomData;
194 mod sealed {
195 pub trait Sealed {}
196 }
197 pub trait State: sealed::Sealed {
199 type Blobref;
200 }
201 pub struct Empty(());
203 impl sealed::Sealed for Empty {}
204 impl State for Empty {
205 type Blobref = Unset;
206 }
207 pub struct SetBlobref<S: State = Empty>(PhantomData<fn() -> S>);
209 impl<S: State> sealed::Sealed for SetBlobref<S> {}
210 impl<S: State> State for SetBlobref<S> {
211 type Blobref = Set<members::blobref>;
212 }
213 #[allow(non_camel_case_types)]
215 pub mod members {
216 pub struct blobref(());
218 }
219}
220
221pub struct BlobMetadataBuilder<'a, S: blob_metadata_state::State> {
223 _state: PhantomData<fn() -> S>,
224 _fields: (Option<BlobRef<'a>>, Option<CowStr<'a>>),
225 _lifetime: PhantomData<&'a ()>,
226}
227
228impl<'a> BlobMetadata<'a> {
229 pub fn new() -> BlobMetadataBuilder<'a, blob_metadata_state::Empty> {
231 BlobMetadataBuilder::new()
232 }
233}
234
235impl<'a> BlobMetadataBuilder<'a, blob_metadata_state::Empty> {
236 pub fn new() -> Self {
238 BlobMetadataBuilder {
239 _state: PhantomData,
240 _fields: (None, None),
241 _lifetime: PhantomData,
242 }
243 }
244}
245
246impl<'a, S> BlobMetadataBuilder<'a, S>
247where
248 S: blob_metadata_state::State,
249 S::Blobref: blob_metadata_state::IsUnset,
250{
251 pub fn blobref(
253 mut self,
254 value: impl Into<BlobRef<'a>>,
255 ) -> BlobMetadataBuilder<'a, blob_metadata_state::SetBlobref<S>> {
256 self._fields.0 = Option::Some(value.into());
257 BlobMetadataBuilder {
258 _state: PhantomData,
259 _fields: self._fields,
260 _lifetime: PhantomData,
261 }
262 }
263}
264
265impl<'a, S: blob_metadata_state::State> BlobMetadataBuilder<'a, S> {
266 pub fn name(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
268 self._fields.1 = value.into();
269 self
270 }
271 pub fn maybe_name(mut self, value: Option<CowStr<'a>>) -> Self {
273 self._fields.1 = value;
274 self
275 }
276}
277
278impl<'a, S> BlobMetadataBuilder<'a, S>
279where
280 S: blob_metadata_state::State,
281 S::Blobref: blob_metadata_state::IsSet,
282{
283 pub fn build(self) -> BlobMetadata<'a> {
285 BlobMetadata {
286 blobref: self._fields.0.unwrap(),
287 name: self._fields.1,
288 extra_data: Default::default(),
289 }
290 }
291 pub fn build_with_data(
293 self,
294 extra_data: BTreeMap<
295 jacquard_common::deps::smol_str::SmolStr,
296 jacquard_common::types::value::Data<'a>,
297 >,
298 ) -> BlobMetadata<'a> {
299 BlobMetadata {
300 blobref: self._fields.0.unwrap(),
301 name: self._fields.1,
302 extra_data: Some(extra_data),
303 }
304 }
305}
306
307fn lexicon_doc_com_whtwnd_blog_defs() -> LexiconDoc<'static> {
308 #[allow(unused_imports)]
309 use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType};
310 use jacquard_lexicon::lexicon::*;
311 use alloc::collections::BTreeMap;
312 LexiconDoc {
313 lexicon: Lexicon::Lexicon1,
314 id: CowStr::new_static("com.whtwnd.blog.defs"),
315 defs: {
316 let mut map = BTreeMap::new();
317 map.insert(
318 SmolStr::new_static("blobMetadata"),
319 LexUserType::Object(LexObject {
320 required: Some(vec![SmolStr::new_static("blobref")]),
321 properties: {
322 #[allow(unused_mut)]
323 let mut map = BTreeMap::new();
324 map.insert(
325 SmolStr::new_static("blobref"),
326 LexObjectProperty::Blob(LexBlob { ..Default::default() }),
327 );
328 map.insert(
329 SmolStr::new_static("name"),
330 LexObjectProperty::String(LexString { ..Default::default() }),
331 );
332 map
333 },
334 ..Default::default()
335 }),
336 );
337 map.insert(
338 SmolStr::new_static("blogEntry"),
339 LexUserType::Object(LexObject {
340 required: Some(vec![SmolStr::new_static("content")]),
341 properties: {
342 #[allow(unused_mut)]
343 let mut map = BTreeMap::new();
344 map.insert(
345 SmolStr::new_static("content"),
346 LexObjectProperty::String(LexString {
347 max_length: Some(100000usize),
348 ..Default::default()
349 }),
350 );
351 map.insert(
352 SmolStr::new_static("createdAt"),
353 LexObjectProperty::String(LexString {
354 format: Some(LexStringFormat::Datetime),
355 ..Default::default()
356 }),
357 );
358 map
359 },
360 ..Default::default()
361 }),
362 );
363 map.insert(
364 SmolStr::new_static("comment"),
365 LexUserType::Object(LexObject {
366 required: Some(
367 vec![
368 SmolStr::new_static("content"),
369 SmolStr::new_static("entryUri")
370 ],
371 ),
372 properties: {
373 #[allow(unused_mut)]
374 let mut map = BTreeMap::new();
375 map.insert(
376 SmolStr::new_static("content"),
377 LexObjectProperty::String(LexString {
378 max_length: Some(1000usize),
379 ..Default::default()
380 }),
381 );
382 map.insert(
383 SmolStr::new_static("entryUri"),
384 LexObjectProperty::String(LexString {
385 format: Some(LexStringFormat::AtUri),
386 ..Default::default()
387 }),
388 );
389 map
390 },
391 ..Default::default()
392 }),
393 );
394 map.insert(
395 SmolStr::new_static("ogp"),
396 LexUserType::Object(LexObject {
397 required: Some(vec![SmolStr::new_static("url")]),
398 properties: {
399 #[allow(unused_mut)]
400 let mut map = BTreeMap::new();
401 map.insert(
402 SmolStr::new_static("height"),
403 LexObjectProperty::Integer(LexInteger {
404 ..Default::default()
405 }),
406 );
407 map.insert(
408 SmolStr::new_static("url"),
409 LexObjectProperty::String(LexString {
410 format: Some(LexStringFormat::Uri),
411 ..Default::default()
412 }),
413 );
414 map.insert(
415 SmolStr::new_static("width"),
416 LexObjectProperty::Integer(LexInteger {
417 ..Default::default()
418 }),
419 );
420 map
421 },
422 ..Default::default()
423 }),
424 );
425 map
426 },
427 ..Default::default()
428 }
429}
430
431pub mod comment_state {
432
433 pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
434 #[allow(unused)]
435 use ::core::marker::PhantomData;
436 mod sealed {
437 pub trait Sealed {}
438 }
439 pub trait State: sealed::Sealed {
441 type EntryUri;
442 type Content;
443 }
444 pub struct Empty(());
446 impl sealed::Sealed for Empty {}
447 impl State for Empty {
448 type EntryUri = Unset;
449 type Content = Unset;
450 }
451 pub struct SetEntryUri<S: State = Empty>(PhantomData<fn() -> S>);
453 impl<S: State> sealed::Sealed for SetEntryUri<S> {}
454 impl<S: State> State for SetEntryUri<S> {
455 type EntryUri = Set<members::entry_uri>;
456 type Content = S::Content;
457 }
458 pub struct SetContent<S: State = Empty>(PhantomData<fn() -> S>);
460 impl<S: State> sealed::Sealed for SetContent<S> {}
461 impl<S: State> State for SetContent<S> {
462 type EntryUri = S::EntryUri;
463 type Content = Set<members::content>;
464 }
465 #[allow(non_camel_case_types)]
467 pub mod members {
468 pub struct entry_uri(());
470 pub struct content(());
472 }
473}
474
475pub struct CommentBuilder<'a, S: comment_state::State> {
477 _state: PhantomData<fn() -> S>,
478 _fields: (Option<CowStr<'a>>, Option<AtUri<'a>>),
479 _lifetime: PhantomData<&'a ()>,
480}
481
482impl<'a> Comment<'a> {
483 pub fn new() -> CommentBuilder<'a, comment_state::Empty> {
485 CommentBuilder::new()
486 }
487}
488
489impl<'a> CommentBuilder<'a, comment_state::Empty> {
490 pub fn new() -> Self {
492 CommentBuilder {
493 _state: PhantomData,
494 _fields: (None, None),
495 _lifetime: PhantomData,
496 }
497 }
498}
499
500impl<'a, S> CommentBuilder<'a, S>
501where
502 S: comment_state::State,
503 S::Content: comment_state::IsUnset,
504{
505 pub fn content(
507 mut self,
508 value: impl Into<CowStr<'a>>,
509 ) -> CommentBuilder<'a, comment_state::SetContent<S>> {
510 self._fields.0 = Option::Some(value.into());
511 CommentBuilder {
512 _state: PhantomData,
513 _fields: self._fields,
514 _lifetime: PhantomData,
515 }
516 }
517}
518
519impl<'a, S> CommentBuilder<'a, S>
520where
521 S: comment_state::State,
522 S::EntryUri: comment_state::IsUnset,
523{
524 pub fn entry_uri(
526 mut self,
527 value: impl Into<AtUri<'a>>,
528 ) -> CommentBuilder<'a, comment_state::SetEntryUri<S>> {
529 self._fields.1 = Option::Some(value.into());
530 CommentBuilder {
531 _state: PhantomData,
532 _fields: self._fields,
533 _lifetime: PhantomData,
534 }
535 }
536}
537
538impl<'a, S> CommentBuilder<'a, S>
539where
540 S: comment_state::State,
541 S::EntryUri: comment_state::IsSet,
542 S::Content: comment_state::IsSet,
543{
544 pub fn build(self) -> Comment<'a> {
546 Comment {
547 content: self._fields.0.unwrap(),
548 entry_uri: self._fields.1.unwrap(),
549 extra_data: Default::default(),
550 }
551 }
552 pub fn build_with_data(
554 self,
555 extra_data: BTreeMap<
556 jacquard_common::deps::smol_str::SmolStr,
557 jacquard_common::types::value::Data<'a>,
558 >,
559 ) -> Comment<'a> {
560 Comment {
561 content: self._fields.0.unwrap(),
562 entry_uri: self._fields.1.unwrap(),
563 extra_data: Some(extra_data),
564 }
565 }
566}
567
568pub mod ogp_state {
569
570 pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
571 #[allow(unused)]
572 use ::core::marker::PhantomData;
573 mod sealed {
574 pub trait Sealed {}
575 }
576 pub trait State: sealed::Sealed {
578 type Url;
579 }
580 pub struct Empty(());
582 impl sealed::Sealed for Empty {}
583 impl State for Empty {
584 type Url = Unset;
585 }
586 pub struct SetUrl<S: State = Empty>(PhantomData<fn() -> S>);
588 impl<S: State> sealed::Sealed for SetUrl<S> {}
589 impl<S: State> State for SetUrl<S> {
590 type Url = Set<members::url>;
591 }
592 #[allow(non_camel_case_types)]
594 pub mod members {
595 pub struct url(());
597 }
598}
599
600pub struct OgpBuilder<'a, S: ogp_state::State> {
602 _state: PhantomData<fn() -> S>,
603 _fields: (Option<i64>, Option<UriValue<'a>>, Option<i64>),
604 _lifetime: PhantomData<&'a ()>,
605}
606
607impl<'a> Ogp<'a> {
608 pub fn new() -> OgpBuilder<'a, ogp_state::Empty> {
610 OgpBuilder::new()
611 }
612}
613
614impl<'a> OgpBuilder<'a, ogp_state::Empty> {
615 pub fn new() -> Self {
617 OgpBuilder {
618 _state: PhantomData,
619 _fields: (None, None, None),
620 _lifetime: PhantomData,
621 }
622 }
623}
624
625impl<'a, S: ogp_state::State> OgpBuilder<'a, S> {
626 pub fn height(mut self, value: impl Into<Option<i64>>) -> Self {
628 self._fields.0 = value.into();
629 self
630 }
631 pub fn maybe_height(mut self, value: Option<i64>) -> Self {
633 self._fields.0 = value;
634 self
635 }
636}
637
638impl<'a, S> OgpBuilder<'a, S>
639where
640 S: ogp_state::State,
641 S::Url: ogp_state::IsUnset,
642{
643 pub fn url(
645 mut self,
646 value: impl Into<UriValue<'a>>,
647 ) -> OgpBuilder<'a, ogp_state::SetUrl<S>> {
648 self._fields.1 = Option::Some(value.into());
649 OgpBuilder {
650 _state: PhantomData,
651 _fields: self._fields,
652 _lifetime: PhantomData,
653 }
654 }
655}
656
657impl<'a, S: ogp_state::State> OgpBuilder<'a, S> {
658 pub fn width(mut self, value: impl Into<Option<i64>>) -> Self {
660 self._fields.2 = value.into();
661 self
662 }
663 pub fn maybe_width(mut self, value: Option<i64>) -> Self {
665 self._fields.2 = value;
666 self
667 }
668}
669
670impl<'a, S> OgpBuilder<'a, S>
671where
672 S: ogp_state::State,
673 S::Url: ogp_state::IsSet,
674{
675 pub fn build(self) -> Ogp<'a> {
677 Ogp {
678 height: self._fields.0,
679 url: self._fields.1.unwrap(),
680 width: self._fields.2,
681 extra_data: Default::default(),
682 }
683 }
684 pub fn build_with_data(
686 self,
687 extra_data: BTreeMap<
688 jacquard_common::deps::smol_str::SmolStr,
689 jacquard_common::types::value::Data<'a>,
690 >,
691 ) -> Ogp<'a> {
692 Ogp {
693 height: self._fields.0,
694 url: self._fields.1.unwrap(),
695 width: self._fields.2,
696 extra_data: Some(extra_data),
697 }
698 }
699}