···11+{
22+ "lexicon": 1,
33+ "id": "fm.teal.alpha.actor.status",
44+ "defs": {
55+ "main": {
66+ "type": "record",
77+ "description": "This lexicon is in a not officially released state. It is subject to change. | A declaration of the status of the actor. Only one can be shown at a time. If there are multiple, the latest record should be picked and earlier records should be deleted or tombstoned.",
88+ "key": "literal:self",
99+ "record": {
1010+ "type": "object",
1111+ "required": [
1212+ "time",
1313+ "item"
1414+ ],
1515+ "properties": {
1616+ "expiry": {
1717+ "type": "string",
1818+ "description": "The unix timestamp of the expiry time of the item. If unavailable, default to 10 minutes past the start time.",
1919+ "format": "datetime"
2020+ },
2121+ "item": {
2222+ "type": "ref",
2323+ "ref": "fm.teal.alpha.feed.defs#playView"
2424+ },
2525+ "time": {
2626+ "type": "string",
2727+ "description": "The unix timestamp of when the item was recorded",
2828+ "format": "datetime"
2929+ }
3030+ }
3131+ }
3232+ }
3333+ }
3434+}
···11+{
22+ "lexicon": 1,
33+ "id": "fm.teal.alpha.feed.play",
44+ "description": "This lexicon is in a not officially released state. It is subject to change. | A declaration of a teal.fm play. Plays are submitted as a result of a user listening to a track. Plays should be marked as tracked when a user has listened to the entire track if it's under 2 minutes long, or half of the track's duration up to 4 minutes, whichever is longest.",
55+ "defs": {
66+ "main": {
77+ "type": "record",
88+ "key": "tid",
99+ "record": {
1010+ "type": "object",
1111+ "required": [
1212+ "trackName"
1313+ ],
1414+ "properties": {
1515+ "artistMbIds": {
1616+ "type": "array",
1717+ "description": "Array of Musicbrainz artist IDs. Prefer using 'artists'.",
1818+ "items": {
1919+ "type": "string"
2020+ }
2121+ },
2222+ "artistNames": {
2323+ "type": "array",
2424+ "description": "Array of artist names in order of original appearance. Prefer using 'artists'.",
2525+ "items": {
2626+ "type": "string",
2727+ "minLength": 1,
2828+ "maxLength": 256,
2929+ "maxGraphemes": 2560
3030+ }
3131+ },
3232+ "artists": {
3333+ "type": "array",
3434+ "description": "Array of artists in order of original appearance.",
3535+ "items": {
3636+ "type": "ref",
3737+ "ref": "fm.teal.alpha.feed.defs#artist"
3838+ }
3939+ },
4040+ "duration": {
4141+ "type": "integer",
4242+ "description": "The length of the track in seconds"
4343+ },
4444+ "isrc": {
4545+ "type": "string",
4646+ "description": "The ISRC code associated with the recording"
4747+ },
4848+ "musicServiceBaseDomain": {
4949+ "type": "string",
5050+ "description": "The base domain of the music service. e.g. music.apple.com, tidal.com, spotify.com. Defaults to 'local' if unavailable or not provided."
5151+ },
5252+ "originUrl": {
5353+ "type": "string",
5454+ "description": "The URL associated with this track"
5555+ },
5656+ "playedTime": {
5757+ "type": "string",
5858+ "description": "The unix timestamp of when the track was played",
5959+ "format": "datetime"
6060+ },
6161+ "recordingMbId": {
6262+ "type": "string",
6363+ "description": "The Musicbrainz recording ID of the track"
6464+ },
6565+ "releaseDiscriminant": {
6666+ "type": "string",
6767+ "description": "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.",
6868+ "maxLength": 128,
6969+ "maxGraphemes": 1280
7070+ },
7171+ "releaseMbId": {
7272+ "type": "string",
7373+ "description": "The Musicbrainz release ID"
7474+ },
7575+ "releaseName": {
7676+ "type": "string",
7777+ "description": "The name of the release/album",
7878+ "maxLength": 256,
7979+ "maxGraphemes": 2560
8080+ },
8181+ "submissionClientAgent": {
8282+ "type": "string",
8383+ "description": "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.",
8484+ "maxLength": 256,
8585+ "maxGraphemes": 2560
8686+ },
8787+ "trackDiscriminant": {
8888+ "type": "string",
8989+ "description": "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.",
9090+ "maxLength": 128,
9191+ "maxGraphemes": 1280
9292+ },
9393+ "trackMbId": {
9494+ "type": "string",
9595+ "description": "The Musicbrainz ID of the track"
9696+ },
9797+ "trackName": {
9898+ "type": "string",
9999+ "description": "The name of the track",
100100+ "minLength": 1,
101101+ "maxLength": 256,
102102+ "maxGraphemes": 2560
103103+ }
104104+ }
105105+ }
106106+ }
107107+ }
108108+}
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// This file was automatically generated from Lexicon schemas.
44+// Any manual changes will be overwritten on the next regeneration.
55+66+pub mod alpha;
+8
crates/jacquard-api/src/fm_teal/alpha.rs
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// This file was automatically generated from Lexicon schemas.
44+// Any manual changes will be overwritten on the next regeneration.
55+66+pub mod actor;
77+pub mod feed;
88+pub mod stats;
+118
crates/jacquard-api/src/fm_teal/alpha/actor.rs
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: fm.teal.alpha.actor.defs
44+//
55+// This file was automatically generated from Lexicon schemas.
66+// Any manual changes will be overwritten on the next regeneration.
77+88+pub mod get_profile;
99+pub mod get_profiles;
1010+pub mod profile;
1111+pub mod profile_status;
1212+pub mod search_actors;
1313+pub mod status;
1414+1515+#[jacquard_derive::lexicon]
1616+#[derive(
1717+ serde::Serialize,
1818+ serde::Deserialize,
1919+ Debug,
2020+ Clone,
2121+ PartialEq,
2222+ Eq,
2323+ jacquard_derive::IntoStatic,
2424+ Default
2525+)]
2626+#[serde(rename_all = "camelCase")]
2727+pub struct MiniProfileView<'a> {
2828+ /// IPLD of the avatar
2929+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3030+ #[serde(borrow)]
3131+ pub avatar: std::option::Option<jacquard_common::CowStr<'a>>,
3232+ /// The decentralized identifier of the actor
3333+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3434+ #[serde(borrow)]
3535+ pub did: std::option::Option<jacquard_common::CowStr<'a>>,
3636+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3737+ #[serde(borrow)]
3838+ pub display_name: std::option::Option<jacquard_common::CowStr<'a>>,
3939+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
4040+ #[serde(borrow)]
4141+ pub handle: std::option::Option<jacquard_common::CowStr<'a>>,
4242+}
4343+4444+#[jacquard_derive::lexicon]
4545+#[derive(
4646+ serde::Serialize,
4747+ serde::Deserialize,
4848+ Debug,
4949+ Clone,
5050+ PartialEq,
5151+ Eq,
5252+ jacquard_derive::IntoStatic,
5353+ Default
5454+)]
5555+#[serde(rename_all = "camelCase")]
5656+pub struct ProfileView<'a> {
5757+ /// IPLD of the avatar
5858+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5959+ #[serde(borrow)]
6060+ pub avatar: std::option::Option<jacquard_common::CowStr<'a>>,
6161+ /// IPLD of the banner image
6262+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
6363+ #[serde(borrow)]
6464+ pub banner: std::option::Option<jacquard_common::CowStr<'a>>,
6565+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
6666+ pub created_at: std::option::Option<jacquard_common::types::string::Datetime>,
6767+ /// Free-form profile description text.
6868+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
6969+ #[serde(borrow)]
7070+ pub description: std::option::Option<jacquard_common::CowStr<'a>>,
7171+ /// Annotations of text in the profile description (mentions, URLs, hashtags, etc). May be changed to another (backwards compatible) lexicon.
7272+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
7373+ #[serde(borrow)]
7474+ pub description_facets: std::option::Option<
7575+ Vec<crate::app_bsky::richtext::facet::Facet<'a>>,
7676+ >,
7777+ /// The decentralized identifier of the actor
7878+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
7979+ #[serde(borrow)]
8080+ pub did: std::option::Option<jacquard_common::CowStr<'a>>,
8181+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
8282+ #[serde(borrow)]
8383+ pub display_name: std::option::Option<jacquard_common::CowStr<'a>>,
8484+ /// The user's most recent item featured on their profile.
8585+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
8686+ #[serde(borrow)]
8787+ pub featured_item: std::option::Option<
8888+ crate::fm_teal::alpha::actor::profile::FeaturedItem<'a>,
8989+ >,
9090+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
9191+ #[serde(borrow)]
9292+ pub status: std::option::Option<crate::fm_teal::alpha::actor::StatusView<'a>>,
9393+}
9494+9595+/// A declaration of the status of the actor.
9696+#[jacquard_derive::lexicon]
9797+#[derive(
9898+ serde::Serialize,
9999+ serde::Deserialize,
100100+ Debug,
101101+ Clone,
102102+ PartialEq,
103103+ Eq,
104104+ jacquard_derive::IntoStatic,
105105+ Default
106106+)]
107107+#[serde(rename_all = "camelCase")]
108108+pub struct StatusView<'a> {
109109+ /// The unix timestamp of the expiry time of the item. If unavailable, default to 10 minutes past the start time.
110110+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
111111+ pub expiry: std::option::Option<jacquard_common::types::string::Datetime>,
112112+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
113113+ #[serde(borrow)]
114114+ pub item: std::option::Option<crate::fm_teal::alpha::feed::PlayView<'a>>,
115115+ /// The unix timestamp of when the item was recorded
116116+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
117117+ pub time: std::option::Option<jacquard_common::types::string::Datetime>,
118118+}
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: fm.teal.alpha.actor.status
44+//
55+// This file was automatically generated from Lexicon schemas.
66+// Any manual changes will be overwritten on the next regeneration.
77+88+/// This lexicon is in a not officially released state. It is subject to change. | A declaration of the status of the actor. Only one can be shown at a time. If there are multiple, the latest record should be picked and earlier records should be deleted or tombstoned.
99+#[jacquard_derive::lexicon]
1010+#[derive(
1111+ serde::Serialize,
1212+ serde::Deserialize,
1313+ Debug,
1414+ Clone,
1515+ PartialEq,
1616+ Eq,
1717+ jacquard_derive::IntoStatic,
1818+ bon::Builder
1919+)]
2020+#[serde(rename_all = "camelCase")]
2121+pub struct Status<'a> {
2222+ /// The unix timestamp of the expiry time of the item. If unavailable, default to 10 minutes past the start time.
2323+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2424+ #[builder(into)]
2525+ pub expiry: Option<jacquard_common::types::string::Datetime>,
2626+ #[serde(borrow)]
2727+ pub item: crate::fm_teal::alpha::feed::PlayView<'a>,
2828+ /// The unix timestamp of when the item was recorded
2929+ pub time: jacquard_common::types::string::Datetime,
3030+}
3131+3232+impl<'a> Status<'a> {
3333+ pub fn uri(
3434+ uri: impl Into<jacquard_common::CowStr<'a>>,
3535+ ) -> Result<
3636+ jacquard_common::types::uri::RecordUri<'a, StatusRecord>,
3737+ jacquard_common::types::uri::UriError,
3838+ > {
3939+ jacquard_common::types::uri::RecordUri::try_from_uri(
4040+ jacquard_common::types::string::AtUri::new_cow(uri.into())?,
4141+ )
4242+ }
4343+}
4444+4545+/// Typed wrapper for GetRecord response with this collection's record type.
4646+#[derive(
4747+ serde::Serialize,
4848+ serde::Deserialize,
4949+ Debug,
5050+ Clone,
5151+ PartialEq,
5252+ Eq,
5353+ jacquard_derive::IntoStatic
5454+)]
5555+#[serde(rename_all = "camelCase")]
5656+pub struct StatusGetRecordOutput<'a> {
5757+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5858+ #[serde(borrow)]
5959+ pub cid: std::option::Option<jacquard_common::types::string::Cid<'a>>,
6060+ #[serde(borrow)]
6161+ pub uri: jacquard_common::types::string::AtUri<'a>,
6262+ #[serde(borrow)]
6363+ pub value: Status<'a>,
6464+}
6565+6666+impl From<StatusGetRecordOutput<'_>> for Status<'_> {
6767+ fn from(output: StatusGetRecordOutput<'_>) -> Self {
6868+ use jacquard_common::IntoStatic;
6969+ output.value.into_static()
7070+ }
7171+}
7272+7373+impl jacquard_common::types::collection::Collection for Status<'_> {
7474+ const NSID: &'static str = "fm.teal.alpha.actor.status";
7575+ type Record = StatusRecord;
7676+}
7777+7878+/// Marker type for deserializing records from this collection.
7979+#[derive(Debug, serde::Serialize, serde::Deserialize)]
8080+pub struct StatusRecord;
8181+impl jacquard_common::xrpc::XrpcResp for StatusRecord {
8282+ const NSID: &'static str = "fm.teal.alpha.actor.status";
8383+ const ENCODING: &'static str = "application/json";
8484+ type Output<'de> = StatusGetRecordOutput<'de>;
8585+ type Err<'de> = jacquard_common::types::collection::RecordError<'de>;
8686+}
8787+8888+impl jacquard_common::types::collection::Collection for StatusRecord {
8989+ const NSID: &'static str = "fm.teal.alpha.actor.status";
9090+ type Record = StatusRecord;
9191+}
+102
crates/jacquard-api/src/fm_teal/alpha/feed.rs
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: fm.teal.alpha.feed.defs
44+//
55+// This file was automatically generated from Lexicon schemas.
66+// Any manual changes will be overwritten on the next regeneration.
77+88+pub mod get_actor_feed;
99+pub mod get_play;
1010+pub mod play;
1111+1212+#[jacquard_derive::lexicon]
1313+#[derive(
1414+ serde::Serialize,
1515+ serde::Deserialize,
1616+ Debug,
1717+ Clone,
1818+ PartialEq,
1919+ Eq,
2020+ jacquard_derive::IntoStatic,
2121+ Default
2222+)]
2323+#[serde(rename_all = "camelCase")]
2424+pub struct Artist<'a> {
2525+ /// The Musicbrainz ID of the artist
2626+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2727+ #[serde(borrow)]
2828+ pub artist_mb_id: std::option::Option<jacquard_common::CowStr<'a>>,
2929+ /// The name of the artist
3030+ #[serde(borrow)]
3131+ pub artist_name: jacquard_common::CowStr<'a>,
3232+}
3333+3434+#[jacquard_derive::lexicon]
3535+#[derive(
3636+ serde::Serialize,
3737+ serde::Deserialize,
3838+ Debug,
3939+ Clone,
4040+ PartialEq,
4141+ Eq,
4242+ jacquard_derive::IntoStatic,
4343+ bon::Builder
4444+)]
4545+#[serde(rename_all = "camelCase")]
4646+pub struct PlayView<'a> {
4747+ /// Array of artists in order of original appearance.
4848+ #[serde(borrow)]
4949+ pub artists: Vec<crate::fm_teal::alpha::feed::Artist<'a>>,
5050+ /// The length of the track in seconds
5151+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5252+ #[builder(into)]
5353+ pub duration: Option<i64>,
5454+ /// The ISRC code associated with the recording
5555+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5656+ #[builder(into)]
5757+ #[serde(borrow)]
5858+ pub isrc: Option<jacquard_common::CowStr<'a>>,
5959+ /// The base domain of the music service. e.g. music.apple.com, tidal.com, spotify.com. Defaults to 'local' if not provided.
6060+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
6161+ #[builder(into)]
6262+ #[serde(borrow)]
6363+ pub music_service_base_domain: Option<jacquard_common::CowStr<'a>>,
6464+ /// The URL associated with this track
6565+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
6666+ #[builder(into)]
6767+ #[serde(borrow)]
6868+ pub origin_url: Option<jacquard_common::CowStr<'a>>,
6969+ /// The unix timestamp of when the track was played
7070+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
7171+ #[builder(into)]
7272+ pub played_time: Option<jacquard_common::types::string::Datetime>,
7373+ /// The Musicbrainz recording ID of the track
7474+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
7575+ #[builder(into)]
7676+ #[serde(borrow)]
7777+ pub recording_mb_id: Option<jacquard_common::CowStr<'a>>,
7878+ /// The Musicbrainz release ID
7979+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
8080+ #[builder(into)]
8181+ #[serde(borrow)]
8282+ pub release_mb_id: Option<jacquard_common::CowStr<'a>>,
8383+ /// The name of the release/album
8484+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
8585+ #[builder(into)]
8686+ #[serde(borrow)]
8787+ pub release_name: Option<jacquard_common::CowStr<'a>>,
8888+ /// A user-agent style string specifying the user agent. e.g. tealtracker/0.0.1b (Linux; Android 13; SM-A715F). Defaults to 'manual/unknown' if not provided.
8989+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
9090+ #[builder(into)]
9191+ #[serde(borrow)]
9292+ pub submission_client_agent: Option<jacquard_common::CowStr<'a>>,
9393+ /// The Musicbrainz ID of the track
9494+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
9595+ #[builder(into)]
9696+ #[serde(borrow)]
9797+ pub track_mb_id: Option<jacquard_common::CowStr<'a>>,
9898+ /// The name of the track
9999+ #[serde(borrow)]
100100+ #[builder(into)]
101101+ pub track_name: jacquard_common::CowStr<'a>,
102102+}
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: fm.teal.alpha.feed.play
44+//
55+// This file was automatically generated from Lexicon schemas.
66+// Any manual changes will be overwritten on the next regeneration.
77+88+#[jacquard_derive::lexicon]
99+#[derive(
1010+ serde::Serialize,
1111+ serde::Deserialize,
1212+ Debug,
1313+ Clone,
1414+ PartialEq,
1515+ Eq,
1616+ jacquard_derive::IntoStatic,
1717+ bon::Builder
1818+)]
1919+#[serde(rename_all = "camelCase")]
2020+pub struct Play<'a> {
2121+ /// Array of Musicbrainz artist IDs. Prefer using 'artists'.
2222+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2323+ #[builder(into)]
2424+ #[serde(borrow)]
2525+ pub artist_mb_ids: Option<Vec<jacquard_common::CowStr<'a>>>,
2626+ /// Array of artist names in order of original appearance. Prefer using 'artists'.
2727+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2828+ #[builder(into)]
2929+ #[serde(borrow)]
3030+ pub artist_names: Option<Vec<jacquard_common::CowStr<'a>>>,
3131+ /// Array of artists in order of original appearance.
3232+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3333+ #[builder(into)]
3434+ #[serde(borrow)]
3535+ pub artists: Option<Vec<crate::fm_teal::alpha::feed::Artist<'a>>>,
3636+ /// The length of the track in seconds
3737+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3838+ #[builder(into)]
3939+ pub duration: Option<i64>,
4040+ /// The ISRC code associated with the recording
4141+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
4242+ #[builder(into)]
4343+ #[serde(borrow)]
4444+ pub isrc: Option<jacquard_common::CowStr<'a>>,
4545+ /// The base domain of the music service. e.g. music.apple.com, tidal.com, spotify.com. Defaults to 'local' if unavailable or not provided.
4646+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
4747+ #[builder(into)]
4848+ #[serde(borrow)]
4949+ pub music_service_base_domain: Option<jacquard_common::CowStr<'a>>,
5050+ /// The URL associated with this track
5151+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5252+ #[builder(into)]
5353+ #[serde(borrow)]
5454+ pub origin_url: Option<jacquard_common::CowStr<'a>>,
5555+ /// The unix timestamp of when the track was played
5656+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5757+ #[builder(into)]
5858+ pub played_time: Option<jacquard_common::types::string::Datetime>,
5959+ /// The Musicbrainz recording ID of the track
6060+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
6161+ #[builder(into)]
6262+ #[serde(borrow)]
6363+ pub recording_mb_id: Option<jacquard_common::CowStr<'a>>,
6464+ /// 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.
6565+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
6666+ #[builder(into)]
6767+ #[serde(borrow)]
6868+ pub release_discriminant: Option<jacquard_common::CowStr<'a>>,
6969+ /// The Musicbrainz release ID
7070+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
7171+ #[builder(into)]
7272+ #[serde(borrow)]
7373+ pub release_mb_id: Option<jacquard_common::CowStr<'a>>,
7474+ /// The name of the release/album
7575+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
7676+ #[builder(into)]
7777+ #[serde(borrow)]
7878+ pub release_name: Option<jacquard_common::CowStr<'a>>,
7979+ /// 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.
8080+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
8181+ #[builder(into)]
8282+ #[serde(borrow)]
8383+ pub submission_client_agent: Option<jacquard_common::CowStr<'a>>,
8484+ /// 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.
8585+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
8686+ #[builder(into)]
8787+ #[serde(borrow)]
8888+ pub track_discriminant: Option<jacquard_common::CowStr<'a>>,
8989+ /// The Musicbrainz ID of the track
9090+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
9191+ #[builder(into)]
9292+ #[serde(borrow)]
9393+ pub track_mb_id: Option<jacquard_common::CowStr<'a>>,
9494+ /// The name of the track
9595+ #[serde(borrow)]
9696+ #[builder(into)]
9797+ pub track_name: jacquard_common::CowStr<'a>,
9898+}
9999+100100+impl<'a> Play<'a> {
101101+ pub fn uri(
102102+ uri: impl Into<jacquard_common::CowStr<'a>>,
103103+ ) -> Result<
104104+ jacquard_common::types::uri::RecordUri<'a, PlayRecord>,
105105+ jacquard_common::types::uri::UriError,
106106+ > {
107107+ jacquard_common::types::uri::RecordUri::try_from_uri(
108108+ jacquard_common::types::string::AtUri::new_cow(uri.into())?,
109109+ )
110110+ }
111111+}
112112+113113+/// Typed wrapper for GetRecord response with this collection's record type.
114114+#[derive(
115115+ serde::Serialize,
116116+ serde::Deserialize,
117117+ Debug,
118118+ Clone,
119119+ PartialEq,
120120+ Eq,
121121+ jacquard_derive::IntoStatic
122122+)]
123123+#[serde(rename_all = "camelCase")]
124124+pub struct PlayGetRecordOutput<'a> {
125125+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
126126+ #[serde(borrow)]
127127+ pub cid: std::option::Option<jacquard_common::types::string::Cid<'a>>,
128128+ #[serde(borrow)]
129129+ pub uri: jacquard_common::types::string::AtUri<'a>,
130130+ #[serde(borrow)]
131131+ pub value: Play<'a>,
132132+}
133133+134134+impl From<PlayGetRecordOutput<'_>> for Play<'_> {
135135+ fn from(output: PlayGetRecordOutput<'_>) -> Self {
136136+ use jacquard_common::IntoStatic;
137137+ output.value.into_static()
138138+ }
139139+}
140140+141141+impl jacquard_common::types::collection::Collection for Play<'_> {
142142+ const NSID: &'static str = "fm.teal.alpha.feed.play";
143143+ type Record = PlayRecord;
144144+}
145145+146146+/// Marker type for deserializing records from this collection.
147147+#[derive(Debug, serde::Serialize, serde::Deserialize)]
148148+pub struct PlayRecord;
149149+impl jacquard_common::xrpc::XrpcResp for PlayRecord {
150150+ const NSID: &'static str = "fm.teal.alpha.feed.play";
151151+ const ENCODING: &'static str = "application/json";
152152+ type Output<'de> = PlayGetRecordOutput<'de>;
153153+ type Err<'de> = jacquard_common::types::collection::RecordError<'de>;
154154+}
155155+156156+impl jacquard_common::types::collection::Collection for PlayRecord {
157157+ const NSID: &'static str = "fm.teal.alpha.feed.play";
158158+ type Record = PlayRecord;
159159+}
+87
crates/jacquard-api/src/fm_teal/alpha/stats.rs
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: fm.teal.alpha.stats.defs
44+//
55+// This file was automatically generated from Lexicon schemas.
66+// Any manual changes will be overwritten on the next regeneration.
77+88+pub mod get_latest;
99+pub mod get_top_artists;
1010+pub mod get_top_releases;
1111+pub mod get_user_top_artists;
1212+pub mod get_user_top_releases;
1313+1414+#[jacquard_derive::lexicon]
1515+#[derive(
1616+ serde::Serialize,
1717+ serde::Deserialize,
1818+ Debug,
1919+ Clone,
2020+ PartialEq,
2121+ Eq,
2222+ jacquard_derive::IntoStatic,
2323+ bon::Builder
2424+)]
2525+#[serde(rename_all = "camelCase")]
2626+pub struct ArtistView<'a> {
2727+ /// MusicBrainz artist ID
2828+ #[serde(borrow)]
2929+ #[builder(into)]
3030+ pub mbid: jacquard_common::CowStr<'a>,
3131+ /// Artist name
3232+ #[serde(borrow)]
3333+ #[builder(into)]
3434+ pub name: jacquard_common::CowStr<'a>,
3535+ /// Total number of plays for this artist
3636+ pub play_count: i64,
3737+}
3838+3939+#[jacquard_derive::lexicon]
4040+#[derive(
4141+ serde::Serialize,
4242+ serde::Deserialize,
4343+ Debug,
4444+ Clone,
4545+ PartialEq,
4646+ Eq,
4747+ jacquard_derive::IntoStatic,
4848+ bon::Builder
4949+)]
5050+#[serde(rename_all = "camelCase")]
5151+pub struct RecordingView<'a> {
5252+ /// MusicBrainz recording ID
5353+ #[serde(borrow)]
5454+ #[builder(into)]
5555+ pub mbid: jacquard_common::CowStr<'a>,
5656+ /// Recording/track name
5757+ #[serde(borrow)]
5858+ #[builder(into)]
5959+ pub name: jacquard_common::CowStr<'a>,
6060+ /// Total number of plays for this recording
6161+ pub play_count: i64,
6262+}
6363+6464+#[jacquard_derive::lexicon]
6565+#[derive(
6666+ serde::Serialize,
6767+ serde::Deserialize,
6868+ Debug,
6969+ Clone,
7070+ PartialEq,
7171+ Eq,
7272+ jacquard_derive::IntoStatic,
7373+ bon::Builder
7474+)]
7575+#[serde(rename_all = "camelCase")]
7676+pub struct ReleaseView<'a> {
7777+ /// MusicBrainz release ID
7878+ #[serde(borrow)]
7979+ #[builder(into)]
8080+ pub mbid: jacquard_common::CowStr<'a>,
8181+ /// Release/album name
8282+ #[serde(borrow)]
8383+ #[builder(into)]
8484+ pub name: jacquard_common::CowStr<'a>,
8585+ /// Total number of plays for this release
8686+ pub play_count: i64,
8787+}