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::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::games_gamesgamesgamesgames::MediaItem;
28use crate::games_gamesgamesgamesgames::Website;
29#[allow(unused_imports)]
30use jacquard_lexicon::validation::{ConstraintError, ValidationPath};
31use serde::{Deserialize, Serialize};
32#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
35#[serde(
36 rename_all = "camelCase",
37 rename = "games.gamesgamesgamesgames.collection",
38 tag = "$type",
39 bound(deserialize = "S: Deserialize<'de> + BosStr")
40)]
41pub struct Collection<S: BosStr = DefaultStr> {
42 pub created_at: Datetime,
43 #[serde(skip_serializing_if = "Option::is_none")]
44 pub description: Option<S>,
45 #[serde(skip_serializing_if = "Option::is_none")]
46 pub games: Option<Vec<AtUri<S>>>,
47 #[serde(skip_serializing_if = "Option::is_none")]
48 pub media: Option<Vec<MediaItem<S>>>,
49 pub name: S,
50 #[serde(skip_serializing_if = "Option::is_none")]
51 pub parent: Option<AtUri<S>>,
52 #[serde(skip_serializing_if = "Option::is_none")]
53 pub r#type: Option<CollectionType<S>>,
54 #[serde(skip_serializing_if = "Option::is_none")]
55 pub websites: Option<Vec<Website<S>>>,
56 #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
57 pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
58}
59
60#[derive(Debug, Clone, PartialEq, Eq, Hash)]
61pub enum CollectionType<S: BosStr = DefaultStr> {
62 Franchise,
63 Series,
64 Curated,
65 Other(S),
66}
67
68impl<S: BosStr> CollectionType<S> {
69 pub fn as_str(&self) -> &str {
70 match self {
71 Self::Franchise => "franchise",
72 Self::Series => "series",
73 Self::Curated => "curated",
74 Self::Other(s) => s.as_ref(),
75 }
76 }
77 pub fn from_value(s: S) -> Self {
79 match s.as_ref() {
80 "franchise" => Self::Franchise,
81 "series" => Self::Series,
82 "curated" => Self::Curated,
83 _ => Self::Other(s),
84 }
85 }
86}
87
88impl<S: BosStr> core::fmt::Display for CollectionType<S> {
89 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
90 write!(f, "{}", self.as_str())
91 }
92}
93
94impl<S: BosStr> AsRef<str> for CollectionType<S> {
95 fn as_ref(&self) -> &str {
96 self.as_str()
97 }
98}
99
100impl<S: BosStr> Serialize for CollectionType<S> {
101 fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
102 where
103 Ser: serde::Serializer,
104 {
105 serializer.serialize_str(self.as_str())
106 }
107}
108
109impl<'de, S: Deserialize<'de> + BosStr> Deserialize<'de> for CollectionType<S> {
110 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
111 where
112 D: serde::Deserializer<'de>,
113 {
114 let s = S::deserialize(deserializer)?;
115 Ok(Self::from_value(s))
116 }
117}
118
119impl<S: BosStr + Default> Default for CollectionType<S> {
120 fn default() -> Self {
121 Self::Other(Default::default())
122 }
123}
124
125impl<S: BosStr> jacquard_common::IntoStatic for CollectionType<S>
126where
127 S: BosStr + jacquard_common::IntoStatic,
128 S::Output: BosStr,
129{
130 type Output = CollectionType<S::Output>;
131 fn into_static(self) -> Self::Output {
132 match self {
133 CollectionType::Franchise => CollectionType::Franchise,
134 CollectionType::Series => CollectionType::Series,
135 CollectionType::Curated => CollectionType::Curated,
136 CollectionType::Other(v) => CollectionType::Other(v.into_static()),
137 }
138 }
139}
140
141#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
144#[serde(rename_all = "camelCase")]
145pub struct CollectionGetRecordOutput<S: BosStr = DefaultStr> {
146 #[serde(skip_serializing_if = "Option::is_none")]
147 pub cid: Option<Cid<S>>,
148 pub uri: AtUri<S>,
149 pub value: Collection<S>,
150}
151
152impl<S: BosStr> Collection<S> {
153 pub fn uri(uri: S) -> Result<RecordUri<S, CollectionRecord>, UriError> {
154 RecordUri::try_from_uri(AtUri::new(uri)?)
155 }
156}
157
158#[derive(Debug, Serialize, Deserialize)]
161pub struct CollectionRecord;
162impl XrpcResp for CollectionRecord {
163 const NSID: &'static str = "games.gamesgamesgamesgames.collection";
164 const ENCODING: &'static str = "application/json";
165 type Output<S: BosStr> = CollectionGetRecordOutput<S>;
166 type Err = RecordError;
167}
168
169impl<S: BosStr> From<CollectionGetRecordOutput<S>> for Collection<S> {
170 fn from(output: CollectionGetRecordOutput<S>) -> Self {
171 output.value
172 }
173}
174
175impl<S: BosStr> jacquard_common::types::collection::Collection for Collection<S> {
176 const NSID: &'static str = "games.gamesgamesgamesgames.collection";
177 type Record = CollectionRecord;
178}
179
180impl jacquard_common::types::collection::Collection for CollectionRecord {
181 const NSID: &'static str = "games.gamesgamesgamesgames.collection";
182 type Record = CollectionRecord;
183}
184
185impl<S: BosStr> LexiconSchema for Collection<S> {
186 fn nsid() -> &'static str {
187 "games.gamesgamesgamesgames.collection"
188 }
189 fn def_name() -> &'static str {
190 "main"
191 }
192 fn lexicon_doc() -> LexiconDoc<'static> {
193 lexicon_doc_games_gamesgamesgamesgames_collection()
194 }
195 fn validate(&self) -> Result<(), ConstraintError> {
196 Ok(())
197 }
198}
199
200pub mod collection_state {
201
202 pub use crate::builder_types::{IsSet, IsUnset, Set, Unset};
203 #[allow(unused)]
204 use ::core::marker::PhantomData;
205 mod sealed {
206 pub trait Sealed {}
207 }
208 pub trait State: sealed::Sealed {
210 type CreatedAt;
211 type Name;
212 }
213 pub struct Empty(());
215 impl sealed::Sealed for Empty {}
216 impl State for Empty {
217 type CreatedAt = Unset;
218 type Name = Unset;
219 }
220 pub struct SetCreatedAt<St: State = Empty>(PhantomData<fn() -> St>);
222 impl<St: State> sealed::Sealed for SetCreatedAt<St> {}
223 impl<St: State> State for SetCreatedAt<St> {
224 type CreatedAt = Set<members::created_at>;
225 type Name = St::Name;
226 }
227 pub struct SetName<St: State = Empty>(PhantomData<fn() -> St>);
229 impl<St: State> sealed::Sealed for SetName<St> {}
230 impl<St: State> State for SetName<St> {
231 type CreatedAt = St::CreatedAt;
232 type Name = Set<members::name>;
233 }
234 #[allow(non_camel_case_types)]
236 pub mod members {
237 pub struct created_at(());
239 pub struct name(());
241 }
242}
243
244pub struct CollectionBuilder<St: collection_state::State, S: BosStr = DefaultStr> {
246 _state: PhantomData<fn() -> St>,
247 _fields: (
248 Option<Datetime>,
249 Option<S>,
250 Option<Vec<AtUri<S>>>,
251 Option<Vec<MediaItem<S>>>,
252 Option<S>,
253 Option<AtUri<S>>,
254 Option<CollectionType<S>>,
255 Option<Vec<Website<S>>>,
256 ),
257 _type: PhantomData<fn() -> S>,
258}
259
260impl Collection<DefaultStr> {
261 pub fn new() -> CollectionBuilder<collection_state::Empty, DefaultStr> {
263 CollectionBuilder::new()
264 }
265}
266
267impl<S: BosStr> Collection<S> {
268 pub fn builder() -> CollectionBuilder<collection_state::Empty, S> {
270 CollectionBuilder::builder()
271 }
272}
273
274impl CollectionBuilder<collection_state::Empty, DefaultStr> {
275 pub fn new() -> Self {
277 CollectionBuilder {
278 _state: PhantomData,
279 _fields: (None, None, None, None, None, None, None, None),
280 _type: PhantomData,
281 }
282 }
283}
284
285impl<S: BosStr> CollectionBuilder<collection_state::Empty, S> {
286 pub fn builder() -> Self {
288 CollectionBuilder {
289 _state: PhantomData,
290 _fields: (None, None, None, None, None, None, None, None),
291 _type: PhantomData,
292 }
293 }
294}
295
296impl<St, S: BosStr> CollectionBuilder<St, S>
297where
298 St: collection_state::State,
299 St::CreatedAt: collection_state::IsUnset,
300{
301 pub fn created_at(
303 mut self,
304 value: impl Into<Datetime>,
305 ) -> CollectionBuilder<collection_state::SetCreatedAt<St>, S> {
306 self._fields.0 = Option::Some(value.into());
307 CollectionBuilder {
308 _state: PhantomData,
309 _fields: self._fields,
310 _type: PhantomData,
311 }
312 }
313}
314
315impl<St: collection_state::State, S: BosStr> CollectionBuilder<St, S> {
316 pub fn description(mut self, value: impl Into<Option<S>>) -> Self {
318 self._fields.1 = value.into();
319 self
320 }
321 pub fn maybe_description(mut self, value: Option<S>) -> Self {
323 self._fields.1 = value;
324 self
325 }
326}
327
328impl<St: collection_state::State, S: BosStr> CollectionBuilder<St, S> {
329 pub fn games(mut self, value: impl Into<Option<Vec<AtUri<S>>>>) -> Self {
331 self._fields.2 = value.into();
332 self
333 }
334 pub fn maybe_games(mut self, value: Option<Vec<AtUri<S>>>) -> Self {
336 self._fields.2 = value;
337 self
338 }
339}
340
341impl<St: collection_state::State, S: BosStr> CollectionBuilder<St, S> {
342 pub fn media(mut self, value: impl Into<Option<Vec<MediaItem<S>>>>) -> Self {
344 self._fields.3 = value.into();
345 self
346 }
347 pub fn maybe_media(mut self, value: Option<Vec<MediaItem<S>>>) -> Self {
349 self._fields.3 = value;
350 self
351 }
352}
353
354impl<St, S: BosStr> CollectionBuilder<St, S>
355where
356 St: collection_state::State,
357 St::Name: collection_state::IsUnset,
358{
359 pub fn name(
361 mut self,
362 value: impl Into<S>,
363 ) -> CollectionBuilder<collection_state::SetName<St>, S> {
364 self._fields.4 = Option::Some(value.into());
365 CollectionBuilder {
366 _state: PhantomData,
367 _fields: self._fields,
368 _type: PhantomData,
369 }
370 }
371}
372
373impl<St: collection_state::State, S: BosStr> CollectionBuilder<St, S> {
374 pub fn parent(mut self, value: impl Into<Option<AtUri<S>>>) -> Self {
376 self._fields.5 = value.into();
377 self
378 }
379 pub fn maybe_parent(mut self, value: Option<AtUri<S>>) -> Self {
381 self._fields.5 = value;
382 self
383 }
384}
385
386impl<St: collection_state::State, S: BosStr> CollectionBuilder<St, S> {
387 pub fn r#type(mut self, value: impl Into<Option<CollectionType<S>>>) -> Self {
389 self._fields.6 = value.into();
390 self
391 }
392 pub fn maybe_type(mut self, value: Option<CollectionType<S>>) -> Self {
394 self._fields.6 = value;
395 self
396 }
397}
398
399impl<St: collection_state::State, S: BosStr> CollectionBuilder<St, S> {
400 pub fn websites(mut self, value: impl Into<Option<Vec<Website<S>>>>) -> Self {
402 self._fields.7 = value.into();
403 self
404 }
405 pub fn maybe_websites(mut self, value: Option<Vec<Website<S>>>) -> Self {
407 self._fields.7 = value;
408 self
409 }
410}
411
412impl<St, S: BosStr> CollectionBuilder<St, S>
413where
414 St: collection_state::State,
415 St::CreatedAt: collection_state::IsSet,
416 St::Name: collection_state::IsSet,
417{
418 pub fn build(self) -> Collection<S> {
420 Collection {
421 created_at: self._fields.0.unwrap(),
422 description: self._fields.1,
423 games: self._fields.2,
424 media: self._fields.3,
425 name: self._fields.4.unwrap(),
426 parent: self._fields.5,
427 r#type: self._fields.6,
428 websites: self._fields.7,
429 extra_data: Default::default(),
430 }
431 }
432 pub fn build_with_data(self, extra_data: BTreeMap<SmolStr, Data<S>>) -> Collection<S> {
434 Collection {
435 created_at: self._fields.0.unwrap(),
436 description: self._fields.1,
437 games: self._fields.2,
438 media: self._fields.3,
439 name: self._fields.4.unwrap(),
440 parent: self._fields.5,
441 r#type: self._fields.6,
442 websites: self._fields.7,
443 extra_data: Some(extra_data),
444 }
445 }
446}
447
448fn lexicon_doc_games_gamesgamesgamesgames_collection() -> LexiconDoc<'static> {
449 use alloc::collections::BTreeMap;
450 #[allow(unused_imports)]
451 use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType};
452 use jacquard_lexicon::lexicon::*;
453 LexiconDoc {
454 lexicon: Lexicon::Lexicon1,
455 id: CowStr::new_static("games.gamesgamesgamesgames.collection"),
456 defs: {
457 let mut map = BTreeMap::new();
458 map.insert(
459 SmolStr::new_static("main"),
460 LexUserType::Record(LexRecord {
461 description: Some(CowStr::new_static(
462 "A grouping of games — franchise, series, or curated list.",
463 )),
464 key: Some(CowStr::new_static("tid")),
465 record: LexRecordRecord::Object(LexObject {
466 required: Some(vec![
467 SmolStr::new_static("name"),
468 SmolStr::new_static("createdAt"),
469 ]),
470 properties: {
471 #[allow(unused_mut)]
472 let mut map = BTreeMap::new();
473 map.insert(
474 SmolStr::new_static("createdAt"),
475 LexObjectProperty::String(LexString {
476 format: Some(LexStringFormat::Datetime),
477 ..Default::default()
478 }),
479 );
480 map.insert(
481 SmolStr::new_static("description"),
482 LexObjectProperty::String(LexString {
483 ..Default::default()
484 }),
485 );
486 map.insert(
487 SmolStr::new_static("games"),
488 LexObjectProperty::Array(LexArray {
489 items: LexArrayItem::String(LexString {
490 format: Some(LexStringFormat::AtUri),
491 ..Default::default()
492 }),
493 ..Default::default()
494 }),
495 );
496 map.insert(
497 SmolStr::new_static("media"),
498 LexObjectProperty::Array(LexArray {
499 items: LexArrayItem::Ref(LexRef {
500 r#ref: CowStr::new_static(
501 "games.gamesgamesgamesgames.defs#mediaItem",
502 ),
503 ..Default::default()
504 }),
505 ..Default::default()
506 }),
507 );
508 map.insert(
509 SmolStr::new_static("name"),
510 LexObjectProperty::String(LexString {
511 ..Default::default()
512 }),
513 );
514 map.insert(
515 SmolStr::new_static("parent"),
516 LexObjectProperty::String(LexString {
517 format: Some(LexStringFormat::AtUri),
518 ..Default::default()
519 }),
520 );
521 map.insert(
522 SmolStr::new_static("type"),
523 LexObjectProperty::String(LexString {
524 ..Default::default()
525 }),
526 );
527 map.insert(
528 SmolStr::new_static("websites"),
529 LexObjectProperty::Array(LexArray {
530 items: LexArrayItem::Ref(LexRef {
531 r#ref: CowStr::new_static(
532 "games.gamesgamesgamesgames.defs#website",
533 ),
534 ..Default::default()
535 }),
536 ..Default::default()
537 }),
538 );
539 map
540 },
541 ..Default::default()
542 }),
543 ..Default::default()
544 }),
545 );
546 map
547 },
548 ..Default::default()
549 }
550}