1#[allow(unused_imports)]
9use alloc::collections::BTreeMap;
10
11#[allow(unused_imports)]
12use core::marker::PhantomData;
13use jacquard_common::{BosStr, CowStr, 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};
24use jacquard_lexicon::lexicon::LexiconDoc;
25use jacquard_lexicon::schema::LexiconSchema;
26
27use crate::net_anisota::chronicle::level;
28#[allow(unused_imports)]
29use jacquard_lexicon::validation::{ConstraintError, ValidationPath};
30use serde::{Deserialize, Serialize};
31#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
34#[serde(
35 rename_all = "camelCase",
36 bound(deserialize = "S: Deserialize<'de> + BosStr")
37)]
38pub struct ChronicleSignature<S: BosStr = DefaultStr> {
39 pub alg: S,
41 pub kid: S,
43 pub nonce: S,
45 pub sig: S,
47 pub signed_at: Datetime,
49 pub version: i64,
51 #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
52 pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
53}
54
55#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
58#[serde(
59 rename_all = "camelCase",
60 bound(deserialize = "S: Deserialize<'de> + BosStr")
61)]
62pub struct JourneyData<S: BosStr = DefaultStr> {
63 #[serde(skip_serializing_if = "Option::is_none")]
65 pub days_from_previous_level: Option<i64>,
66 #[serde(skip_serializing_if = "Option::is_none")]
68 pub xp_gained_from_previous_level: Option<i64>,
69 #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
70 pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
71}
72
73#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
76#[serde(
77 rename_all = "camelCase",
78 bound(deserialize = "S: Deserialize<'de> + BosStr")
79)]
80pub struct LevelSnapshot<S: BosStr = DefaultStr> {
81 #[serde(skip_serializing_if = "Option::is_none")]
83 pub days_played: Option<i64>,
84 #[serde(skip_serializing_if = "Option::is_none")]
86 pub items_total: Option<i64>,
87 #[serde(skip_serializing_if = "Option::is_none")]
89 pub posts_read_total: Option<i64>,
90 #[serde(skip_serializing_if = "Option::is_none")]
92 pub specimens_documented: Option<i64>,
93 pub total_xp: i64,
95 #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
96 pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
97}
98
99#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
102#[serde(
103 rename_all = "camelCase",
104 rename = "net.anisota.chronicle.level",
105 tag = "$type",
106 bound(deserialize = "S: Deserialize<'de> + BosStr")
107)]
108pub struct Level<S: BosStr = DefaultStr> {
109 pub created_at: Datetime,
111 #[serde(skip_serializing_if = "Option::is_none")]
112 pub journey: Option<level::JourneyData<S>>,
113 pub level: i64,
115 pub signature: level::ChronicleSignature<S>,
116 pub snapshot: level::LevelSnapshot<S>,
117 #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
118 pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
119}
120
121#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
124#[serde(rename_all = "camelCase")]
125pub struct LevelGetRecordOutput<S: BosStr = DefaultStr> {
126 #[serde(skip_serializing_if = "Option::is_none")]
127 pub cid: Option<Cid<S>>,
128 pub uri: AtUri<S>,
129 pub value: Level<S>,
130}
131
132impl<S: BosStr> Level<S> {
133 pub fn uri(uri: S) -> Result<RecordUri<S, LevelRecord>, UriError> {
134 RecordUri::try_from_uri(AtUri::new(uri)?)
135 }
136}
137
138impl<S: BosStr> LexiconSchema for ChronicleSignature<S> {
139 fn nsid() -> &'static str {
140 "net.anisota.chronicle.level"
141 }
142 fn def_name() -> &'static str {
143 "chronicleSignature"
144 }
145 fn lexicon_doc() -> LexiconDoc<'static> {
146 lexicon_doc_net_anisota_chronicle_level()
147 }
148 fn validate(&self) -> Result<(), ConstraintError> {
149 Ok(())
150 }
151}
152
153impl<S: BosStr> LexiconSchema for JourneyData<S> {
154 fn nsid() -> &'static str {
155 "net.anisota.chronicle.level"
156 }
157 fn def_name() -> &'static str {
158 "journeyData"
159 }
160 fn lexicon_doc() -> LexiconDoc<'static> {
161 lexicon_doc_net_anisota_chronicle_level()
162 }
163 fn validate(&self) -> Result<(), ConstraintError> {
164 if let Some(ref value) = self.days_from_previous_level {
165 if *value < 0i64 {
166 return Err(ConstraintError::Minimum {
167 path: ValidationPath::from_field("days_from_previous_level"),
168 min: 0i64,
169 actual: *value,
170 });
171 }
172 }
173 if let Some(ref value) = self.xp_gained_from_previous_level {
174 if *value < 0i64 {
175 return Err(ConstraintError::Minimum {
176 path: ValidationPath::from_field("xp_gained_from_previous_level"),
177 min: 0i64,
178 actual: *value,
179 });
180 }
181 }
182 Ok(())
183 }
184}
185
186impl<S: BosStr> LexiconSchema for LevelSnapshot<S> {
187 fn nsid() -> &'static str {
188 "net.anisota.chronicle.level"
189 }
190 fn def_name() -> &'static str {
191 "levelSnapshot"
192 }
193 fn lexicon_doc() -> LexiconDoc<'static> {
194 lexicon_doc_net_anisota_chronicle_level()
195 }
196 fn validate(&self) -> Result<(), ConstraintError> {
197 if let Some(ref value) = self.days_played {
198 if *value < 0i64 {
199 return Err(ConstraintError::Minimum {
200 path: ValidationPath::from_field("days_played"),
201 min: 0i64,
202 actual: *value,
203 });
204 }
205 }
206 if let Some(ref value) = self.items_total {
207 if *value < 0i64 {
208 return Err(ConstraintError::Minimum {
209 path: ValidationPath::from_field("items_total"),
210 min: 0i64,
211 actual: *value,
212 });
213 }
214 }
215 if let Some(ref value) = self.posts_read_total {
216 if *value < 0i64 {
217 return Err(ConstraintError::Minimum {
218 path: ValidationPath::from_field("posts_read_total"),
219 min: 0i64,
220 actual: *value,
221 });
222 }
223 }
224 if let Some(ref value) = self.specimens_documented {
225 if *value < 0i64 {
226 return Err(ConstraintError::Minimum {
227 path: ValidationPath::from_field("specimens_documented"),
228 min: 0i64,
229 actual: *value,
230 });
231 }
232 }
233 {
234 let value = &self.total_xp;
235 if *value < 0i64 {
236 return Err(ConstraintError::Minimum {
237 path: ValidationPath::from_field("total_xp"),
238 min: 0i64,
239 actual: *value,
240 });
241 }
242 }
243 Ok(())
244 }
245}
246
247#[derive(Debug, Serialize, Deserialize)]
250pub struct LevelRecord;
251impl XrpcResp for LevelRecord {
252 const NSID: &'static str = "net.anisota.chronicle.level";
253 const ENCODING: &'static str = "application/json";
254 type Output<S: BosStr> = LevelGetRecordOutput<S>;
255 type Err = RecordError;
256}
257
258impl<S: BosStr> From<LevelGetRecordOutput<S>> for Level<S> {
259 fn from(output: LevelGetRecordOutput<S>) -> Self {
260 output.value
261 }
262}
263
264impl<S: BosStr> Collection for Level<S> {
265 const NSID: &'static str = "net.anisota.chronicle.level";
266 type Record = LevelRecord;
267}
268
269impl Collection for LevelRecord {
270 const NSID: &'static str = "net.anisota.chronicle.level";
271 type Record = LevelRecord;
272}
273
274impl<S: BosStr> LexiconSchema for Level<S> {
275 fn nsid() -> &'static str {
276 "net.anisota.chronicle.level"
277 }
278 fn def_name() -> &'static str {
279 "main"
280 }
281 fn lexicon_doc() -> LexiconDoc<'static> {
282 lexicon_doc_net_anisota_chronicle_level()
283 }
284 fn validate(&self) -> Result<(), ConstraintError> {
285 {
286 let value = &self.level;
287 if *value > 99i64 {
288 return Err(ConstraintError::Maximum {
289 path: ValidationPath::from_field("level"),
290 max: 99i64,
291 actual: *value,
292 });
293 }
294 }
295 {
296 let value = &self.level;
297 if *value < 1i64 {
298 return Err(ConstraintError::Minimum {
299 path: ValidationPath::from_field("level"),
300 min: 1i64,
301 actual: *value,
302 });
303 }
304 }
305 Ok(())
306 }
307}
308
309pub mod chronicle_signature_state {
310
311 pub use crate::builder_types::{IsSet, IsUnset, Set, Unset};
312 #[allow(unused)]
313 use ::core::marker::PhantomData;
314 mod sealed {
315 pub trait Sealed {}
316 }
317 pub trait State: sealed::Sealed {
319 type Alg;
320 type Kid;
321 type Nonce;
322 type Sig;
323 type SignedAt;
324 type Version;
325 }
326 pub struct Empty(());
328 impl sealed::Sealed for Empty {}
329 impl State for Empty {
330 type Alg = Unset;
331 type Kid = Unset;
332 type Nonce = Unset;
333 type Sig = Unset;
334 type SignedAt = Unset;
335 type Version = Unset;
336 }
337 pub struct SetAlg<St: State = Empty>(PhantomData<fn() -> St>);
339 impl<St: State> sealed::Sealed for SetAlg<St> {}
340 impl<St: State> State for SetAlg<St> {
341 type Alg = Set<members::alg>;
342 type Kid = St::Kid;
343 type Nonce = St::Nonce;
344 type Sig = St::Sig;
345 type SignedAt = St::SignedAt;
346 type Version = St::Version;
347 }
348 pub struct SetKid<St: State = Empty>(PhantomData<fn() -> St>);
350 impl<St: State> sealed::Sealed for SetKid<St> {}
351 impl<St: State> State for SetKid<St> {
352 type Alg = St::Alg;
353 type Kid = Set<members::kid>;
354 type Nonce = St::Nonce;
355 type Sig = St::Sig;
356 type SignedAt = St::SignedAt;
357 type Version = St::Version;
358 }
359 pub struct SetNonce<St: State = Empty>(PhantomData<fn() -> St>);
361 impl<St: State> sealed::Sealed for SetNonce<St> {}
362 impl<St: State> State for SetNonce<St> {
363 type Alg = St::Alg;
364 type Kid = St::Kid;
365 type Nonce = Set<members::nonce>;
366 type Sig = St::Sig;
367 type SignedAt = St::SignedAt;
368 type Version = St::Version;
369 }
370 pub struct SetSig<St: State = Empty>(PhantomData<fn() -> St>);
372 impl<St: State> sealed::Sealed for SetSig<St> {}
373 impl<St: State> State for SetSig<St> {
374 type Alg = St::Alg;
375 type Kid = St::Kid;
376 type Nonce = St::Nonce;
377 type Sig = Set<members::sig>;
378 type SignedAt = St::SignedAt;
379 type Version = St::Version;
380 }
381 pub struct SetSignedAt<St: State = Empty>(PhantomData<fn() -> St>);
383 impl<St: State> sealed::Sealed for SetSignedAt<St> {}
384 impl<St: State> State for SetSignedAt<St> {
385 type Alg = St::Alg;
386 type Kid = St::Kid;
387 type Nonce = St::Nonce;
388 type Sig = St::Sig;
389 type SignedAt = Set<members::signed_at>;
390 type Version = St::Version;
391 }
392 pub struct SetVersion<St: State = Empty>(PhantomData<fn() -> St>);
394 impl<St: State> sealed::Sealed for SetVersion<St> {}
395 impl<St: State> State for SetVersion<St> {
396 type Alg = St::Alg;
397 type Kid = St::Kid;
398 type Nonce = St::Nonce;
399 type Sig = St::Sig;
400 type SignedAt = St::SignedAt;
401 type Version = Set<members::version>;
402 }
403 #[allow(non_camel_case_types)]
405 pub mod members {
406 pub struct alg(());
408 pub struct kid(());
410 pub struct nonce(());
412 pub struct sig(());
414 pub struct signed_at(());
416 pub struct version(());
418 }
419}
420
421pub struct ChronicleSignatureBuilder<St: chronicle_signature_state::State, S: BosStr = DefaultStr> {
423 _state: PhantomData<fn() -> St>,
424 _fields: (
425 Option<S>,
426 Option<S>,
427 Option<S>,
428 Option<S>,
429 Option<Datetime>,
430 Option<i64>,
431 ),
432 _type: PhantomData<fn() -> S>,
433}
434
435impl ChronicleSignature<DefaultStr> {
436 pub fn new() -> ChronicleSignatureBuilder<chronicle_signature_state::Empty, DefaultStr> {
438 ChronicleSignatureBuilder::new()
439 }
440}
441
442impl<S: BosStr> ChronicleSignature<S> {
443 pub fn builder() -> ChronicleSignatureBuilder<chronicle_signature_state::Empty, S> {
445 ChronicleSignatureBuilder::builder()
446 }
447}
448
449impl ChronicleSignatureBuilder<chronicle_signature_state::Empty, DefaultStr> {
450 pub fn new() -> Self {
452 ChronicleSignatureBuilder {
453 _state: PhantomData,
454 _fields: (None, None, None, None, None, None),
455 _type: PhantomData,
456 }
457 }
458}
459
460impl<S: BosStr> ChronicleSignatureBuilder<chronicle_signature_state::Empty, S> {
461 pub fn builder() -> Self {
463 ChronicleSignatureBuilder {
464 _state: PhantomData,
465 _fields: (None, None, None, None, None, None),
466 _type: PhantomData,
467 }
468 }
469}
470
471impl<St, S: BosStr> ChronicleSignatureBuilder<St, S>
472where
473 St: chronicle_signature_state::State,
474 St::Alg: chronicle_signature_state::IsUnset,
475{
476 pub fn alg(
478 mut self,
479 value: impl Into<S>,
480 ) -> ChronicleSignatureBuilder<chronicle_signature_state::SetAlg<St>, S> {
481 self._fields.0 = Option::Some(value.into());
482 ChronicleSignatureBuilder {
483 _state: PhantomData,
484 _fields: self._fields,
485 _type: PhantomData,
486 }
487 }
488}
489
490impl<St, S: BosStr> ChronicleSignatureBuilder<St, S>
491where
492 St: chronicle_signature_state::State,
493 St::Kid: chronicle_signature_state::IsUnset,
494{
495 pub fn kid(
497 mut self,
498 value: impl Into<S>,
499 ) -> ChronicleSignatureBuilder<chronicle_signature_state::SetKid<St>, S> {
500 self._fields.1 = Option::Some(value.into());
501 ChronicleSignatureBuilder {
502 _state: PhantomData,
503 _fields: self._fields,
504 _type: PhantomData,
505 }
506 }
507}
508
509impl<St, S: BosStr> ChronicleSignatureBuilder<St, S>
510where
511 St: chronicle_signature_state::State,
512 St::Nonce: chronicle_signature_state::IsUnset,
513{
514 pub fn nonce(
516 mut self,
517 value: impl Into<S>,
518 ) -> ChronicleSignatureBuilder<chronicle_signature_state::SetNonce<St>, S> {
519 self._fields.2 = Option::Some(value.into());
520 ChronicleSignatureBuilder {
521 _state: PhantomData,
522 _fields: self._fields,
523 _type: PhantomData,
524 }
525 }
526}
527
528impl<St, S: BosStr> ChronicleSignatureBuilder<St, S>
529where
530 St: chronicle_signature_state::State,
531 St::Sig: chronicle_signature_state::IsUnset,
532{
533 pub fn sig(
535 mut self,
536 value: impl Into<S>,
537 ) -> ChronicleSignatureBuilder<chronicle_signature_state::SetSig<St>, S> {
538 self._fields.3 = Option::Some(value.into());
539 ChronicleSignatureBuilder {
540 _state: PhantomData,
541 _fields: self._fields,
542 _type: PhantomData,
543 }
544 }
545}
546
547impl<St, S: BosStr> ChronicleSignatureBuilder<St, S>
548where
549 St: chronicle_signature_state::State,
550 St::SignedAt: chronicle_signature_state::IsUnset,
551{
552 pub fn signed_at(
554 mut self,
555 value: impl Into<Datetime>,
556 ) -> ChronicleSignatureBuilder<chronicle_signature_state::SetSignedAt<St>, S> {
557 self._fields.4 = Option::Some(value.into());
558 ChronicleSignatureBuilder {
559 _state: PhantomData,
560 _fields: self._fields,
561 _type: PhantomData,
562 }
563 }
564}
565
566impl<St, S: BosStr> ChronicleSignatureBuilder<St, S>
567where
568 St: chronicle_signature_state::State,
569 St::Version: chronicle_signature_state::IsUnset,
570{
571 pub fn version(
573 mut self,
574 value: impl Into<i64>,
575 ) -> ChronicleSignatureBuilder<chronicle_signature_state::SetVersion<St>, S> {
576 self._fields.5 = Option::Some(value.into());
577 ChronicleSignatureBuilder {
578 _state: PhantomData,
579 _fields: self._fields,
580 _type: PhantomData,
581 }
582 }
583}
584
585impl<St, S: BosStr> ChronicleSignatureBuilder<St, S>
586where
587 St: chronicle_signature_state::State,
588 St::Alg: chronicle_signature_state::IsSet,
589 St::Kid: chronicle_signature_state::IsSet,
590 St::Nonce: chronicle_signature_state::IsSet,
591 St::Sig: chronicle_signature_state::IsSet,
592 St::SignedAt: chronicle_signature_state::IsSet,
593 St::Version: chronicle_signature_state::IsSet,
594{
595 pub fn build(self) -> ChronicleSignature<S> {
597 ChronicleSignature {
598 alg: self._fields.0.unwrap(),
599 kid: self._fields.1.unwrap(),
600 nonce: self._fields.2.unwrap(),
601 sig: self._fields.3.unwrap(),
602 signed_at: self._fields.4.unwrap(),
603 version: self._fields.5.unwrap(),
604 extra_data: Default::default(),
605 }
606 }
607 pub fn build_with_data(self, extra_data: BTreeMap<SmolStr, Data<S>>) -> ChronicleSignature<S> {
609 ChronicleSignature {
610 alg: self._fields.0.unwrap(),
611 kid: self._fields.1.unwrap(),
612 nonce: self._fields.2.unwrap(),
613 sig: self._fields.3.unwrap(),
614 signed_at: self._fields.4.unwrap(),
615 version: self._fields.5.unwrap(),
616 extra_data: Some(extra_data),
617 }
618 }
619}
620
621fn lexicon_doc_net_anisota_chronicle_level() -> LexiconDoc<'static> {
622 use alloc::collections::BTreeMap;
623 #[allow(unused_imports)]
624 use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType};
625 use jacquard_lexicon::lexicon::*;
626 LexiconDoc {
627 lexicon: Lexicon::Lexicon1,
628 id: CowStr::new_static("net.anisota.chronicle.level"),
629 defs: {
630 let mut map = BTreeMap::new();
631 map.insert(
632 SmolStr::new_static("chronicleSignature"),
633 LexUserType::Object(LexObject {
634 description: Some(CowStr::new_static(
635 "ES256 cryptographic signature proving record authenticity",
636 )),
637 required: Some(vec![
638 SmolStr::new_static("sig"),
639 SmolStr::new_static("alg"),
640 SmolStr::new_static("kid"),
641 SmolStr::new_static("signedAt"),
642 SmolStr::new_static("nonce"),
643 SmolStr::new_static("version"),
644 ]),
645 properties: {
646 #[allow(unused_mut)]
647 let mut map = BTreeMap::new();
648 map.insert(
649 SmolStr::new_static("alg"),
650 LexObjectProperty::String(LexString {
651 description: Some(CowStr::new_static("Signing algorithm (ES256)")),
652 ..Default::default()
653 }),
654 );
655 map.insert(
656 SmolStr::new_static("kid"),
657 LexObjectProperty::String(LexString {
658 description: Some(CowStr::new_static(
659 "Key identifier for the signing key",
660 )),
661 ..Default::default()
662 }),
663 );
664 map.insert(
665 SmolStr::new_static("nonce"),
666 LexObjectProperty::String(LexString {
667 description: Some(CowStr::new_static(
668 "Unique random nonce to prevent replay",
669 )),
670 ..Default::default()
671 }),
672 );
673 map.insert(
674 SmolStr::new_static("sig"),
675 LexObjectProperty::String(LexString {
676 description: Some(CowStr::new_static(
677 "Base64-encoded ES256 signature",
678 )),
679 ..Default::default()
680 }),
681 );
682 map.insert(
683 SmolStr::new_static("signedAt"),
684 LexObjectProperty::String(LexString {
685 description: Some(CowStr::new_static("When the record was signed")),
686 format: Some(LexStringFormat::Datetime),
687 ..Default::default()
688 }),
689 );
690 map.insert(
691 SmolStr::new_static("version"),
692 LexObjectProperty::Integer(LexInteger {
693 ..Default::default()
694 }),
695 );
696 map
697 },
698 ..Default::default()
699 }),
700 );
701 map.insert(
702 SmolStr::new_static("journeyData"),
703 LexUserType::Object(LexObject {
704 description: Some(CowStr::new_static("Journey info from previous level")),
705 properties: {
706 #[allow(unused_mut)]
707 let mut map = BTreeMap::new();
708 map.insert(
709 SmolStr::new_static("daysFromPreviousLevel"),
710 LexObjectProperty::Integer(LexInteger {
711 minimum: Some(0i64),
712 ..Default::default()
713 }),
714 );
715 map.insert(
716 SmolStr::new_static("xpGainedFromPreviousLevel"),
717 LexObjectProperty::Integer(LexInteger {
718 minimum: Some(0i64),
719 ..Default::default()
720 }),
721 );
722 map
723 },
724 ..Default::default()
725 }),
726 );
727 map.insert(
728 SmolStr::new_static("levelSnapshot"),
729 LexUserType::Object(LexObject {
730 description: Some(CowStr::new_static(
731 "Player state at the moment of leveling up",
732 )),
733 required: Some(vec![SmolStr::new_static("totalXP")]),
734 properties: {
735 #[allow(unused_mut)]
736 let mut map = BTreeMap::new();
737 map.insert(
738 SmolStr::new_static("daysPlayed"),
739 LexObjectProperty::Integer(LexInteger {
740 minimum: Some(0i64),
741 ..Default::default()
742 }),
743 );
744 map.insert(
745 SmolStr::new_static("itemsTotal"),
746 LexObjectProperty::Integer(LexInteger {
747 minimum: Some(0i64),
748 ..Default::default()
749 }),
750 );
751 map.insert(
752 SmolStr::new_static("postsReadTotal"),
753 LexObjectProperty::Integer(LexInteger {
754 minimum: Some(0i64),
755 ..Default::default()
756 }),
757 );
758 map.insert(
759 SmolStr::new_static("specimensDocumented"),
760 LexObjectProperty::Integer(LexInteger {
761 minimum: Some(0i64),
762 ..Default::default()
763 }),
764 );
765 map.insert(
766 SmolStr::new_static("totalXP"),
767 LexObjectProperty::Integer(LexInteger {
768 minimum: Some(0i64),
769 ..Default::default()
770 }),
771 );
772 map
773 },
774 ..Default::default()
775 }),
776 );
777 map.insert(
778 SmolStr::new_static("main"),
779 LexUserType::Record(LexRecord {
780 description: Some(
781 CowStr::new_static(
782 "Immutable level milestone record. Created once on level-up with createRecord. rkey is zero-padded level (001-099).",
783 ),
784 ),
785 key: Some(CowStr::new_static("any")),
786 record: LexRecordRecord::Object(LexObject {
787 required: Some(
788 vec![
789 SmolStr::new_static("level"),
790 SmolStr::new_static("snapshot"),
791 SmolStr::new_static("signature"),
792 SmolStr::new_static("createdAt")
793 ],
794 ),
795 properties: {
796 #[allow(unused_mut)]
797 let mut map = BTreeMap::new();
798 map.insert(
799 SmolStr::new_static("createdAt"),
800 LexObjectProperty::String(LexString {
801 description: Some(
802 CowStr::new_static("When the level was reached"),
803 ),
804 format: Some(LexStringFormat::Datetime),
805 ..Default::default()
806 }),
807 );
808 map.insert(
809 SmolStr::new_static("journey"),
810 LexObjectProperty::Ref(LexRef {
811 r#ref: CowStr::new_static("#journeyData"),
812 ..Default::default()
813 }),
814 );
815 map.insert(
816 SmolStr::new_static("level"),
817 LexObjectProperty::Integer(LexInteger {
818 minimum: Some(1i64),
819 maximum: Some(99i64),
820 ..Default::default()
821 }),
822 );
823 map.insert(
824 SmolStr::new_static("signature"),
825 LexObjectProperty::Ref(LexRef {
826 r#ref: CowStr::new_static("#chronicleSignature"),
827 ..Default::default()
828 }),
829 );
830 map.insert(
831 SmolStr::new_static("snapshot"),
832 LexObjectProperty::Ref(LexRef {
833 r#ref: CowStr::new_static("#levelSnapshot"),
834 ..Default::default()
835 }),
836 );
837 map
838 },
839 ..Default::default()
840 }),
841 ..Default::default()
842 }),
843 );
844 map
845 },
846 ..Default::default()
847 }
848}
849
850pub mod level_snapshot_state {
851
852 pub use crate::builder_types::{IsSet, IsUnset, Set, Unset};
853 #[allow(unused)]
854 use ::core::marker::PhantomData;
855 mod sealed {
856 pub trait Sealed {}
857 }
858 pub trait State: sealed::Sealed {
860 type TotalXp;
861 }
862 pub struct Empty(());
864 impl sealed::Sealed for Empty {}
865 impl State for Empty {
866 type TotalXp = Unset;
867 }
868 pub struct SetTotalXp<St: State = Empty>(PhantomData<fn() -> St>);
870 impl<St: State> sealed::Sealed for SetTotalXp<St> {}
871 impl<St: State> State for SetTotalXp<St> {
872 type TotalXp = Set<members::total_xp>;
873 }
874 #[allow(non_camel_case_types)]
876 pub mod members {
877 pub struct total_xp(());
879 }
880}
881
882pub struct LevelSnapshotBuilder<St: level_snapshot_state::State, S: BosStr = DefaultStr> {
884 _state: PhantomData<fn() -> St>,
885 _fields: (
886 Option<i64>,
887 Option<i64>,
888 Option<i64>,
889 Option<i64>,
890 Option<i64>,
891 ),
892 _type: PhantomData<fn() -> S>,
893}
894
895impl LevelSnapshot<DefaultStr> {
896 pub fn new() -> LevelSnapshotBuilder<level_snapshot_state::Empty, DefaultStr> {
898 LevelSnapshotBuilder::new()
899 }
900}
901
902impl<S: BosStr> LevelSnapshot<S> {
903 pub fn builder() -> LevelSnapshotBuilder<level_snapshot_state::Empty, S> {
905 LevelSnapshotBuilder::builder()
906 }
907}
908
909impl LevelSnapshotBuilder<level_snapshot_state::Empty, DefaultStr> {
910 pub fn new() -> Self {
912 LevelSnapshotBuilder {
913 _state: PhantomData,
914 _fields: (None, None, None, None, None),
915 _type: PhantomData,
916 }
917 }
918}
919
920impl<S: BosStr> LevelSnapshotBuilder<level_snapshot_state::Empty, S> {
921 pub fn builder() -> Self {
923 LevelSnapshotBuilder {
924 _state: PhantomData,
925 _fields: (None, None, None, None, None),
926 _type: PhantomData,
927 }
928 }
929}
930
931impl<St: level_snapshot_state::State, S: BosStr> LevelSnapshotBuilder<St, S> {
932 pub fn days_played(mut self, value: impl Into<Option<i64>>) -> Self {
934 self._fields.0 = value.into();
935 self
936 }
937 pub fn maybe_days_played(mut self, value: Option<i64>) -> Self {
939 self._fields.0 = value;
940 self
941 }
942}
943
944impl<St: level_snapshot_state::State, S: BosStr> LevelSnapshotBuilder<St, S> {
945 pub fn items_total(mut self, value: impl Into<Option<i64>>) -> Self {
947 self._fields.1 = value.into();
948 self
949 }
950 pub fn maybe_items_total(mut self, value: Option<i64>) -> Self {
952 self._fields.1 = value;
953 self
954 }
955}
956
957impl<St: level_snapshot_state::State, S: BosStr> LevelSnapshotBuilder<St, S> {
958 pub fn posts_read_total(mut self, value: impl Into<Option<i64>>) -> Self {
960 self._fields.2 = value.into();
961 self
962 }
963 pub fn maybe_posts_read_total(mut self, value: Option<i64>) -> Self {
965 self._fields.2 = value;
966 self
967 }
968}
969
970impl<St: level_snapshot_state::State, S: BosStr> LevelSnapshotBuilder<St, S> {
971 pub fn specimens_documented(mut self, value: impl Into<Option<i64>>) -> Self {
973 self._fields.3 = value.into();
974 self
975 }
976 pub fn maybe_specimens_documented(mut self, value: Option<i64>) -> Self {
978 self._fields.3 = value;
979 self
980 }
981}
982
983impl<St, S: BosStr> LevelSnapshotBuilder<St, S>
984where
985 St: level_snapshot_state::State,
986 St::TotalXp: level_snapshot_state::IsUnset,
987{
988 pub fn total_xp(
990 mut self,
991 value: impl Into<i64>,
992 ) -> LevelSnapshotBuilder<level_snapshot_state::SetTotalXp<St>, S> {
993 self._fields.4 = Option::Some(value.into());
994 LevelSnapshotBuilder {
995 _state: PhantomData,
996 _fields: self._fields,
997 _type: PhantomData,
998 }
999 }
1000}
1001
1002impl<St, S: BosStr> LevelSnapshotBuilder<St, S>
1003where
1004 St: level_snapshot_state::State,
1005 St::TotalXp: level_snapshot_state::IsSet,
1006{
1007 pub fn build(self) -> LevelSnapshot<S> {
1009 LevelSnapshot {
1010 days_played: self._fields.0,
1011 items_total: self._fields.1,
1012 posts_read_total: self._fields.2,
1013 specimens_documented: self._fields.3,
1014 total_xp: self._fields.4.unwrap(),
1015 extra_data: Default::default(),
1016 }
1017 }
1018 pub fn build_with_data(self, extra_data: BTreeMap<SmolStr, Data<S>>) -> LevelSnapshot<S> {
1020 LevelSnapshot {
1021 days_played: self._fields.0,
1022 items_total: self._fields.1,
1023 posts_read_total: self._fields.2,
1024 specimens_documented: self._fields.3,
1025 total_xp: self._fields.4.unwrap(),
1026 extra_data: Some(extra_data),
1027 }
1028 }
1029}
1030
1031pub mod level_state {
1032
1033 pub use crate::builder_types::{IsSet, IsUnset, Set, Unset};
1034 #[allow(unused)]
1035 use ::core::marker::PhantomData;
1036 mod sealed {
1037 pub trait Sealed {}
1038 }
1039 pub trait State: sealed::Sealed {
1041 type CreatedAt;
1042 type Level;
1043 type Signature;
1044 type Snapshot;
1045 }
1046 pub struct Empty(());
1048 impl sealed::Sealed for Empty {}
1049 impl State for Empty {
1050 type CreatedAt = Unset;
1051 type Level = Unset;
1052 type Signature = Unset;
1053 type Snapshot = Unset;
1054 }
1055 pub struct SetCreatedAt<St: State = Empty>(PhantomData<fn() -> St>);
1057 impl<St: State> sealed::Sealed for SetCreatedAt<St> {}
1058 impl<St: State> State for SetCreatedAt<St> {
1059 type CreatedAt = Set<members::created_at>;
1060 type Level = St::Level;
1061 type Signature = St::Signature;
1062 type Snapshot = St::Snapshot;
1063 }
1064 pub struct SetLevel<St: State = Empty>(PhantomData<fn() -> St>);
1066 impl<St: State> sealed::Sealed for SetLevel<St> {}
1067 impl<St: State> State for SetLevel<St> {
1068 type CreatedAt = St::CreatedAt;
1069 type Level = Set<members::level>;
1070 type Signature = St::Signature;
1071 type Snapshot = St::Snapshot;
1072 }
1073 pub struct SetSignature<St: State = Empty>(PhantomData<fn() -> St>);
1075 impl<St: State> sealed::Sealed for SetSignature<St> {}
1076 impl<St: State> State for SetSignature<St> {
1077 type CreatedAt = St::CreatedAt;
1078 type Level = St::Level;
1079 type Signature = Set<members::signature>;
1080 type Snapshot = St::Snapshot;
1081 }
1082 pub struct SetSnapshot<St: State = Empty>(PhantomData<fn() -> St>);
1084 impl<St: State> sealed::Sealed for SetSnapshot<St> {}
1085 impl<St: State> State for SetSnapshot<St> {
1086 type CreatedAt = St::CreatedAt;
1087 type Level = St::Level;
1088 type Signature = St::Signature;
1089 type Snapshot = Set<members::snapshot>;
1090 }
1091 #[allow(non_camel_case_types)]
1093 pub mod members {
1094 pub struct created_at(());
1096 pub struct level(());
1098 pub struct signature(());
1100 pub struct snapshot(());
1102 }
1103}
1104
1105pub struct LevelBuilder<St: level_state::State, S: BosStr = DefaultStr> {
1107 _state: PhantomData<fn() -> St>,
1108 _fields: (
1109 Option<Datetime>,
1110 Option<level::JourneyData<S>>,
1111 Option<i64>,
1112 Option<level::ChronicleSignature<S>>,
1113 Option<level::LevelSnapshot<S>>,
1114 ),
1115 _type: PhantomData<fn() -> S>,
1116}
1117
1118impl Level<DefaultStr> {
1119 pub fn new() -> LevelBuilder<level_state::Empty, DefaultStr> {
1121 LevelBuilder::new()
1122 }
1123}
1124
1125impl<S: BosStr> Level<S> {
1126 pub fn builder() -> LevelBuilder<level_state::Empty, S> {
1128 LevelBuilder::builder()
1129 }
1130}
1131
1132impl LevelBuilder<level_state::Empty, DefaultStr> {
1133 pub fn new() -> Self {
1135 LevelBuilder {
1136 _state: PhantomData,
1137 _fields: (None, None, None, None, None),
1138 _type: PhantomData,
1139 }
1140 }
1141}
1142
1143impl<S: BosStr> LevelBuilder<level_state::Empty, S> {
1144 pub fn builder() -> Self {
1146 LevelBuilder {
1147 _state: PhantomData,
1148 _fields: (None, None, None, None, None),
1149 _type: PhantomData,
1150 }
1151 }
1152}
1153
1154impl<St, S: BosStr> LevelBuilder<St, S>
1155where
1156 St: level_state::State,
1157 St::CreatedAt: level_state::IsUnset,
1158{
1159 pub fn created_at(
1161 mut self,
1162 value: impl Into<Datetime>,
1163 ) -> LevelBuilder<level_state::SetCreatedAt<St>, S> {
1164 self._fields.0 = Option::Some(value.into());
1165 LevelBuilder {
1166 _state: PhantomData,
1167 _fields: self._fields,
1168 _type: PhantomData,
1169 }
1170 }
1171}
1172
1173impl<St: level_state::State, S: BosStr> LevelBuilder<St, S> {
1174 pub fn journey(mut self, value: impl Into<Option<level::JourneyData<S>>>) -> Self {
1176 self._fields.1 = value.into();
1177 self
1178 }
1179 pub fn maybe_journey(mut self, value: Option<level::JourneyData<S>>) -> Self {
1181 self._fields.1 = value;
1182 self
1183 }
1184}
1185
1186impl<St, S: BosStr> LevelBuilder<St, S>
1187where
1188 St: level_state::State,
1189 St::Level: level_state::IsUnset,
1190{
1191 pub fn level(mut self, value: impl Into<i64>) -> LevelBuilder<level_state::SetLevel<St>, S> {
1193 self._fields.2 = Option::Some(value.into());
1194 LevelBuilder {
1195 _state: PhantomData,
1196 _fields: self._fields,
1197 _type: PhantomData,
1198 }
1199 }
1200}
1201
1202impl<St, S: BosStr> LevelBuilder<St, S>
1203where
1204 St: level_state::State,
1205 St::Signature: level_state::IsUnset,
1206{
1207 pub fn signature(
1209 mut self,
1210 value: impl Into<level::ChronicleSignature<S>>,
1211 ) -> LevelBuilder<level_state::SetSignature<St>, S> {
1212 self._fields.3 = Option::Some(value.into());
1213 LevelBuilder {
1214 _state: PhantomData,
1215 _fields: self._fields,
1216 _type: PhantomData,
1217 }
1218 }
1219}
1220
1221impl<St, S: BosStr> LevelBuilder<St, S>
1222where
1223 St: level_state::State,
1224 St::Snapshot: level_state::IsUnset,
1225{
1226 pub fn snapshot(
1228 mut self,
1229 value: impl Into<level::LevelSnapshot<S>>,
1230 ) -> LevelBuilder<level_state::SetSnapshot<St>, S> {
1231 self._fields.4 = Option::Some(value.into());
1232 LevelBuilder {
1233 _state: PhantomData,
1234 _fields: self._fields,
1235 _type: PhantomData,
1236 }
1237 }
1238}
1239
1240impl<St, S: BosStr> LevelBuilder<St, S>
1241where
1242 St: level_state::State,
1243 St::CreatedAt: level_state::IsSet,
1244 St::Level: level_state::IsSet,
1245 St::Signature: level_state::IsSet,
1246 St::Snapshot: level_state::IsSet,
1247{
1248 pub fn build(self) -> Level<S> {
1250 Level {
1251 created_at: self._fields.0.unwrap(),
1252 journey: self._fields.1,
1253 level: self._fields.2.unwrap(),
1254 signature: self._fields.3.unwrap(),
1255 snapshot: self._fields.4.unwrap(),
1256 extra_data: Default::default(),
1257 }
1258 }
1259 pub fn build_with_data(self, extra_data: BTreeMap<SmolStr, Data<S>>) -> Level<S> {
1261 Level {
1262 created_at: self._fields.0.unwrap(),
1263 journey: self._fields.1,
1264 level: self._fields.2.unwrap(),
1265 signature: self._fields.3.unwrap(),
1266 snapshot: self._fields.4.unwrap(),
1267 extra_data: Some(extra_data),
1268 }
1269 }
1270}