// @generated by jacquard-lexicon. DO NOT EDIT.
//
// Lexicon: fm.teal.alpha.feed.play
//
// This file was automatically generated from Lexicon schemas.
// Any manual changes will be overwritten on the next regeneration.

#[allow(unused_imports)]
use alloc::collections::BTreeMap;

#[allow(unused_imports)]
use core::marker::PhantomData;
use jacquard_common::CowStr;

#[allow(unused_imports)]
use jacquard_common::deps::codegen::unicode_segmentation::UnicodeSegmentation;
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::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;

#[lexicon]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(rename_all = "camelCase")]
pub struct Play<'a> {
    ///Array of Musicbrainz artist IDs. Prefer using 'artists'.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(borrow)]
    pub artist_mb_ids: Option<Vec<CowStr<'a>>>,
    ///Array of artist names in order of original appearance. Prefer using 'artists'.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(borrow)]
    pub artist_names: Option<Vec<CowStr<'a>>>,
    ///Array of artists in order of original appearance.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(borrow)]
    pub artists: Option<Vec<Artist<'a>>>,
    ///The length of the track in seconds
    #[serde(skip_serializing_if = "Option::is_none")]
    pub duration: Option<i64>,
    ///The ISRC code associated with the recording
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(borrow)]
    pub isrc: Option<CowStr<'a>>,
    ///The base domain of the music service. e.g. music.apple.com, tidal.com, spotify.com. Defaults to 'local' if unavailable or not provided.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(borrow)]
    pub music_service_base_domain: Option<CowStr<'a>>,
    ///The URL associated with this track
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(borrow)]
    pub origin_url: Option<CowStr<'a>>,
    ///The unix timestamp of when the track was played
    #[serde(skip_serializing_if = "Option::is_none")]
    pub played_time: Option<Datetime>,
    ///The Musicbrainz recording ID of the track
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(borrow)]
    pub recording_mb_id: Option<CowStr<'a>>,
    ///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.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(borrow)]
    pub release_discriminant: Option<CowStr<'a>>,
    ///The Musicbrainz release ID
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(borrow)]
    pub release_mb_id: Option<CowStr<'a>>,
    ///The name of the release/album
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(borrow)]
    pub release_name: Option<CowStr<'a>>,
    ///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.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(borrow)]
    pub submission_client_agent: Option<CowStr<'a>>,
    ///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.
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(borrow)]
    pub track_discriminant: Option<CowStr<'a>>,
    ///The Musicbrainz ID of the track
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(borrow)]
    pub track_mb_id: Option<CowStr<'a>>,
    ///The name of the track
    #[serde(borrow)]
    pub track_name: CowStr<'a>,
}

/// Typed wrapper for GetRecord response with this collection's record type.

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(rename_all = "camelCase")]
pub struct PlayGetRecordOutput<'a> {
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(borrow)]
    pub cid: Option<Cid<'a>>,
    #[serde(borrow)]
    pub uri: AtUri<'a>,
    #[serde(borrow)]
    pub value: Play<'a>,
}

impl<'a> Play<'a> {
    pub fn uri(
        uri: impl Into<CowStr<'a>>,
    ) -> Result<RecordUri<'a, PlayRecord>, UriError> {
        RecordUri::try_from_uri(AtUri::new_cow(uri.into())?)
    }
}

/// Marker type for deserializing records from this collection.

#[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<'de> = PlayGetRecordOutput<'de>;
    type Err<'de> = RecordError<'de>;
}

impl From<PlayGetRecordOutput<'_>> for Play<'_> {
    fn from(output: PlayGetRecordOutput<'_>) -> Self {
        use jacquard_common::IntoStatic;
        output.value.into_static()
    }
}

impl Collection for Play<'_> {
    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<'a> LexiconSchema for Play<'a> {
    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 {}
    }
    /// State trait tracking which required fields have been set
    pub trait State: sealed::Sealed {
        type TrackName;
    }
    /// Empty state - all required fields are unset
    pub struct Empty(());
    impl sealed::Sealed for Empty {}
    impl State for Empty {
        type TrackName = Unset;
    }
    ///State transition - sets the `track_name` field to Set
    pub struct SetTrackName<S: State = Empty>(PhantomData<fn() -> S>);
    impl<S: State> sealed::Sealed for SetTrackName<S> {}
    impl<S: State> State for SetTrackName<S> {
        type TrackName = Set<members::track_name>;
    }
    /// Marker types for field names
    #[allow(non_camel_case_types)]
    pub mod members {
        ///Marker type for the `track_name` field
        pub struct track_name(());
    }
}

/// Builder for constructing an instance of this type
pub struct PlayBuilder<'a, S: play_state::State> {
    _state: PhantomData<fn() -> S>,
    _fields: (
        Option<Vec<CowStr<'a>>>,
        Option<Vec<CowStr<'a>>>,
        Option<Vec<Artist<'a>>>,
        Option<i64>,
        Option<CowStr<'a>>,
        Option<CowStr<'a>>,
        Option<CowStr<'a>>,
        Option<Datetime>,
        Option<CowStr<'a>>,
        Option<CowStr<'a>>,
        Option<CowStr<'a>>,
        Option<CowStr<'a>>,
        Option<CowStr<'a>>,
        Option<CowStr<'a>>,
        Option<CowStr<'a>>,
        Option<CowStr<'a>>,
    ),
    _lifetime: PhantomData<&'a ()>,
}

impl<'a> Play<'a> {
    /// Create a new builder for this type
    pub fn new() -> PlayBuilder<'a, play_state::Empty> {
        PlayBuilder::new()
    }
}

impl<'a> PlayBuilder<'a, play_state::Empty> {
    /// Create a new builder with all fields unset
    pub fn new() -> Self {
        PlayBuilder {
            _state: PhantomData,
            _fields: (
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                None,
                None,
            ),
            _lifetime: PhantomData,
        }
    }
}

impl<'a, S: play_state::State> PlayBuilder<'a, S> {
    /// Set the `artistMbIds` field (optional)
    pub fn artist_mb_ids(mut self, value: impl Into<Option<Vec<CowStr<'a>>>>) -> Self {
        self._fields.0 = value.into();
        self
    }
    /// Set the `artistMbIds` field to an Option value (optional)
    pub fn maybe_artist_mb_ids(mut self, value: Option<Vec<CowStr<'a>>>) -> Self {
        self._fields.0 = value;
        self
    }
}

impl<'a, S: play_state::State> PlayBuilder<'a, S> {
    /// Set the `artistNames` field (optional)
    pub fn artist_names(mut self, value: impl Into<Option<Vec<CowStr<'a>>>>) -> Self {
        self._fields.1 = value.into();
        self
    }
    /// Set the `artistNames` field to an Option value (optional)
    pub fn maybe_artist_names(mut self, value: Option<Vec<CowStr<'a>>>) -> Self {
        self._fields.1 = value;
        self
    }
}

impl<'a, S: play_state::State> PlayBuilder<'a, S> {
    /// Set the `artists` field (optional)
    pub fn artists(mut self, value: impl Into<Option<Vec<Artist<'a>>>>) -> Self {
        self._fields.2 = value.into();
        self
    }
    /// Set the `artists` field to an Option value (optional)
    pub fn maybe_artists(mut self, value: Option<Vec<Artist<'a>>>) -> Self {
        self._fields.2 = value;
        self
    }
}

impl<'a, S: play_state::State> PlayBuilder<'a, S> {
    /// Set the `duration` field (optional)
    pub fn duration(mut self, value: impl Into<Option<i64>>) -> Self {
        self._fields.3 = value.into();
        self
    }
    /// Set the `duration` field to an Option value (optional)
    pub fn maybe_duration(mut self, value: Option<i64>) -> Self {
        self._fields.3 = value;
        self
    }
}

impl<'a, S: play_state::State> PlayBuilder<'a, S> {
    /// Set the `isrc` field (optional)
    pub fn isrc(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
        self._fields.4 = value.into();
        self
    }
    /// Set the `isrc` field to an Option value (optional)
    pub fn maybe_isrc(mut self, value: Option<CowStr<'a>>) -> Self {
        self._fields.4 = value;
        self
    }
}

impl<'a, S: play_state::State> PlayBuilder<'a, S> {
    /// Set the `musicServiceBaseDomain` field (optional)
    pub fn music_service_base_domain(
        mut self,
        value: impl Into<Option<CowStr<'a>>>,
    ) -> Self {
        self._fields.5 = value.into();
        self
    }
    /// Set the `musicServiceBaseDomain` field to an Option value (optional)
    pub fn maybe_music_service_base_domain(mut self, value: Option<CowStr<'a>>) -> Self {
        self._fields.5 = value;
        self
    }
}

impl<'a, S: play_state::State> PlayBuilder<'a, S> {
    /// Set the `originUrl` field (optional)
    pub fn origin_url(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
        self._fields.6 = value.into();
        self
    }
    /// Set the `originUrl` field to an Option value (optional)
    pub fn maybe_origin_url(mut self, value: Option<CowStr<'a>>) -> Self {
        self._fields.6 = value;
        self
    }
}

impl<'a, S: play_state::State> PlayBuilder<'a, S> {
    /// Set the `playedTime` field (optional)
    pub fn played_time(mut self, value: impl Into<Option<Datetime>>) -> Self {
        self._fields.7 = value.into();
        self
    }
    /// Set the `playedTime` field to an Option value (optional)
    pub fn maybe_played_time(mut self, value: Option<Datetime>) -> Self {
        self._fields.7 = value;
        self
    }
}

impl<'a, S: play_state::State> PlayBuilder<'a, S> {
    /// Set the `recordingMbId` field (optional)
    pub fn recording_mb_id(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
        self._fields.8 = value.into();
        self
    }
    /// Set the `recordingMbId` field to an Option value (optional)
    pub fn maybe_recording_mb_id(mut self, value: Option<CowStr<'a>>) -> Self {
        self._fields.8 = value;
        self
    }
}

impl<'a, S: play_state::State> PlayBuilder<'a, S> {
    /// Set the `releaseDiscriminant` field (optional)
    pub fn release_discriminant(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
        self._fields.9 = value.into();
        self
    }
    /// Set the `releaseDiscriminant` field to an Option value (optional)
    pub fn maybe_release_discriminant(mut self, value: Option<CowStr<'a>>) -> Self {
        self._fields.9 = value;
        self
    }
}

impl<'a, S: play_state::State> PlayBuilder<'a, S> {
    /// Set the `releaseMbId` field (optional)
    pub fn release_mb_id(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
        self._fields.10 = value.into();
        self
    }
    /// Set the `releaseMbId` field to an Option value (optional)
    pub fn maybe_release_mb_id(mut self, value: Option<CowStr<'a>>) -> Self {
        self._fields.10 = value;
        self
    }
}

impl<'a, S: play_state::State> PlayBuilder<'a, S> {
    /// Set the `releaseName` field (optional)
    pub fn release_name(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
        self._fields.11 = value.into();
        self
    }
    /// Set the `releaseName` field to an Option value (optional)
    pub fn maybe_release_name(mut self, value: Option<CowStr<'a>>) -> Self {
        self._fields.11 = value;
        self
    }
}

impl<'a, S: play_state::State> PlayBuilder<'a, S> {
    /// Set the `submissionClientAgent` field (optional)
    pub fn submission_client_agent(
        mut self,
        value: impl Into<Option<CowStr<'a>>>,
    ) -> Self {
        self._fields.12 = value.into();
        self
    }
    /// Set the `submissionClientAgent` field to an Option value (optional)
    pub fn maybe_submission_client_agent(mut self, value: Option<CowStr<'a>>) -> Self {
        self._fields.12 = value;
        self
    }
}

impl<'a, S: play_state::State> PlayBuilder<'a, S> {
    /// Set the `trackDiscriminant` field (optional)
    pub fn track_discriminant(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
        self._fields.13 = value.into();
        self
    }
    /// Set the `trackDiscriminant` field to an Option value (optional)
    pub fn maybe_track_discriminant(mut self, value: Option<CowStr<'a>>) -> Self {
        self._fields.13 = value;
        self
    }
}

impl<'a, S: play_state::State> PlayBuilder<'a, S> {
    /// Set the `trackMbId` field (optional)
    pub fn track_mb_id(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
        self._fields.14 = value.into();
        self
    }
    /// Set the `trackMbId` field to an Option value (optional)
    pub fn maybe_track_mb_id(mut self, value: Option<CowStr<'a>>) -> Self {
        self._fields.14 = value;
        self
    }
}

impl<'a, S> PlayBuilder<'a, S>
where
    S: play_state::State,
    S::TrackName: play_state::IsUnset,
{
    /// Set the `trackName` field (required)
    pub fn track_name(
        mut self,
        value: impl Into<CowStr<'a>>,
    ) -> PlayBuilder<'a, play_state::SetTrackName<S>> {
        self._fields.15 = Option::Some(value.into());
        PlayBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _lifetime: PhantomData,
        }
    }
}

impl<'a, S> PlayBuilder<'a, S>
where
    S: play_state::State,
    S::TrackName: play_state::IsSet,
{
    /// Build the final struct
    pub fn build(self) -> Play<'a> {
        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(),
        }
    }
    /// Build the final struct with custom extra_data
    pub fn build_with_data(
        self,
        extra_data: BTreeMap<
            jacquard_common::deps::smol_str::SmolStr,
            jacquard_common::types::value::Data<'a>,
        >,
    ) -> Play<'a> {
        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()
    }
}