#[allow(unused_imports)]
use alloc::collections::BTreeMap;
#[allow(unused_imports)]
use core::marker::PhantomData;
use jacquard_common::{CowStr, BosStr, DefaultStr, FromStaticStr};
#[allow(unused_imports)]
use jacquard_common::deps::codegen::unicode_segmentation::UnicodeSegmentation;
use jacquard_common::deps::smol_str::SmolStr;
use jacquard_common::types::collection::{Collection, RecordError};
use jacquard_common::types::string::{AtUri, Cid, Datetime};
use jacquard_common::types::uri::{RecordUri, UriError};
use jacquard_common::types::value::Data;
use jacquard_common::xrpc::XrpcResp;
use jacquard_derive::{IntoStatic, lexicon};
use jacquard_lexicon::lexicon::LexiconDoc;
use jacquard_lexicon::schema::LexiconSchema;
#[allow(unused_imports)]
use jacquard_lexicon::validation::{ConstraintError, ValidationPath};
use serde::{Serialize, Deserialize};
use crate::fm_teal::alpha::feed::Artist;
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(
rename_all = "camelCase",
rename = "fm.teal.alpha.feed.play",
tag = "$type",
bound(deserialize = "S: Deserialize<'de> + BosStr")
)]
pub struct Play<S: BosStr = DefaultStr> {
#[serde(skip_serializing_if = "Option::is_none")]
pub artist_mb_ids: Option<Vec<S>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub artist_names: Option<Vec<S>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub artists: Option<Vec<Artist<S>>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub duration: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub isrc: Option<S>,
#[serde(skip_serializing_if = "Option::is_none")]
pub music_service_base_domain: Option<S>,
#[serde(skip_serializing_if = "Option::is_none")]
pub origin_url: Option<S>,
#[serde(skip_serializing_if = "Option::is_none")]
pub played_time: Option<Datetime>,
#[serde(skip_serializing_if = "Option::is_none")]
pub recording_mb_id: Option<S>,
#[serde(skip_serializing_if = "Option::is_none")]
pub release_discriminant: Option<S>,
#[serde(skip_serializing_if = "Option::is_none")]
pub release_mb_id: Option<S>,
#[serde(skip_serializing_if = "Option::is_none")]
pub release_name: Option<S>,
#[serde(skip_serializing_if = "Option::is_none")]
pub submission_client_agent: Option<S>,
#[serde(skip_serializing_if = "Option::is_none")]
pub track_discriminant: Option<S>,
#[serde(skip_serializing_if = "Option::is_none")]
pub track_mb_id: Option<S>,
pub track_name: S,
#[serde(flatten, default, skip_serializing_if = "Option::is_none")]
pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(rename_all = "camelCase")]
pub struct PlayGetRecordOutput<S: BosStr = DefaultStr> {
#[serde(skip_serializing_if = "Option::is_none")]
pub cid: Option<Cid<S>>,
pub uri: AtUri<S>,
pub value: Play<S>,
}
impl<S: BosStr> Play<S> {
pub fn uri(uri: S) -> Result<RecordUri<S, PlayRecord>, UriError> {
RecordUri::try_from_uri(AtUri::new(uri)?)
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct PlayRecord;
impl XrpcResp for PlayRecord {
const NSID: &'static str = "fm.teal.alpha.feed.play";
const ENCODING: &'static str = "application/json";
type Output<S: BosStr> = PlayGetRecordOutput<S>;
type Err = RecordError;
}
impl<S: BosStr> From<PlayGetRecordOutput<S>> for Play<S> {
fn from(output: PlayGetRecordOutput<S>) -> Self {
output.value
}
}
impl<S: BosStr> Collection for Play<S> {
const NSID: &'static str = "fm.teal.alpha.feed.play";
type Record = PlayRecord;
}
impl Collection for PlayRecord {
const NSID: &'static str = "fm.teal.alpha.feed.play";
type Record = PlayRecord;
}
impl<S: BosStr> LexiconSchema for Play<S> {
fn nsid() -> &'static str {
"fm.teal.alpha.feed.play"
}
fn def_name() -> &'static str {
"main"
}
fn lexicon_doc() -> LexiconDoc<'static> {
lexicon_doc_fm_teal_alpha_feed_play()
}
fn validate(&self) -> Result<(), ConstraintError> {
if let Some(ref value) = self.release_discriminant {
#[allow(unused_comparisons)]
if <str>::len(value.as_ref()) > 128usize {
return Err(ConstraintError::MaxLength {
path: ValidationPath::from_field("release_discriminant"),
max: 128usize,
actual: <str>::len(value.as_ref()),
});
}
}
if let Some(ref value) = self.release_discriminant {
{
let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count();
if count > 1280usize {
return Err(ConstraintError::MaxGraphemes {
path: ValidationPath::from_field("release_discriminant"),
max: 1280usize,
actual: count,
});
}
}
}
if let Some(ref value) = self.release_name {
#[allow(unused_comparisons)]
if <str>::len(value.as_ref()) > 256usize {
return Err(ConstraintError::MaxLength {
path: ValidationPath::from_field("release_name"),
max: 256usize,
actual: <str>::len(value.as_ref()),
});
}
}
if let Some(ref value) = self.release_name {
{
let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count();
if count > 2560usize {
return Err(ConstraintError::MaxGraphemes {
path: ValidationPath::from_field("release_name"),
max: 2560usize,
actual: count,
});
}
}
}
if let Some(ref value) = self.submission_client_agent {
#[allow(unused_comparisons)]
if <str>::len(value.as_ref()) > 256usize {
return Err(ConstraintError::MaxLength {
path: ValidationPath::from_field("submission_client_agent"),
max: 256usize,
actual: <str>::len(value.as_ref()),
});
}
}
if let Some(ref value) = self.submission_client_agent {
{
let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count();
if count > 2560usize {
return Err(ConstraintError::MaxGraphemes {
path: ValidationPath::from_field("submission_client_agent"),
max: 2560usize,
actual: count,
});
}
}
}
if let Some(ref value) = self.track_discriminant {
#[allow(unused_comparisons)]
if <str>::len(value.as_ref()) > 128usize {
return Err(ConstraintError::MaxLength {
path: ValidationPath::from_field("track_discriminant"),
max: 128usize,
actual: <str>::len(value.as_ref()),
});
}
}
if let Some(ref value) = self.track_discriminant {
{
let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count();
if count > 1280usize {
return Err(ConstraintError::MaxGraphemes {
path: ValidationPath::from_field("track_discriminant"),
max: 1280usize,
actual: count,
});
}
}
}
{
let value = &self.track_name;
#[allow(unused_comparisons)]
if <str>::len(value.as_ref()) > 256usize {
return Err(ConstraintError::MaxLength {
path: ValidationPath::from_field("track_name"),
max: 256usize,
actual: <str>::len(value.as_ref()),
});
}
}
{
let value = &self.track_name;
#[allow(unused_comparisons)]
if <str>::len(value.as_ref()) < 1usize {
return Err(ConstraintError::MinLength {
path: ValidationPath::from_field("track_name"),
min: 1usize,
actual: <str>::len(value.as_ref()),
});
}
}
{
let value = &self.track_name;
{
let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count();
if count > 2560usize {
return Err(ConstraintError::MaxGraphemes {
path: ValidationPath::from_field("track_name"),
max: 2560usize,
actual: count,
});
}
}
}
Ok(())
}
}
pub mod play_state {
pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
#[allow(unused)]
use ::core::marker::PhantomData;
mod sealed {
pub trait Sealed {}
}
pub trait State: sealed::Sealed {
type TrackName;
}
pub struct Empty(());
impl sealed::Sealed for Empty {}
impl State for Empty {
type TrackName = Unset;
}
pub struct SetTrackName<St: State = Empty>(PhantomData<fn() -> St>);
impl<St: State> sealed::Sealed for SetTrackName<St> {}
impl<St: State> State for SetTrackName<St> {
type TrackName = Set<members::track_name>;
}
#[allow(non_camel_case_types)]
pub mod members {
pub struct track_name(());
}
}
pub struct PlayBuilder<S: BosStr, St: play_state::State> {
_state: PhantomData<fn() -> St>,
_fields: (
Option<Vec<S>>,
Option<Vec<S>>,
Option<Vec<Artist<S>>>,
Option<i64>,
Option<S>,
Option<S>,
Option<S>,
Option<Datetime>,
Option<S>,
Option<S>,
Option<S>,
Option<S>,
Option<S>,
Option<S>,
Option<S>,
Option<S>,
),
_type: PhantomData<fn() -> S>,
}
impl<S: BosStr> Play<S> {
pub fn new() -> PlayBuilder<S, play_state::Empty> {
PlayBuilder::new()
}
}
impl<S: BosStr> PlayBuilder<S, play_state::Empty> {
pub fn new() -> Self {
PlayBuilder {
_state: PhantomData,
_fields: (
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
),
_type: PhantomData,
}
}
}
impl<S: BosStr, St: play_state::State> PlayBuilder<S, St> {
pub fn artist_mb_ids(mut self, value: impl Into<Option<Vec<S>>>) -> Self {
self._fields.0 = value.into();
self
}
pub fn maybe_artist_mb_ids(mut self, value: Option<Vec<S>>) -> Self {
self._fields.0 = value;
self
}
}
impl<S: BosStr, St: play_state::State> PlayBuilder<S, St> {
pub fn artist_names(mut self, value: impl Into<Option<Vec<S>>>) -> Self {
self._fields.1 = value.into();
self
}
pub fn maybe_artist_names(mut self, value: Option<Vec<S>>) -> Self {
self._fields.1 = value;
self
}
}
impl<S: BosStr, St: play_state::State> PlayBuilder<S, St> {
pub fn artists(mut self, value: impl Into<Option<Vec<Artist<S>>>>) -> Self {
self._fields.2 = value.into();
self
}
pub fn maybe_artists(mut self, value: Option<Vec<Artist<S>>>) -> Self {
self._fields.2 = value;
self
}
}
impl<S: BosStr, St: play_state::State> PlayBuilder<S, St> {
pub fn duration(mut self, value: impl Into<Option<i64>>) -> Self {
self._fields.3 = value.into();
self
}
pub fn maybe_duration(mut self, value: Option<i64>) -> Self {
self._fields.3 = value;
self
}
}
impl<S: BosStr, St: play_state::State> PlayBuilder<S, St> {
pub fn isrc(mut self, value: impl Into<Option<S>>) -> Self {
self._fields.4 = value.into();
self
}
pub fn maybe_isrc(mut self, value: Option<S>) -> Self {
self._fields.4 = value;
self
}
}
impl<S: BosStr, St: play_state::State> PlayBuilder<S, St> {
pub fn music_service_base_domain(mut self, value: impl Into<Option<S>>) -> Self {
self._fields.5 = value.into();
self
}
pub fn maybe_music_service_base_domain(mut self, value: Option<S>) -> Self {
self._fields.5 = value;
self
}
}
impl<S: BosStr, St: play_state::State> PlayBuilder<S, St> {
pub fn origin_url(mut self, value: impl Into<Option<S>>) -> Self {
self._fields.6 = value.into();
self
}
pub fn maybe_origin_url(mut self, value: Option<S>) -> Self {
self._fields.6 = value;
self
}
}
impl<S: BosStr, St: play_state::State> PlayBuilder<S, St> {
pub fn played_time(mut self, value: impl Into<Option<Datetime>>) -> Self {
self._fields.7 = value.into();
self
}
pub fn maybe_played_time(mut self, value: Option<Datetime>) -> Self {
self._fields.7 = value;
self
}
}
impl<S: BosStr, St: play_state::State> PlayBuilder<S, St> {
pub fn recording_mb_id(mut self, value: impl Into<Option<S>>) -> Self {
self._fields.8 = value.into();
self
}
pub fn maybe_recording_mb_id(mut self, value: Option<S>) -> Self {
self._fields.8 = value;
self
}
}
impl<S: BosStr, St: play_state::State> PlayBuilder<S, St> {
pub fn release_discriminant(mut self, value: impl Into<Option<S>>) -> Self {
self._fields.9 = value.into();
self
}
pub fn maybe_release_discriminant(mut self, value: Option<S>) -> Self {
self._fields.9 = value;
self
}
}
impl<S: BosStr, St: play_state::State> PlayBuilder<S, St> {
pub fn release_mb_id(mut self, value: impl Into<Option<S>>) -> Self {
self._fields.10 = value.into();
self
}
pub fn maybe_release_mb_id(mut self, value: Option<S>) -> Self {
self._fields.10 = value;
self
}
}
impl<S: BosStr, St: play_state::State> PlayBuilder<S, St> {
pub fn release_name(mut self, value: impl Into<Option<S>>) -> Self {
self._fields.11 = value.into();
self
}
pub fn maybe_release_name(mut self, value: Option<S>) -> Self {
self._fields.11 = value;
self
}
}
impl<S: BosStr, St: play_state::State> PlayBuilder<S, St> {
pub fn submission_client_agent(mut self, value: impl Into<Option<S>>) -> Self {
self._fields.12 = value.into();
self
}
pub fn maybe_submission_client_agent(mut self, value: Option<S>) -> Self {
self._fields.12 = value;
self
}
}
impl<S: BosStr, St: play_state::State> PlayBuilder<S, St> {
pub fn track_discriminant(mut self, value: impl Into<Option<S>>) -> Self {
self._fields.13 = value.into();
self
}
pub fn maybe_track_discriminant(mut self, value: Option<S>) -> Self {
self._fields.13 = value;
self
}
}
impl<S: BosStr, St: play_state::State> PlayBuilder<S, St> {
pub fn track_mb_id(mut self, value: impl Into<Option<S>>) -> Self {
self._fields.14 = value.into();
self
}
pub fn maybe_track_mb_id(mut self, value: Option<S>) -> Self {
self._fields.14 = value;
self
}
}
impl<S: BosStr, St> PlayBuilder<S, St>
where
St: play_state::State,
St::TrackName: play_state::IsUnset,
{
pub fn track_name(
mut self,
value: impl Into<S>,
) -> PlayBuilder<S, play_state::SetTrackName<St>> {
self._fields.15 = Option::Some(value.into());
PlayBuilder {
_state: PhantomData,
_fields: self._fields,
_type: PhantomData,
}
}
}
impl<S: BosStr, St> PlayBuilder<S, St>
where
St: play_state::State,
St::TrackName: play_state::IsSet,
{
pub fn build(self) -> Play<S> {
Play {
artist_mb_ids: self._fields.0,
artist_names: self._fields.1,
artists: self._fields.2,
duration: self._fields.3,
isrc: self._fields.4,
music_service_base_domain: self._fields.5,
origin_url: self._fields.6,
played_time: self._fields.7,
recording_mb_id: self._fields.8,
release_discriminant: self._fields.9,
release_mb_id: self._fields.10,
release_name: self._fields.11,
submission_client_agent: self._fields.12,
track_discriminant: self._fields.13,
track_mb_id: self._fields.14,
track_name: self._fields.15.unwrap(),
extra_data: Default::default(),
}
}
pub fn build_with_data(self, extra_data: BTreeMap<SmolStr, Data<S>>) -> Play<S> {
Play {
artist_mb_ids: self._fields.0,
artist_names: self._fields.1,
artists: self._fields.2,
duration: self._fields.3,
isrc: self._fields.4,
music_service_base_domain: self._fields.5,
origin_url: self._fields.6,
played_time: self._fields.7,
recording_mb_id: self._fields.8,
release_discriminant: self._fields.9,
release_mb_id: self._fields.10,
release_name: self._fields.11,
submission_client_agent: self._fields.12,
track_discriminant: self._fields.13,
track_mb_id: self._fields.14,
track_name: self._fields.15.unwrap(),
extra_data: Some(extra_data),
}
}
}
fn lexicon_doc_fm_teal_alpha_feed_play() -> LexiconDoc<'static> {
#[allow(unused_imports)]
use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType};
use jacquard_lexicon::lexicon::*;
use alloc::collections::BTreeMap;
LexiconDoc {
lexicon: Lexicon::Lexicon1,
id: CowStr::new_static("fm.teal.alpha.feed.play"),
defs: {
let mut map = BTreeMap::new();
map.insert(
SmolStr::new_static("main"),
LexUserType::Record(LexRecord {
key: Some(CowStr::new_static("tid")),
record: LexRecordRecord::Object(LexObject {
required: Some(vec![SmolStr::new_static("trackName")]),
properties: {
#[allow(unused_mut)]
let mut map = BTreeMap::new();
map.insert(
SmolStr::new_static("artistMbIds"),
LexObjectProperty::Array(LexArray {
description: Some(
CowStr::new_static(
"Array of Musicbrainz artist IDs. Prefer using 'artists'.",
),
),
items: LexArrayItem::String(LexString {
..Default::default()
}),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("artistNames"),
LexObjectProperty::Array(LexArray {
description: Some(
CowStr::new_static(
"Array of artist names in order of original appearance. Prefer using 'artists'.",
),
),
items: LexArrayItem::String(LexString {
min_length: Some(1usize),
max_length: Some(256usize),
max_graphemes: Some(2560usize),
..Default::default()
}),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("artists"),
LexObjectProperty::Array(LexArray {
description: Some(
CowStr::new_static(
"Array of artists in order of original appearance.",
),
),
items: LexArrayItem::Ref(LexRef {
r#ref: CowStr::new_static("fm.teal.alpha.feed.defs#artist"),
..Default::default()
}),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("duration"),
LexObjectProperty::Integer(LexInteger {
..Default::default()
}),
);
map.insert(
SmolStr::new_static("isrc"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static(
"The ISRC code associated with the recording",
),
),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("musicServiceBaseDomain"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static(
"The base domain of the music service. e.g. music.apple.com, tidal.com, spotify.com. Defaults to 'local' if unavailable or not provided.",
),
),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("originUrl"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static("The URL associated with this track"),
),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("playedTime"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static(
"The unix timestamp of when the track was played",
),
),
format: Some(LexStringFormat::Datetime),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("recordingMbId"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static(
"The Musicbrainz recording ID of the track",
),
),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("releaseDiscriminant"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static(
"Distinguishing information for release variants (e.g. 'Deluxe Edition', 'Remastered', '2023 Remaster', 'Special Edition'). Used to differentiate between different versions of the same base release while maintaining grouping capabilities.",
),
),
max_length: Some(128usize),
max_graphemes: Some(1280usize),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("releaseMbId"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static("The Musicbrainz release ID"),
),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("releaseName"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static("The name of the release/album"),
),
max_length: Some(256usize),
max_graphemes: Some(2560usize),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("submissionClientAgent"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static(
"A metadata string specifying the user agent where the format is `<app-identifier>/<version> (<kernel/OS-base>; <platform/OS-version>; <device-model>)`. If string is provided, only `app-identifier` and `version` are required. `app-identifier` is recommended to be in reverse dns format. Defaults to 'manual/unknown' if unavailable or not provided.",
),
),
max_length: Some(256usize),
max_graphemes: Some(2560usize),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("trackDiscriminant"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static(
"Distinguishing information for track variants (e.g. 'Acoustic Version', 'Live at Wembley', 'Radio Edit', 'Demo'). Used to differentiate between different versions of the same base track while maintaining grouping capabilities.",
),
),
max_length: Some(128usize),
max_graphemes: Some(1280usize),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("trackMbId"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static("The Musicbrainz ID of the track"),
),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("trackName"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static("The name of the track"),
),
min_length: Some(1usize),
max_length: Some(256usize),
max_graphemes: Some(2560usize),
..Default::default()
}),
);
map
},
..Default::default()
}),
..Default::default()
}),
);
map
},
..Default::default()
}
}