···11+{
22+ "lexicon": 1,
33+ "id": "app.rocksky.actor.defs",
44+ "defs": {
55+ "profileViewBasic": {
66+ "type": "object",
77+ "properties": {
88+ "avatar": {
99+ "type": "string",
1010+ "description": "The URL of the actor's avatar image.",
1111+ "format": "uri"
1212+ },
1313+ "createdAt": {
1414+ "type": "string",
1515+ "description": "The date and time when the actor was created.",
1616+ "format": "datetime"
1717+ },
1818+ "did": {
1919+ "type": "string",
2020+ "description": "The DID of the actor."
2121+ },
2222+ "displayName": {
2323+ "type": "string",
2424+ "description": "The display name of the actor."
2525+ },
2626+ "handle": {
2727+ "type": "string",
2828+ "description": "The handle of the actor."
2929+ },
3030+ "id": {
3131+ "type": "string",
3232+ "description": "The unique identifier of the actor."
3333+ },
3434+ "updatedAt": {
3535+ "type": "string",
3636+ "description": "The date and time when the actor was last updated.",
3737+ "format": "datetime"
3838+ }
3939+ }
4040+ },
4141+ "profileViewDetailed": {
4242+ "type": "object",
4343+ "properties": {
4444+ "avatar": {
4545+ "type": "string",
4646+ "description": "The URL of the actor's avatar image.",
4747+ "format": "uri"
4848+ },
4949+ "createdAt": {
5050+ "type": "string",
5151+ "description": "The date and time when the actor was created.",
5252+ "format": "datetime"
5353+ },
5454+ "did": {
5555+ "type": "string",
5656+ "description": "The DID of the actor."
5757+ },
5858+ "displayName": {
5959+ "type": "string",
6060+ "description": "The display name of the actor."
6161+ },
6262+ "handle": {
6363+ "type": "string",
6464+ "description": "The handle of the actor."
6565+ },
6666+ "id": {
6767+ "type": "string",
6868+ "description": "The unique identifier of the actor."
6969+ },
7070+ "updatedAt": {
7171+ "type": "string",
7272+ "description": "The date and time when the actor was last updated.",
7373+ "format": "datetime"
7474+ }
7575+ }
7676+ }
7777+ }
7878+}
···11+{
22+ "lexicon": 1,
33+ "id": "app.rocksky.album.defs",
44+ "defs": {
55+ "albumViewBasic": {
66+ "type": "object",
77+ "properties": {
88+ "albumArt": {
99+ "type": "string",
1010+ "description": "The URL of the album art image.",
1111+ "format": "uri"
1212+ },
1313+ "artist": {
1414+ "type": "string",
1515+ "description": "The artist of the album."
1616+ },
1717+ "artistUri": {
1818+ "type": "string",
1919+ "description": "The URI of the album's artist.",
2020+ "format": "at-uri"
2121+ },
2222+ "id": {
2323+ "type": "string",
2424+ "description": "The unique identifier of the album."
2525+ },
2626+ "playCount": {
2727+ "type": "integer",
2828+ "description": "The number of times the album has been played.",
2929+ "minimum": 0
3030+ },
3131+ "releaseDate": {
3232+ "type": "string",
3333+ "description": "The release date of the album."
3434+ },
3535+ "sha256": {
3636+ "type": "string",
3737+ "description": "The SHA256 hash of the album."
3838+ },
3939+ "title": {
4040+ "type": "string",
4141+ "description": "The title of the album."
4242+ },
4343+ "uniqueListeners": {
4444+ "type": "integer",
4545+ "description": "The number of unique listeners who have played the album.",
4646+ "minimum": 0
4747+ },
4848+ "uri": {
4949+ "type": "string",
5050+ "description": "The URI of the album.",
5151+ "format": "at-uri"
5252+ },
5353+ "year": {
5454+ "type": "integer",
5555+ "description": "The year the album was released."
5656+ }
5757+ }
5858+ },
5959+ "albumViewDetailed": {
6060+ "type": "object",
6161+ "properties": {
6262+ "albumArt": {
6363+ "type": "string",
6464+ "description": "The URL of the album art image.",
6565+ "format": "uri"
6666+ },
6767+ "artist": {
6868+ "type": "string",
6969+ "description": "The artist of the album."
7070+ },
7171+ "artistUri": {
7272+ "type": "string",
7373+ "description": "The URI of the album's artist.",
7474+ "format": "at-uri"
7575+ },
7676+ "id": {
7777+ "type": "string",
7878+ "description": "The unique identifier of the album."
7979+ },
8080+ "playCount": {
8181+ "type": "integer",
8282+ "description": "The number of times the album has been played.",
8383+ "minimum": 0
8484+ },
8585+ "releaseDate": {
8686+ "type": "string",
8787+ "description": "The release date of the album."
8888+ },
8989+ "sha256": {
9090+ "type": "string",
9191+ "description": "The SHA256 hash of the album."
9292+ },
9393+ "title": {
9494+ "type": "string",
9595+ "description": "The title of the album."
9696+ },
9797+ "tracks": {
9898+ "type": "array",
9999+ "items": {
100100+ "type": "ref",
101101+ "ref": "app.rocksky.song.defs.songViewBasic"
102102+ }
103103+ },
104104+ "uniqueListeners": {
105105+ "type": "integer",
106106+ "description": "The number of unique listeners who have played the album.",
107107+ "minimum": 0
108108+ },
109109+ "uri": {
110110+ "type": "string",
111111+ "description": "The URI of the album.",
112112+ "format": "at-uri"
113113+ },
114114+ "year": {
115115+ "type": "integer",
116116+ "description": "The year the album was released."
117117+ }
118118+ }
119119+ }
120120+ }
121121+}
···11+{
22+ "lexicon": 1,
33+ "id": "app.rocksky.apikey.defs",
44+ "defs": {
55+ "apiKeyView": {
66+ "type": "object",
77+ "properties": {
88+ "createdAt": {
99+ "type": "string",
1010+ "description": "The date and time when the API key was created.",
1111+ "format": "datetime"
1212+ },
1313+ "description": {
1414+ "type": "string",
1515+ "description": "A description for the API key."
1616+ },
1717+ "id": {
1818+ "type": "string",
1919+ "description": "The unique identifier of the API key."
2020+ },
2121+ "name": {
2222+ "type": "string",
2323+ "description": "The name of the API key."
2424+ }
2525+ }
2626+ }
2727+ }
2828+}
···11+{
22+ "lexicon": 1,
33+ "id": "app.rocksky.artist.defs",
44+ "defs": {
55+ "artistViewBasic": {
66+ "type": "object",
77+ "properties": {
88+ "id": {
99+ "type": "string",
1010+ "description": "The unique identifier of the artist."
1111+ },
1212+ "name": {
1313+ "type": "string",
1414+ "description": "The name of the artist."
1515+ },
1616+ "picture": {
1717+ "type": "string",
1818+ "description": "The picture of the artist."
1919+ },
2020+ "playCount": {
2121+ "type": "integer",
2222+ "description": "The number of times the artist has been played.",
2323+ "minimum": 0
2424+ },
2525+ "sha256": {
2626+ "type": "string",
2727+ "description": "The SHA256 hash of the artist."
2828+ },
2929+ "uniqueListeners": {
3030+ "type": "integer",
3131+ "description": "The number of unique listeners who have played the artist.",
3232+ "minimum": 0
3333+ },
3434+ "uri": {
3535+ "type": "string",
3636+ "description": "The URI of the artist.",
3737+ "format": "at-uri"
3838+ }
3939+ }
4040+ },
4141+ "artistViewDetailed": {
4242+ "type": "object",
4343+ "properties": {
4444+ "id": {
4545+ "type": "string",
4646+ "description": "The unique identifier of the artist."
4747+ },
4848+ "name": {
4949+ "type": "string",
5050+ "description": "The name of the artist."
5151+ },
5252+ "picture": {
5353+ "type": "string",
5454+ "description": "The picture of the artist."
5555+ },
5656+ "playCount": {
5757+ "type": "integer",
5858+ "description": "The number of times the artist has been played.",
5959+ "minimum": 0
6060+ },
6161+ "sha256": {
6262+ "type": "string",
6363+ "description": "The SHA256 hash of the artist."
6464+ },
6565+ "uniqueListeners": {
6666+ "type": "integer",
6767+ "description": "The number of unique listeners who have played the artist.",
6868+ "minimum": 0
6969+ },
7070+ "uri": {
7171+ "type": "string",
7272+ "description": "The URI of the artist.",
7373+ "format": "at-uri"
7474+ }
7575+ }
7676+ }
7777+ }
7878+}
···11+{
22+ "lexicon": 1,
33+ "id": "app.rocksky.playlist.defs",
44+ "defs": {
55+ "playlistViewBasic": {
66+ "type": "object",
77+ "description": "Basic view of a playlist, including its metadata",
88+ "properties": {
99+ "coverImageUrl": {
1010+ "type": "string",
1111+ "description": "The URL of the cover image for the playlist.",
1212+ "format": "uri"
1313+ },
1414+ "createdAt": {
1515+ "type": "string",
1616+ "description": "The date and time when the playlist was created.",
1717+ "format": "datetime"
1818+ },
1919+ "curatorAvatarUrl": {
2020+ "type": "string",
2121+ "description": "The URL of the avatar image of the curator.",
2222+ "format": "uri"
2323+ },
2424+ "curatorDid": {
2525+ "type": "string",
2626+ "description": "The DID of the curator of the playlist.",
2727+ "format": "at-identifier"
2828+ },
2929+ "curatorHandle": {
3030+ "type": "string",
3131+ "description": "The handle of the curator of the playlist.",
3232+ "format": "at-identifier"
3333+ },
3434+ "curatorName": {
3535+ "type": "string",
3636+ "description": "The name of the curator of the playlist."
3737+ },
3838+ "description": {
3939+ "type": "string",
4040+ "description": "A description of the playlist."
4141+ },
4242+ "id": {
4343+ "type": "string",
4444+ "description": "The unique identifier of the playlist."
4545+ },
4646+ "title": {
4747+ "type": "string",
4848+ "description": "The title of the playlist."
4949+ },
5050+ "trackCount": {
5151+ "type": "integer",
5252+ "description": "The number of tracks in the playlist.",
5353+ "minimum": 0
5454+ },
5555+ "uri": {
5656+ "type": "string",
5757+ "description": "The URI of the playlist.",
5858+ "format": "at-uri"
5959+ }
6060+ }
6161+ },
6262+ "playlistViewDetailed": {
6363+ "type": "object",
6464+ "description": "Detailed view of a playlist, including its tracks and metadata",
6565+ "properties": {
6666+ "coverImageUrl": {
6767+ "type": "string",
6868+ "description": "The URL of the cover image for the playlist.",
6969+ "format": "uri"
7070+ },
7171+ "createdAt": {
7272+ "type": "string",
7373+ "description": "The date and time when the playlist was created.",
7474+ "format": "datetime"
7575+ },
7676+ "curatorAvatarUrl": {
7777+ "type": "string",
7878+ "description": "The URL of the avatar image of the curator.",
7979+ "format": "uri"
8080+ },
8181+ "curatorDid": {
8282+ "type": "string",
8383+ "description": "The DID of the curator of the playlist.",
8484+ "format": "at-identifier"
8585+ },
8686+ "curatorHandle": {
8787+ "type": "string",
8888+ "description": "The handle of the curator of the playlist.",
8989+ "format": "at-identifier"
9090+ },
9191+ "curatorName": {
9292+ "type": "string",
9393+ "description": "The name of the curator of the playlist."
9494+ },
9595+ "description": {
9696+ "type": "string",
9797+ "description": "A description of the playlist."
9898+ },
9999+ "id": {
100100+ "type": "string",
101101+ "description": "The unique identifier of the playlist."
102102+ },
103103+ "title": {
104104+ "type": "string",
105105+ "description": "The title of the playlist."
106106+ },
107107+ "tracks": {
108108+ "type": "array",
109109+ "description": "A list of tracks in the playlist.",
110110+ "items": {
111111+ "type": "ref",
112112+ "ref": "app.rocksky.song.defs#songViewBasic"
113113+ }
114114+ },
115115+ "uri": {
116116+ "type": "string",
117117+ "description": "The URI of the playlist.",
118118+ "format": "at-uri"
119119+ }
120120+ }
121121+ }
122122+ }
123123+}
···11+{
22+ "lexicon": 1,
33+ "id": "app.rocksky.radio.defs",
44+ "defs": {
55+ "radioViewBasic": {
66+ "type": "object",
77+ "properties": {
88+ "createdAt": {
99+ "type": "string",
1010+ "description": "The date and time when the radio was created.",
1111+ "format": "datetime"
1212+ },
1313+ "description": {
1414+ "type": "string",
1515+ "description": "A brief description of the radio."
1616+ },
1717+ "id": {
1818+ "type": "string",
1919+ "description": "The unique identifier of the radio."
2020+ },
2121+ "name": {
2222+ "type": "string",
2323+ "description": "The name of the radio."
2424+ }
2525+ }
2626+ },
2727+ "radioViewDetailed": {
2828+ "type": "object",
2929+ "properties": {
3030+ "createdAt": {
3131+ "type": "string",
3232+ "description": "The date and time when the radio was created.",
3333+ "format": "datetime"
3434+ },
3535+ "description": {
3636+ "type": "string",
3737+ "description": "A brief description of the radio."
3838+ },
3939+ "genre": {
4040+ "type": "string",
4141+ "description": "The genre of the radio."
4242+ },
4343+ "id": {
4444+ "type": "string",
4545+ "description": "The unique identifier of the radio."
4646+ },
4747+ "logo": {
4848+ "type": "string",
4949+ "description": "The logo of the radio station."
5050+ },
5151+ "name": {
5252+ "type": "string",
5353+ "description": "The name of the radio."
5454+ },
5555+ "url": {
5656+ "type": "string",
5757+ "description": "The streaming URL of the radio.",
5858+ "format": "uri"
5959+ },
6060+ "website": {
6161+ "type": "string",
6262+ "description": "The website of the radio.",
6363+ "format": "uri"
6464+ }
6565+ }
6666+ }
6767+ }
6868+}
···11+{
22+ "lexicon": 1,
33+ "id": "app.rocksky.scrobble.createScrobble",
44+ "defs": {
55+ "main": {
66+ "type": "procedure",
77+ "description": "Create a new scrobble",
88+ "input": {
99+ "encoding": "application/json",
1010+ "schema": {
1111+ "type": "object",
1212+ "required": [
1313+ "title",
1414+ "artist"
1515+ ],
1616+ "properties": {
1717+ "album": {
1818+ "type": "string",
1919+ "description": "The album of the track being scrobbled"
2020+ },
2121+ "albumArt": {
2222+ "type": "string",
2323+ "description": "The URL of the album art for the track",
2424+ "format": "uri"
2525+ },
2626+ "appleMusicLink": {
2727+ "type": "string",
2828+ "description": "The Apple Music link for the track, if available",
2929+ "format": "uri"
3030+ },
3131+ "artist": {
3232+ "type": "string",
3333+ "description": "The artist of the track being scrobbled"
3434+ },
3535+ "artistPicture": {
3636+ "type": "string",
3737+ "description": "The URL of the artist's picture, if available",
3838+ "format": "uri"
3939+ },
4040+ "composer": {
4141+ "type": "string",
4242+ "description": "The composer of the track, if available"
4343+ },
4444+ "copyrightMessage": {
4545+ "type": "string",
4646+ "description": "The copyright message for the track, if available"
4747+ },
4848+ "deezerLink": {
4949+ "type": "string",
5050+ "description": "The Deezer link for the track, if available",
5151+ "format": "uri"
5252+ },
5353+ "discNumber": {
5454+ "type": "integer",
5555+ "description": "The disc number of the track in the album, if applicable"
5656+ },
5757+ "duration": {
5858+ "type": "integer",
5959+ "description": "The duration of the track in seconds"
6060+ },
6161+ "label": {
6262+ "type": "string",
6363+ "description": "The record label of the track, if available"
6464+ },
6565+ "lastfmLink": {
6666+ "type": "string",
6767+ "description": "The Last.fm link for the track, if available",
6868+ "format": "uri"
6969+ },
7070+ "lyrics": {
7171+ "type": "string",
7272+ "description": "The lyrics of the track, if available"
7373+ },
7474+ "mbId": {
7575+ "type": "string",
7676+ "description": "The MusicBrainz ID of the track, if available"
7777+ },
7878+ "releaseDate": {
7979+ "type": "string",
8080+ "description": "The release date of the track, formatted as YYYY-MM-DD"
8181+ },
8282+ "spotifyLink": {
8383+ "type": "string",
8484+ "description": "The Spotify link for the track, if available",
8585+ "format": "uri"
8686+ },
8787+ "tidalLink": {
8888+ "type": "string",
8989+ "description": "The Tidal link for the track, if available",
9090+ "format": "uri"
9191+ },
9292+ "timestamp": {
9393+ "type": "integer",
9494+ "description": "The timestamp of the scrobble in milliseconds since epoch"
9595+ },
9696+ "title": {
9797+ "type": "string",
9898+ "description": "The title of the track being scrobbled"
9999+ },
100100+ "trackNumber": {
101101+ "type": "integer",
102102+ "description": "The track number of the track in the album"
103103+ },
104104+ "year": {
105105+ "type": "integer",
106106+ "description": "The year the track was released"
107107+ },
108108+ "youtubeLink": {
109109+ "type": "string",
110110+ "description": "The Youtube link for the track, if available",
111111+ "format": "uri"
112112+ }
113113+ }
114114+ }
115115+ },
116116+ "output": {
117117+ "encoding": "application/json",
118118+ "schema": {
119119+ "type": "ref",
120120+ "ref": "app.rocksky.scrobble.defs#scrobbleViewBasic"
121121+ }
122122+ }
123123+ }
124124+ }
125125+}
···11+{
22+ "lexicon": 1,
33+ "id": "app.rocksky.scrobble.defs",
44+ "defs": {
55+ "scrobbleViewBasic": {
66+ "type": "object",
77+ "properties": {
88+ "album": {
99+ "type": "string",
1010+ "description": "The album of the song."
1111+ },
1212+ "albumUri": {
1313+ "type": "string",
1414+ "description": "The URI of the album.",
1515+ "format": "at-uri"
1616+ },
1717+ "artist": {
1818+ "type": "string",
1919+ "description": "The artist of the song."
2020+ },
2121+ "artistUri": {
2222+ "type": "string",
2323+ "description": "The URI of the artist.",
2424+ "format": "at-uri"
2525+ },
2626+ "cover": {
2727+ "type": "string",
2828+ "description": "The album art URL of the song.",
2929+ "format": "uri"
3030+ },
3131+ "date": {
3232+ "type": "string",
3333+ "description": "The timestamp when the scrobble was created.",
3434+ "format": "datetime"
3535+ },
3636+ "id": {
3737+ "type": "string",
3838+ "description": "The unique identifier of the scrobble."
3939+ },
4040+ "sha256": {
4141+ "type": "string",
4242+ "description": "The SHA256 hash of the scrobble data."
4343+ },
4444+ "title": {
4545+ "type": "string",
4646+ "description": "The title of the scrobble."
4747+ },
4848+ "uri": {
4949+ "type": "string",
5050+ "description": "The URI of the scrobble.",
5151+ "format": "uri"
5252+ },
5353+ "user": {
5454+ "type": "string",
5555+ "description": "The handle of the user who created the scrobble."
5656+ }
5757+ }
5858+ },
5959+ "scrobbleViewDetailed": {
6060+ "type": "object",
6161+ "properties": {
6262+ "album": {
6363+ "type": "string",
6464+ "description": "The album of the song."
6565+ },
6666+ "albumUri": {
6767+ "type": "string",
6868+ "description": "The URI of the album.",
6969+ "format": "at-uri"
7070+ },
7171+ "artist": {
7272+ "type": "string",
7373+ "description": "The artist of the song."
7474+ },
7575+ "artistUri": {
7676+ "type": "string",
7777+ "description": "The URI of the artist.",
7878+ "format": "at-uri"
7979+ },
8080+ "cover": {
8181+ "type": "string",
8282+ "description": "The album art URL of the song.",
8383+ "format": "uri"
8484+ },
8585+ "date": {
8686+ "type": "string",
8787+ "description": "The timestamp when the scrobble was created.",
8888+ "format": "datetime"
8989+ },
9090+ "id": {
9191+ "type": "string",
9292+ "description": "The unique identifier of the scrobble."
9393+ },
9494+ "listeners": {
9595+ "type": "integer",
9696+ "description": "The number of listeners"
9797+ },
9898+ "scrobbles": {
9999+ "type": "integer",
100100+ "description": "The number of scrobbles for this song"
101101+ },
102102+ "sha256": {
103103+ "type": "string",
104104+ "description": "The SHA256 hash of the scrobble data."
105105+ },
106106+ "title": {
107107+ "type": "string",
108108+ "description": "The title of the scrobble."
109109+ },
110110+ "uri": {
111111+ "type": "string",
112112+ "description": "The URI of the scrobble.",
113113+ "format": "uri"
114114+ },
115115+ "user": {
116116+ "type": "string",
117117+ "description": "The handle of the user who created the scrobble."
118118+ }
119119+ }
120120+ }
121121+ }
122122+}
···11+{
22+ "lexicon": 1,
33+ "id": "app.rocksky.song.createSong",
44+ "defs": {
55+ "main": {
66+ "type": "procedure",
77+ "description": "Create a new song",
88+ "input": {
99+ "encoding": "application/json",
1010+ "schema": {
1111+ "type": "object",
1212+ "required": [
1313+ "title",
1414+ "artist",
1515+ "album",
1616+ "albumArtist"
1717+ ],
1818+ "properties": {
1919+ "album": {
2020+ "type": "string",
2121+ "description": "The album of the song, if applicable"
2222+ },
2323+ "albumArt": {
2424+ "type": "string",
2525+ "description": "The URL of the album art for the song",
2626+ "format": "uri"
2727+ },
2828+ "albumArtist": {
2929+ "type": "string",
3030+ "description": "The album artist of the song, if different from the main artist"
3131+ },
3232+ "artist": {
3333+ "type": "string",
3434+ "description": "The artist of the song"
3535+ },
3636+ "discNumber": {
3737+ "type": "integer",
3838+ "description": "The disc number of the song in the album, if applicable"
3939+ },
4040+ "duration": {
4141+ "type": "integer",
4242+ "description": "The duration of the song in seconds"
4343+ },
4444+ "lyrics": {
4545+ "type": "string",
4646+ "description": "The lyrics of the song, if available"
4747+ },
4848+ "mbId": {
4949+ "type": "string",
5050+ "description": "The MusicBrainz ID of the song, if available"
5151+ },
5252+ "releaseDate": {
5353+ "type": "string",
5454+ "description": "The release date of the song, formatted as YYYY-MM-DD"
5555+ },
5656+ "title": {
5757+ "type": "string",
5858+ "description": "The title of the song"
5959+ },
6060+ "trackNumber": {
6161+ "type": "integer",
6262+ "description": "The track number of the song in the album, if applicable"
6363+ },
6464+ "year": {
6565+ "type": "integer",
6666+ "description": "The year the song was released"
6767+ }
6868+ }
6969+ }
7070+ },
7171+ "output": {
7272+ "encoding": "application/json",
7373+ "schema": {
7474+ "type": "ref",
7575+ "ref": "app.rocksky.song.defs#songViewDetailed"
7676+ }
7777+ }
7878+ }
7979+ }
8080+}
···11+{
22+ "lexicon": 1,
33+ "id": "app.rocksky.song.defs",
44+ "defs": {
55+ "songViewBasic": {
66+ "type": "object",
77+ "properties": {
88+ "album": {
99+ "type": "string",
1010+ "description": "The album of the song."
1111+ },
1212+ "albumArt": {
1313+ "type": "string",
1414+ "description": "The URL of the album art image.",
1515+ "format": "uri"
1616+ },
1717+ "albumArtist": {
1818+ "type": "string",
1919+ "description": "The artist of the album the song belongs to."
2020+ },
2121+ "albumUri": {
2222+ "type": "string",
2323+ "description": "The URI of the album the song belongs to.",
2424+ "format": "at-uri"
2525+ },
2626+ "artist": {
2727+ "type": "string",
2828+ "description": "The artist of the song."
2929+ },
3030+ "artistUri": {
3131+ "type": "string",
3232+ "description": "The URI of the artist of the song.",
3333+ "format": "at-uri"
3434+ },
3535+ "createdAt": {
3636+ "type": "string",
3737+ "description": "The timestamp when the song was created.",
3838+ "format": "datetime"
3939+ },
4040+ "discNumber": {
4141+ "type": "integer",
4242+ "description": "The disc number of the song in the album."
4343+ },
4444+ "duration": {
4545+ "type": "integer",
4646+ "description": "The duration of the song in milliseconds."
4747+ },
4848+ "id": {
4949+ "type": "string",
5050+ "description": "The unique identifier of the song."
5151+ },
5252+ "playCount": {
5353+ "type": "integer",
5454+ "description": "The number of times the song has been played.",
5555+ "minimum": 0
5656+ },
5757+ "sha256": {
5858+ "type": "string",
5959+ "description": "The SHA256 hash of the song."
6060+ },
6161+ "title": {
6262+ "type": "string",
6363+ "description": "The title of the song."
6464+ },
6565+ "trackNumber": {
6666+ "type": "integer",
6767+ "description": "The track number of the song in the album."
6868+ },
6969+ "uniqueListeners": {
7070+ "type": "integer",
7171+ "description": "The number of unique listeners who have played the song.",
7272+ "minimum": 0
7373+ },
7474+ "uri": {
7575+ "type": "string",
7676+ "description": "The URI of the song.",
7777+ "format": "at-uri"
7878+ }
7979+ }
8080+ },
8181+ "songViewDetailed": {
8282+ "type": "object",
8383+ "properties": {
8484+ "album": {
8585+ "type": "string",
8686+ "description": "The album of the song."
8787+ },
8888+ "albumArt": {
8989+ "type": "string",
9090+ "description": "The URL of the album art image.",
9191+ "format": "uri"
9292+ },
9393+ "albumArtist": {
9494+ "type": "string",
9595+ "description": "The artist of the album the song belongs to."
9696+ },
9797+ "albumUri": {
9898+ "type": "string",
9999+ "description": "The URI of the album the song belongs to.",
100100+ "format": "at-uri"
101101+ },
102102+ "artist": {
103103+ "type": "string",
104104+ "description": "The artist of the song."
105105+ },
106106+ "artistUri": {
107107+ "type": "string",
108108+ "description": "The URI of the artist of the song.",
109109+ "format": "at-uri"
110110+ },
111111+ "createdAt": {
112112+ "type": "string",
113113+ "description": "The timestamp when the song was created.",
114114+ "format": "datetime"
115115+ },
116116+ "discNumber": {
117117+ "type": "integer",
118118+ "description": "The disc number of the song in the album."
119119+ },
120120+ "duration": {
121121+ "type": "integer",
122122+ "description": "The duration of the song in milliseconds."
123123+ },
124124+ "id": {
125125+ "type": "string",
126126+ "description": "The unique identifier of the song."
127127+ },
128128+ "playCount": {
129129+ "type": "integer",
130130+ "description": "The number of times the song has been played.",
131131+ "minimum": 0
132132+ },
133133+ "sha256": {
134134+ "type": "string",
135135+ "description": "The SHA256 hash of the song."
136136+ },
137137+ "title": {
138138+ "type": "string",
139139+ "description": "The title of the song."
140140+ },
141141+ "trackNumber": {
142142+ "type": "integer",
143143+ "description": "The track number of the song in the album."
144144+ },
145145+ "uniqueListeners": {
146146+ "type": "integer",
147147+ "description": "The number of unique listeners who have played the song.",
148148+ "minimum": 0
149149+ },
150150+ "uri": {
151151+ "type": "string",
152152+ "description": "The URI of the song.",
153153+ "format": "at-uri"
154154+ }
155155+ }
156156+ }
157157+ }
158158+}
···11+{
22+ "lexicon": 1,
33+ "id": "app.rocksky.stats.defs",
44+ "defs": {
55+ "statsView": {
66+ "type": "object",
77+ "properties": {
88+ "albums": {
99+ "type": "integer",
1010+ "description": "The total number of unique albums scrobbled."
1111+ },
1212+ "artists": {
1313+ "type": "integer",
1414+ "description": "The total number of unique artists scrobbled."
1515+ },
1616+ "lovedTracks": {
1717+ "type": "integer",
1818+ "description": "The total number of tracks marked as loved."
1919+ },
2020+ "scrobbles": {
2121+ "type": "integer",
2222+ "description": "The total number of scrobbles."
2323+ },
2424+ "tracks": {
2525+ "type": "integer",
2626+ "description": "The total number of unique tracks scrobbled."
2727+ }
2828+ }
2929+ }
3030+ }
3131+}
···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 album;
88+pub mod apikey;
99+pub mod artist;
1010+pub mod charts;
1111+pub mod dropbox;
1212+pub mod feed;
1313+pub mod googledrive;
1414+pub mod like;
1515+pub mod player;
1616+pub mod playlist;
1717+pub mod radio;
1818+pub mod scrobble;
1919+pub mod shout;
2020+pub mod song;
2121+pub mod spotify;
2222+pub mod stats;
+96
crates/jacquard-api/src/app_rocksky/actor.rs
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: app.rocksky.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_actor_albums;
99+pub mod get_actor_artists;
1010+pub mod get_actor_loved_songs;
1111+pub mod get_actor_playlists;
1212+pub mod get_actor_scrobbles;
1313+pub mod get_actor_songs;
1414+pub mod get_profile;
1515+1616+#[jacquard_derive::lexicon]
1717+#[derive(
1818+ serde::Serialize,
1919+ serde::Deserialize,
2020+ Debug,
2121+ Clone,
2222+ PartialEq,
2323+ Eq,
2424+ jacquard_derive::IntoStatic,
2525+ Default
2626+)]
2727+#[serde(rename_all = "camelCase")]
2828+pub struct ProfileViewBasic<'a> {
2929+ /// The URL of the actor's avatar image.
3030+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3131+ #[serde(borrow)]
3232+ pub avatar: std::option::Option<jacquard_common::types::string::Uri<'a>>,
3333+ /// The date and time when the actor was created.
3434+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3535+ pub created_at: std::option::Option<jacquard_common::types::string::Datetime>,
3636+ /// The DID of the actor.
3737+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3838+ #[serde(borrow)]
3939+ pub did: std::option::Option<jacquard_common::CowStr<'a>>,
4040+ /// The display name of the actor.
4141+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
4242+ #[serde(borrow)]
4343+ pub display_name: std::option::Option<jacquard_common::CowStr<'a>>,
4444+ /// The handle of the actor.
4545+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
4646+ #[serde(borrow)]
4747+ pub handle: std::option::Option<jacquard_common::CowStr<'a>>,
4848+ /// The unique identifier of the actor.
4949+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5050+ #[serde(borrow)]
5151+ pub id: std::option::Option<jacquard_common::CowStr<'a>>,
5252+ /// The date and time when the actor was last updated.
5353+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5454+ pub updated_at: std::option::Option<jacquard_common::types::string::Datetime>,
5555+}
5656+5757+#[jacquard_derive::lexicon]
5858+#[derive(
5959+ serde::Serialize,
6060+ serde::Deserialize,
6161+ Debug,
6262+ Clone,
6363+ PartialEq,
6464+ Eq,
6565+ jacquard_derive::IntoStatic,
6666+ Default
6767+)]
6868+#[serde(rename_all = "camelCase")]
6969+pub struct ProfileViewDetailed<'a> {
7070+ /// The URL of the actor's avatar image.
7171+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
7272+ #[serde(borrow)]
7373+ pub avatar: std::option::Option<jacquard_common::types::string::Uri<'a>>,
7474+ /// The date and time when the actor was created.
7575+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
7676+ pub created_at: std::option::Option<jacquard_common::types::string::Datetime>,
7777+ /// The DID 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+ /// The display name of the actor.
8282+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
8383+ #[serde(borrow)]
8484+ pub display_name: std::option::Option<jacquard_common::CowStr<'a>>,
8585+ /// The handle of the actor.
8686+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
8787+ #[serde(borrow)]
8888+ pub handle: std::option::Option<jacquard_common::CowStr<'a>>,
8989+ /// The unique identifier of the actor.
9090+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
9191+ #[serde(borrow)]
9292+ pub id: std::option::Option<jacquard_common::CowStr<'a>>,
9393+ /// The date and time when the actor was last updated.
9494+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
9595+ pub updated_at: std::option::Option<jacquard_common::types::string::Datetime>,
9696+}
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: app.rocksky.actor.getProfile
44+//
55+// This file was automatically generated from Lexicon schemas.
66+// Any manual changes will be overwritten on the next regeneration.
77+88+#[derive(
99+ serde::Serialize,
1010+ serde::Deserialize,
1111+ Debug,
1212+ Clone,
1313+ PartialEq,
1414+ Eq,
1515+ bon::Builder,
1616+ jacquard_derive::IntoStatic
1717+)]
1818+#[builder(start_fn = new)]
1919+#[serde(rename_all = "camelCase")]
2020+pub struct GetProfile<'a> {
2121+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2222+ #[serde(borrow)]
2323+ pub did: std::option::Option<jacquard_common::types::ident::AtIdentifier<'a>>,
2424+}
2525+2626+#[jacquard_derive::lexicon]
2727+#[derive(
2828+ serde::Serialize,
2929+ serde::Deserialize,
3030+ Debug,
3131+ Clone,
3232+ PartialEq,
3333+ Eq,
3434+ jacquard_derive::IntoStatic
3535+)]
3636+#[serde(rename_all = "camelCase")]
3737+pub struct GetProfileOutput<'a> {
3838+ #[serde(flatten)]
3939+ #[serde(borrow)]
4040+ pub value: crate::app_rocksky::actor::ProfileViewDetailed<'a>,
4141+}
4242+4343+///Response type for
4444+///app.rocksky.actor.getProfile
4545+pub struct GetProfileResponse;
4646+impl jacquard_common::xrpc::XrpcResp for GetProfileResponse {
4747+ const NSID: &'static str = "app.rocksky.actor.getProfile";
4848+ const ENCODING: &'static str = "application/json";
4949+ type Output<'de> = GetProfileOutput<'de>;
5050+ type Err<'de> = jacquard_common::xrpc::GenericError<'de>;
5151+}
5252+5353+impl<'a> jacquard_common::xrpc::XrpcRequest for GetProfile<'a> {
5454+ const NSID: &'static str = "app.rocksky.actor.getProfile";
5555+ const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Query;
5656+ type Response = GetProfileResponse;
5757+}
5858+5959+///Endpoint type for
6060+///app.rocksky.actor.getProfile
6161+pub struct GetProfileRequest;
6262+impl jacquard_common::xrpc::XrpcEndpoint for GetProfileRequest {
6363+ const PATH: &'static str = "/xrpc/app.rocksky.actor.getProfile";
6464+ const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Query;
6565+ type Request<'de> = GetProfile<'de>;
6666+ type Response = GetProfileResponse;
6767+}
+240
crates/jacquard-api/src/app_rocksky/album.rs
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: app.rocksky.album.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_album;
99+pub mod get_album_tracks;
1010+pub mod get_albums;
1111+1212+/// A declaration of an album.
1313+#[jacquard_derive::lexicon]
1414+#[derive(
1515+ serde::Serialize,
1616+ serde::Deserialize,
1717+ Debug,
1818+ Clone,
1919+ PartialEq,
2020+ Eq,
2121+ jacquard_derive::IntoStatic,
2222+ bon::Builder
2323+)]
2424+#[serde(rename_all = "camelCase")]
2525+pub struct Album<'a> {
2626+ /// The album art of the album.
2727+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2828+ #[builder(into)]
2929+ #[serde(borrow)]
3030+ pub album_art: Option<jacquard_common::types::blob::Blob<'a>>,
3131+ /// The Apple Music link of the album.
3232+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3333+ #[builder(into)]
3434+ #[serde(borrow)]
3535+ pub apple_music_link: Option<jacquard_common::types::string::Uri<'a>>,
3636+ /// The artist of the album.
3737+ #[serde(borrow)]
3838+ #[builder(into)]
3939+ pub artist: jacquard_common::CowStr<'a>,
4040+ /// The date and time when the album was created.
4141+ pub created_at: jacquard_common::types::string::Datetime,
4242+ /// The duration of the album in seconds.
4343+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
4444+ #[builder(into)]
4545+ pub duration: Option<i64>,
4646+ /// The genre of the album.
4747+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
4848+ #[builder(into)]
4949+ #[serde(borrow)]
5050+ pub genre: Option<jacquard_common::CowStr<'a>>,
5151+ /// The release date of the album.
5252+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5353+ #[builder(into)]
5454+ pub release_date: Option<jacquard_common::types::string::Datetime>,
5555+ /// The Spotify link of the album.
5656+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5757+ #[builder(into)]
5858+ #[serde(borrow)]
5959+ pub spotify_link: Option<jacquard_common::types::string::Uri<'a>>,
6060+ /// The tags of the album.
6161+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
6262+ #[builder(into)]
6363+ #[serde(borrow)]
6464+ pub tags: Option<Vec<jacquard_common::CowStr<'a>>>,
6565+ /// The tidal link of the album.
6666+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
6767+ #[builder(into)]
6868+ #[serde(borrow)]
6969+ pub tidal_link: Option<jacquard_common::types::string::Uri<'a>>,
7070+ /// The title of the album.
7171+ #[serde(borrow)]
7272+ #[builder(into)]
7373+ pub title: jacquard_common::CowStr<'a>,
7474+ /// The year the album was released.
7575+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
7676+ #[builder(into)]
7777+ pub year: Option<i64>,
7878+ /// The YouTube link of the album.
7979+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
8080+ #[builder(into)]
8181+ #[serde(borrow)]
8282+ pub youtube_link: Option<jacquard_common::types::string::Uri<'a>>,
8383+}
8484+8585+/// Typed wrapper for GetRecord response with this collection's record type.
8686+#[derive(
8787+ serde::Serialize,
8888+ serde::Deserialize,
8989+ Debug,
9090+ Clone,
9191+ PartialEq,
9292+ Eq,
9393+ jacquard_derive::IntoStatic
9494+)]
9595+#[serde(rename_all = "camelCase")]
9696+pub struct AlbumGetRecordOutput<'a> {
9797+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
9898+ #[serde(borrow)]
9999+ pub cid: std::option::Option<jacquard_common::types::string::Cid<'a>>,
100100+ #[serde(borrow)]
101101+ pub uri: jacquard_common::types::string::AtUri<'a>,
102102+ #[serde(borrow)]
103103+ pub value: Album<'a>,
104104+}
105105+106106+/// Marker type for deserializing records from this collection.
107107+pub struct AlbumRecord;
108108+impl jacquard_common::xrpc::XrpcResp for AlbumRecord {
109109+ const NSID: &'static str = "app.rocksky.album";
110110+ const ENCODING: &'static str = "application/json";
111111+ type Output<'de> = AlbumGetRecordOutput<'de>;
112112+ type Err<'de> = jacquard_common::types::collection::RecordError<'de>;
113113+}
114114+115115+impl jacquard_common::types::collection::Collection for Album<'_> {
116116+ const NSID: &'static str = "app.rocksky.album";
117117+ type Record = AlbumRecord;
118118+}
119119+120120+impl From<AlbumGetRecordOutput<'_>> for Album<'_> {
121121+ fn from(output: AlbumGetRecordOutput<'_>) -> Self {
122122+ use jacquard_common::IntoStatic;
123123+ output.value.into_static()
124124+ }
125125+}
126126+127127+#[jacquard_derive::lexicon]
128128+#[derive(
129129+ serde::Serialize,
130130+ serde::Deserialize,
131131+ Debug,
132132+ Clone,
133133+ PartialEq,
134134+ Eq,
135135+ jacquard_derive::IntoStatic,
136136+ Default
137137+)]
138138+#[serde(rename_all = "camelCase")]
139139+pub struct AlbumViewBasic<'a> {
140140+ /// The URL of the album art image.
141141+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
142142+ #[serde(borrow)]
143143+ pub album_art: std::option::Option<jacquard_common::types::string::Uri<'a>>,
144144+ /// The artist of the album.
145145+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
146146+ #[serde(borrow)]
147147+ pub artist: std::option::Option<jacquard_common::CowStr<'a>>,
148148+ /// The URI of the album's artist.
149149+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
150150+ #[serde(borrow)]
151151+ pub artist_uri: std::option::Option<jacquard_common::types::string::AtUri<'a>>,
152152+ /// The unique identifier of the album.
153153+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
154154+ #[serde(borrow)]
155155+ pub id: std::option::Option<jacquard_common::CowStr<'a>>,
156156+ /// The number of times the album has been played.
157157+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
158158+ pub play_count: std::option::Option<i64>,
159159+ /// The release date of the album.
160160+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
161161+ #[serde(borrow)]
162162+ pub release_date: std::option::Option<jacquard_common::CowStr<'a>>,
163163+ /// The SHA256 hash of the album.
164164+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
165165+ #[serde(borrow)]
166166+ pub sha256: std::option::Option<jacquard_common::CowStr<'a>>,
167167+ /// The title of the album.
168168+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
169169+ #[serde(borrow)]
170170+ pub title: std::option::Option<jacquard_common::CowStr<'a>>,
171171+ /// The number of unique listeners who have played the album.
172172+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
173173+ pub unique_listeners: std::option::Option<i64>,
174174+ /// The URI of the album.
175175+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
176176+ #[serde(borrow)]
177177+ pub uri: std::option::Option<jacquard_common::types::string::AtUri<'a>>,
178178+ /// The year the album was released.
179179+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
180180+ pub year: std::option::Option<i64>,
181181+}
182182+183183+#[jacquard_derive::lexicon]
184184+#[derive(
185185+ serde::Serialize,
186186+ serde::Deserialize,
187187+ Debug,
188188+ Clone,
189189+ PartialEq,
190190+ Eq,
191191+ jacquard_derive::IntoStatic,
192192+ Default
193193+)]
194194+#[serde(rename_all = "camelCase")]
195195+pub struct AlbumViewDetailed<'a> {
196196+ /// The URL of the album art image.
197197+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
198198+ #[serde(borrow)]
199199+ pub album_art: std::option::Option<jacquard_common::types::string::Uri<'a>>,
200200+ /// The artist of the album.
201201+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
202202+ #[serde(borrow)]
203203+ pub artist: std::option::Option<jacquard_common::CowStr<'a>>,
204204+ /// The URI of the album's artist.
205205+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
206206+ #[serde(borrow)]
207207+ pub artist_uri: std::option::Option<jacquard_common::types::string::AtUri<'a>>,
208208+ /// The unique identifier of the album.
209209+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
210210+ #[serde(borrow)]
211211+ pub id: std::option::Option<jacquard_common::CowStr<'a>>,
212212+ /// The number of times the album has been played.
213213+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
214214+ pub play_count: std::option::Option<i64>,
215215+ /// The release date of the album.
216216+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
217217+ #[serde(borrow)]
218218+ pub release_date: std::option::Option<jacquard_common::CowStr<'a>>,
219219+ /// The SHA256 hash of the album.
220220+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
221221+ #[serde(borrow)]
222222+ pub sha256: std::option::Option<jacquard_common::CowStr<'a>>,
223223+ /// The title of the album.
224224+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
225225+ #[serde(borrow)]
226226+ pub title: std::option::Option<jacquard_common::CowStr<'a>>,
227227+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
228228+ #[serde(borrow)]
229229+ pub tracks: std::option::Option<Vec<jacquard_common::types::value::Data<'a>>>,
230230+ /// The number of unique listeners who have played the album.
231231+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
232232+ pub unique_listeners: std::option::Option<i64>,
233233+ /// The URI of the album.
234234+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
235235+ #[serde(borrow)]
236236+ pub uri: std::option::Option<jacquard_common::types::string::AtUri<'a>>,
237237+ /// The year the album was released.
238238+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
239239+ pub year: std::option::Option<i64>,
240240+}
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: app.rocksky.album.getAlbums
44+//
55+// This file was automatically generated from Lexicon schemas.
66+// Any manual changes will be overwritten on the next regeneration.
77+88+#[derive(
99+ serde::Serialize,
1010+ serde::Deserialize,
1111+ Debug,
1212+ Clone,
1313+ PartialEq,
1414+ Eq,
1515+ bon::Builder,
1616+ jacquard_derive::IntoStatic
1717+)]
1818+#[builder(start_fn = new)]
1919+#[serde(rename_all = "camelCase")]
2020+pub struct GetAlbums {
2121+ ///(min: 1)
2222+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2323+ pub limit: std::option::Option<i64>,
2424+ ///(min: 0)
2525+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2626+ pub offset: std::option::Option<i64>,
2727+}
2828+2929+#[jacquard_derive::lexicon]
3030+#[derive(
3131+ serde::Serialize,
3232+ serde::Deserialize,
3333+ Debug,
3434+ Clone,
3535+ PartialEq,
3636+ Eq,
3737+ jacquard_derive::IntoStatic,
3838+ Default
3939+)]
4040+#[serde(rename_all = "camelCase")]
4141+pub struct GetAlbumsOutput<'a> {
4242+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
4343+ #[serde(borrow)]
4444+ pub albums: std::option::Option<Vec<crate::app_rocksky::album::AlbumViewBasic<'a>>>,
4545+}
4646+4747+///Response type for
4848+///app.rocksky.album.getAlbums
4949+pub struct GetAlbumsResponse;
5050+impl jacquard_common::xrpc::XrpcResp for GetAlbumsResponse {
5151+ const NSID: &'static str = "app.rocksky.album.getAlbums";
5252+ const ENCODING: &'static str = "application/json";
5353+ type Output<'de> = GetAlbumsOutput<'de>;
5454+ type Err<'de> = jacquard_common::xrpc::GenericError<'de>;
5555+}
5656+5757+impl jacquard_common::xrpc::XrpcRequest for GetAlbums {
5858+ const NSID: &'static str = "app.rocksky.album.getAlbums";
5959+ const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Query;
6060+ type Response = GetAlbumsResponse;
6161+}
6262+6363+///Endpoint type for
6464+///app.rocksky.album.getAlbums
6565+pub struct GetAlbumsRequest;
6666+impl jacquard_common::xrpc::XrpcEndpoint for GetAlbumsRequest {
6767+ const PATH: &'static str = "/xrpc/app.rocksky.album.getAlbums";
6868+ const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Query;
6969+ type Request<'de> = GetAlbums;
7070+ type Response = GetAlbumsResponse;
7171+}
+41
crates/jacquard-api/src/app_rocksky/apikey.rs
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: app.rocksky.apikey.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 create_apikey;
99+pub mod get_apikeys;
1010+pub mod remove_apikey;
1111+pub mod update_apikey;
1212+1313+#[jacquard_derive::lexicon]
1414+#[derive(
1515+ serde::Serialize,
1616+ serde::Deserialize,
1717+ Debug,
1818+ Clone,
1919+ PartialEq,
2020+ Eq,
2121+ jacquard_derive::IntoStatic,
2222+ Default
2323+)]
2424+#[serde(rename_all = "camelCase")]
2525+pub struct ApiKeyView<'a> {
2626+ /// The date and time when the API key was created.
2727+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2828+ pub created_at: std::option::Option<jacquard_common::types::string::Datetime>,
2929+ /// A description for the API key.
3030+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3131+ #[serde(borrow)]
3232+ pub description: std::option::Option<jacquard_common::CowStr<'a>>,
3333+ /// The unique identifier of the API key.
3434+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3535+ #[serde(borrow)]
3636+ pub id: std::option::Option<jacquard_common::CowStr<'a>>,
3737+ /// The name of the API key.
3838+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3939+ #[serde(borrow)]
4040+ pub name: std::option::Option<jacquard_common::CowStr<'a>>,
4141+}
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: app.rocksky.charts.getScrobblesChart
44+//
55+// This file was automatically generated from Lexicon schemas.
66+// Any manual changes will be overwritten on the next regeneration.
77+88+#[derive(
99+ serde::Serialize,
1010+ serde::Deserialize,
1111+ Debug,
1212+ Clone,
1313+ PartialEq,
1414+ Eq,
1515+ bon::Builder,
1616+ jacquard_derive::IntoStatic
1717+)]
1818+#[builder(start_fn = new)]
1919+#[serde(rename_all = "camelCase")]
2020+pub struct GetScrobblesChart<'a> {
2121+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2222+ #[serde(borrow)]
2323+ pub albumuri: std::option::Option<jacquard_common::types::string::AtUri<'a>>,
2424+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2525+ #[serde(borrow)]
2626+ pub artisturi: std::option::Option<jacquard_common::types::string::AtUri<'a>>,
2727+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2828+ #[serde(borrow)]
2929+ pub did: std::option::Option<jacquard_common::types::ident::AtIdentifier<'a>>,
3030+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3131+ #[serde(borrow)]
3232+ pub songuri: std::option::Option<jacquard_common::types::string::AtUri<'a>>,
3333+}
3434+3535+#[jacquard_derive::lexicon]
3636+#[derive(
3737+ serde::Serialize,
3838+ serde::Deserialize,
3939+ Debug,
4040+ Clone,
4141+ PartialEq,
4242+ Eq,
4343+ jacquard_derive::IntoStatic
4444+)]
4545+#[serde(rename_all = "camelCase")]
4646+pub struct GetScrobblesChartOutput<'a> {
4747+ #[serde(flatten)]
4848+ #[serde(borrow)]
4949+ pub value: crate::app_rocksky::charts::ChartsView<'a>,
5050+}
5151+5252+///Response type for
5353+///app.rocksky.charts.getScrobblesChart
5454+pub struct GetScrobblesChartResponse;
5555+impl jacquard_common::xrpc::XrpcResp for GetScrobblesChartResponse {
5656+ const NSID: &'static str = "app.rocksky.charts.getScrobblesChart";
5757+ const ENCODING: &'static str = "application/json";
5858+ type Output<'de> = GetScrobblesChartOutput<'de>;
5959+ type Err<'de> = jacquard_common::xrpc::GenericError<'de>;
6060+}
6161+6262+impl<'a> jacquard_common::xrpc::XrpcRequest for GetScrobblesChart<'a> {
6363+ const NSID: &'static str = "app.rocksky.charts.getScrobblesChart";
6464+ const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Query;
6565+ type Response = GetScrobblesChartResponse;
6666+}
6767+6868+///Endpoint type for
6969+///app.rocksky.charts.getScrobblesChart
7070+pub struct GetScrobblesChartRequest;
7171+impl jacquard_common::xrpc::XrpcEndpoint for GetScrobblesChartRequest {
7272+ const PATH: &'static str = "/xrpc/app.rocksky.charts.getScrobblesChart";
7373+ const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Query;
7474+ type Request<'de> = GetScrobblesChart<'de>;
7575+ type Response = GetScrobblesChartResponse;
7676+}
+86
crates/jacquard-api/src/app_rocksky/dropbox.rs
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: app.rocksky.dropbox.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 download_file;
99+pub mod get_files;
1010+pub mod get_metadata;
1111+pub mod get_temporary_link;
1212+1313+#[jacquard_derive::lexicon]
1414+#[derive(
1515+ serde::Serialize,
1616+ serde::Deserialize,
1717+ Debug,
1818+ Clone,
1919+ PartialEq,
2020+ Eq,
2121+ jacquard_derive::IntoStatic,
2222+ Default
2323+)]
2424+#[serde(rename_all = "camelCase")]
2525+pub struct FileListView<'a> {
2626+ /// A list of files in the Dropbox.
2727+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2828+ #[serde(borrow)]
2929+ pub files: std::option::Option<Vec<crate::app_rocksky::dropbox::FileView<'a>>>,
3030+}
3131+3232+#[jacquard_derive::lexicon]
3333+#[derive(
3434+ serde::Serialize,
3535+ serde::Deserialize,
3636+ Debug,
3737+ Clone,
3838+ PartialEq,
3939+ Eq,
4040+ jacquard_derive::IntoStatic,
4141+ Default
4242+)]
4343+#[serde(rename_all = "camelCase")]
4444+pub struct FileView<'a> {
4545+ /// The last modified date and time of the file on the client.
4646+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
4747+ pub client_modified: std::option::Option<jacquard_common::types::string::Datetime>,
4848+ /// The unique identifier of the file.
4949+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5050+ #[serde(borrow)]
5151+ pub id: std::option::Option<jacquard_common::CowStr<'a>>,
5252+ /// The name of the file.
5353+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5454+ #[serde(borrow)]
5555+ pub name: std::option::Option<jacquard_common::CowStr<'a>>,
5656+ /// The display path of the file.
5757+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5858+ #[serde(borrow)]
5959+ pub path_display: std::option::Option<jacquard_common::CowStr<'a>>,
6060+ /// The lowercased path of the file.
6161+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
6262+ #[serde(borrow)]
6363+ pub path_lower: std::option::Option<jacquard_common::CowStr<'a>>,
6464+ /// The last modified date and time of the file on the server.
6565+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
6666+ pub server_modified: std::option::Option<jacquard_common::types::string::Datetime>,
6767+}
6868+6969+#[jacquard_derive::lexicon]
7070+#[derive(
7171+ serde::Serialize,
7272+ serde::Deserialize,
7373+ Debug,
7474+ Clone,
7575+ PartialEq,
7676+ Eq,
7777+ jacquard_derive::IntoStatic,
7878+ Default
7979+)]
8080+#[serde(rename_all = "camelCase")]
8181+pub struct TemporaryLinkView<'a> {
8282+ /// The temporary link to access the file.
8383+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
8484+ #[serde(borrow)]
8585+ pub link: std::option::Option<jacquard_common::types::string::Uri<'a>>,
8686+}
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: app.rocksky.like.likeSong
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+ Default
1818+)]
1919+#[serde(rename_all = "camelCase")]
2020+pub struct LikeSong<'a> {
2121+ /// The unique identifier of the song to like
2222+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2323+ #[serde(borrow)]
2424+ pub uri: std::option::Option<jacquard_common::types::string::AtUri<'a>>,
2525+}
2626+2727+#[jacquard_derive::lexicon]
2828+#[derive(
2929+ serde::Serialize,
3030+ serde::Deserialize,
3131+ Debug,
3232+ Clone,
3333+ PartialEq,
3434+ Eq,
3535+ jacquard_derive::IntoStatic
3636+)]
3737+#[serde(rename_all = "camelCase")]
3838+pub struct LikeSongOutput<'a> {
3939+ #[serde(flatten)]
4040+ #[serde(borrow)]
4141+ pub value: crate::app_rocksky::song::SongViewDetailed<'a>,
4242+}
4343+4444+///Response type for
4545+///app.rocksky.like.likeSong
4646+pub struct LikeSongResponse;
4747+impl jacquard_common::xrpc::XrpcResp for LikeSongResponse {
4848+ const NSID: &'static str = "app.rocksky.like.likeSong";
4949+ const ENCODING: &'static str = "application/json";
5050+ type Output<'de> = LikeSongOutput<'de>;
5151+ type Err<'de> = jacquard_common::xrpc::GenericError<'de>;
5252+}
5353+5454+impl<'a> jacquard_common::xrpc::XrpcRequest for LikeSong<'a> {
5555+ const NSID: &'static str = "app.rocksky.like.likeSong";
5656+ const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Procedure(
5757+ "application/json",
5858+ );
5959+ type Response = LikeSongResponse;
6060+}
6161+6262+///Endpoint type for
6363+///app.rocksky.like.likeSong
6464+pub struct LikeSongRequest;
6565+impl jacquard_common::xrpc::XrpcEndpoint for LikeSongRequest {
6666+ const PATH: &'static str = "/xrpc/app.rocksky.like.likeSong";
6767+ const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Procedure(
6868+ "application/json",
6969+ );
7070+ type Request<'de> = LikeSong<'de>;
7171+ type Response = LikeSongResponse;
7272+}
+32
crates/jacquard-api/src/app_rocksky/player.rs
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: app.rocksky.player.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_currently_playing;
99+pub mod next;
1010+pub mod pause;
1111+pub mod play;
1212+pub mod previous;
1313+pub mod seek;
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 CurrentlyPlayingViewDetailed<'a> {
2828+ /// The title of the currently playing track
2929+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3030+ #[serde(borrow)]
3131+ pub title: std::option::Option<jacquard_common::CowStr<'a>>,
3232+}
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: app.rocksky.player.seek
44+//
55+// This file was automatically generated from Lexicon schemas.
66+// Any manual changes will be overwritten on the next regeneration.
77+88+#[derive(
99+ serde::Serialize,
1010+ serde::Deserialize,
1111+ Debug,
1212+ Clone,
1313+ PartialEq,
1414+ Eq,
1515+ bon::Builder,
1616+ jacquard_derive::IntoStatic
1717+)]
1818+#[builder(start_fn = new)]
1919+#[serde(rename_all = "camelCase")]
2020+pub struct SeekParams {
2121+ pub position: i64,
2222+}
2323+2424+/// XRPC request marker type
2525+#[derive(
2626+ Debug,
2727+ Clone,
2828+ Copy,
2929+ PartialEq,
3030+ Eq,
3131+ serde::Serialize,
3232+ serde::Deserialize,
3333+ jacquard_derive::IntoStatic
3434+)]
3535+pub struct Seek;
3636+///Response type for
3737+///app.rocksky.player.seek
3838+pub struct SeekResponse;
3939+impl jacquard_common::xrpc::XrpcResp for SeekResponse {
4040+ const NSID: &'static str = "app.rocksky.player.seek";
4141+ const ENCODING: &'static str = "application/json";
4242+ type Output<'de> = ();
4343+ type Err<'de> = jacquard_common::xrpc::GenericError<'de>;
4444+}
4545+4646+impl jacquard_common::xrpc::XrpcRequest for Seek {
4747+ const NSID: &'static str = "app.rocksky.player.seek";
4848+ const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Procedure(
4949+ "application/json",
5050+ );
5151+ type Response = SeekResponse;
5252+}
5353+5454+///Endpoint type for
5555+///app.rocksky.player.seek
5656+pub struct SeekRequest;
5757+impl jacquard_common::xrpc::XrpcEndpoint for SeekRequest {
5858+ const PATH: &'static str = "/xrpc/app.rocksky.player.seek";
5959+ const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Procedure(
6060+ "application/json",
6161+ );
6262+ type Request<'de> = Seek;
6363+ type Response = SeekResponse;
6464+}
+233
crates/jacquard-api/src/app_rocksky/playlist.rs
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: app.rocksky.playlist.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_playlist;
99+pub mod get_playlists;
1010+1111+/// A declaration of a playlist.
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+ bon::Builder
2222+)]
2323+#[serde(rename_all = "camelCase")]
2424+pub struct Playlist<'a> {
2525+ /// The Apple Music link of the playlist.
2626+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2727+ #[builder(into)]
2828+ #[serde(borrow)]
2929+ pub apple_music_link: Option<jacquard_common::CowStr<'a>>,
3030+ /// The date the playlist was created.
3131+ pub created_at: jacquard_common::types::string::Datetime,
3232+ /// The playlist description.
3333+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3434+ #[builder(into)]
3535+ #[serde(borrow)]
3636+ pub description: Option<jacquard_common::CowStr<'a>>,
3737+ /// The name of the playlist.
3838+ #[serde(borrow)]
3939+ #[builder(into)]
4040+ pub name: jacquard_common::CowStr<'a>,
4141+ /// The picture of the playlist.
4242+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
4343+ #[builder(into)]
4444+ #[serde(borrow)]
4545+ pub picture: Option<jacquard_common::types::blob::Blob<'a>>,
4646+ /// The Spotify link of the playlist.
4747+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
4848+ #[builder(into)]
4949+ #[serde(borrow)]
5050+ pub spotify_link: Option<jacquard_common::CowStr<'a>>,
5151+ /// The Tidal link of the playlist.
5252+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5353+ #[builder(into)]
5454+ #[serde(borrow)]
5555+ pub tidal_link: Option<jacquard_common::CowStr<'a>>,
5656+ /// The tracks in the playlist.
5757+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5858+ #[builder(into)]
5959+ #[serde(borrow)]
6060+ pub tracks: Option<Vec<jacquard_common::types::value::Data<'a>>>,
6161+ /// The YouTube link of the playlist.
6262+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
6363+ #[builder(into)]
6464+ #[serde(borrow)]
6565+ pub youtube_link: Option<jacquard_common::CowStr<'a>>,
6666+}
6767+6868+/// Typed wrapper for GetRecord response with this collection's record type.
6969+#[derive(
7070+ serde::Serialize,
7171+ serde::Deserialize,
7272+ Debug,
7373+ Clone,
7474+ PartialEq,
7575+ Eq,
7676+ jacquard_derive::IntoStatic
7777+)]
7878+#[serde(rename_all = "camelCase")]
7979+pub struct PlaylistGetRecordOutput<'a> {
8080+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
8181+ #[serde(borrow)]
8282+ pub cid: std::option::Option<jacquard_common::types::string::Cid<'a>>,
8383+ #[serde(borrow)]
8484+ pub uri: jacquard_common::types::string::AtUri<'a>,
8585+ #[serde(borrow)]
8686+ pub value: Playlist<'a>,
8787+}
8888+8989+/// Marker type for deserializing records from this collection.
9090+pub struct PlaylistRecord;
9191+impl jacquard_common::xrpc::XrpcResp for PlaylistRecord {
9292+ const NSID: &'static str = "app.rocksky.playlist";
9393+ const ENCODING: &'static str = "application/json";
9494+ type Output<'de> = PlaylistGetRecordOutput<'de>;
9595+ type Err<'de> = jacquard_common::types::collection::RecordError<'de>;
9696+}
9797+9898+impl jacquard_common::types::collection::Collection for Playlist<'_> {
9999+ const NSID: &'static str = "app.rocksky.playlist";
100100+ type Record = PlaylistRecord;
101101+}
102102+103103+impl From<PlaylistGetRecordOutput<'_>> for Playlist<'_> {
104104+ fn from(output: PlaylistGetRecordOutput<'_>) -> Self {
105105+ use jacquard_common::IntoStatic;
106106+ output.value.into_static()
107107+ }
108108+}
109109+110110+/// Basic view of a playlist, including its metadata
111111+#[jacquard_derive::lexicon]
112112+#[derive(
113113+ serde::Serialize,
114114+ serde::Deserialize,
115115+ Debug,
116116+ Clone,
117117+ PartialEq,
118118+ Eq,
119119+ jacquard_derive::IntoStatic,
120120+ Default
121121+)]
122122+#[serde(rename_all = "camelCase")]
123123+pub struct PlaylistViewBasic<'a> {
124124+ /// The URL of the cover image for the playlist.
125125+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
126126+ #[serde(borrow)]
127127+ pub cover_image_url: std::option::Option<jacquard_common::types::string::Uri<'a>>,
128128+ /// The date and time when the playlist was created.
129129+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
130130+ pub created_at: std::option::Option<jacquard_common::types::string::Datetime>,
131131+ /// The URL of the avatar image of the curator.
132132+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
133133+ #[serde(borrow)]
134134+ pub curator_avatar_url: std::option::Option<jacquard_common::types::string::Uri<'a>>,
135135+ /// The DID of the curator of the playlist.
136136+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
137137+ #[serde(borrow)]
138138+ pub curator_did: std::option::Option<
139139+ jacquard_common::types::ident::AtIdentifier<'a>,
140140+ >,
141141+ /// The handle of the curator of the playlist.
142142+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
143143+ #[serde(borrow)]
144144+ pub curator_handle: std::option::Option<
145145+ jacquard_common::types::ident::AtIdentifier<'a>,
146146+ >,
147147+ /// The name of the curator of the playlist.
148148+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
149149+ #[serde(borrow)]
150150+ pub curator_name: std::option::Option<jacquard_common::CowStr<'a>>,
151151+ /// A description of the playlist.
152152+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
153153+ #[serde(borrow)]
154154+ pub description: std::option::Option<jacquard_common::CowStr<'a>>,
155155+ /// The unique identifier of the playlist.
156156+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
157157+ #[serde(borrow)]
158158+ pub id: std::option::Option<jacquard_common::CowStr<'a>>,
159159+ /// The title of the playlist.
160160+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
161161+ #[serde(borrow)]
162162+ pub title: std::option::Option<jacquard_common::CowStr<'a>>,
163163+ /// The number of tracks in the playlist.
164164+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
165165+ pub track_count: std::option::Option<i64>,
166166+ /// The URI of the playlist.
167167+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
168168+ #[serde(borrow)]
169169+ pub uri: std::option::Option<jacquard_common::types::string::AtUri<'a>>,
170170+}
171171+172172+/// Detailed view of a playlist, including its tracks and metadata
173173+#[jacquard_derive::lexicon]
174174+#[derive(
175175+ serde::Serialize,
176176+ serde::Deserialize,
177177+ Debug,
178178+ Clone,
179179+ PartialEq,
180180+ Eq,
181181+ jacquard_derive::IntoStatic,
182182+ Default
183183+)]
184184+#[serde(rename_all = "camelCase")]
185185+pub struct PlaylistViewDetailed<'a> {
186186+ /// The URL of the cover image for the playlist.
187187+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
188188+ #[serde(borrow)]
189189+ pub cover_image_url: std::option::Option<jacquard_common::types::string::Uri<'a>>,
190190+ /// The date and time when the playlist was created.
191191+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
192192+ pub created_at: std::option::Option<jacquard_common::types::string::Datetime>,
193193+ /// The URL of the avatar image of the curator.
194194+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
195195+ #[serde(borrow)]
196196+ pub curator_avatar_url: std::option::Option<jacquard_common::types::string::Uri<'a>>,
197197+ /// The DID of the curator of the playlist.
198198+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
199199+ #[serde(borrow)]
200200+ pub curator_did: std::option::Option<
201201+ jacquard_common::types::ident::AtIdentifier<'a>,
202202+ >,
203203+ /// The handle of the curator of the playlist.
204204+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
205205+ #[serde(borrow)]
206206+ pub curator_handle: std::option::Option<
207207+ jacquard_common::types::ident::AtIdentifier<'a>,
208208+ >,
209209+ /// The name of the curator of the playlist.
210210+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
211211+ #[serde(borrow)]
212212+ pub curator_name: std::option::Option<jacquard_common::CowStr<'a>>,
213213+ /// A description of the playlist.
214214+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
215215+ #[serde(borrow)]
216216+ pub description: std::option::Option<jacquard_common::CowStr<'a>>,
217217+ /// The unique identifier of the playlist.
218218+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
219219+ #[serde(borrow)]
220220+ pub id: std::option::Option<jacquard_common::CowStr<'a>>,
221221+ /// The title of the playlist.
222222+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
223223+ #[serde(borrow)]
224224+ pub title: std::option::Option<jacquard_common::CowStr<'a>>,
225225+ /// A list of tracks in the playlist.
226226+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
227227+ #[serde(borrow)]
228228+ pub tracks: std::option::Option<Vec<crate::app_rocksky::song::SongViewBasic<'a>>>,
229229+ /// The URI of the playlist.
230230+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
231231+ #[serde(borrow)]
232232+ pub uri: std::option::Option<jacquard_common::types::string::AtUri<'a>>,
233233+}
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: app.rocksky.playlist.getPlaylists
44+//
55+// This file was automatically generated from Lexicon schemas.
66+// Any manual changes will be overwritten on the next regeneration.
77+88+#[derive(
99+ serde::Serialize,
1010+ serde::Deserialize,
1111+ Debug,
1212+ Clone,
1313+ PartialEq,
1414+ Eq,
1515+ bon::Builder,
1616+ jacquard_derive::IntoStatic
1717+)]
1818+#[builder(start_fn = new)]
1919+#[serde(rename_all = "camelCase")]
2020+pub struct GetPlaylists {
2121+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2222+ pub limit: std::option::Option<i64>,
2323+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2424+ pub offset: std::option::Option<i64>,
2525+}
2626+2727+#[jacquard_derive::lexicon]
2828+#[derive(
2929+ serde::Serialize,
3030+ serde::Deserialize,
3131+ Debug,
3232+ Clone,
3333+ PartialEq,
3434+ Eq,
3535+ jacquard_derive::IntoStatic,
3636+ Default
3737+)]
3838+#[serde(rename_all = "camelCase")]
3939+pub struct GetPlaylistsOutput<'a> {
4040+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
4141+ #[serde(borrow)]
4242+ pub playlists: std::option::Option<
4343+ Vec<crate::app_rocksky::playlist::PlaylistViewBasic<'a>>,
4444+ >,
4545+}
4646+4747+///Response type for
4848+///app.rocksky.playlist.getPlaylists
4949+pub struct GetPlaylistsResponse;
5050+impl jacquard_common::xrpc::XrpcResp for GetPlaylistsResponse {
5151+ const NSID: &'static str = "app.rocksky.playlist.getPlaylists";
5252+ const ENCODING: &'static str = "application/json";
5353+ type Output<'de> = GetPlaylistsOutput<'de>;
5454+ type Err<'de> = jacquard_common::xrpc::GenericError<'de>;
5555+}
5656+5757+impl jacquard_common::xrpc::XrpcRequest for GetPlaylists {
5858+ const NSID: &'static str = "app.rocksky.playlist.getPlaylists";
5959+ const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Query;
6060+ type Response = GetPlaylistsResponse;
6161+}
6262+6363+///Endpoint type for
6464+///app.rocksky.playlist.getPlaylists
6565+pub struct GetPlaylistsRequest;
6666+impl jacquard_common::xrpc::XrpcEndpoint for GetPlaylistsRequest {
6767+ const PATH: &'static str = "/xrpc/app.rocksky.playlist.getPlaylists";
6868+ const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Query;
6969+ type Request<'de> = GetPlaylists;
7070+ type Response = GetPlaylistsResponse;
7171+}
+169
crates/jacquard-api/src/app_rocksky/radio.rs
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: app.rocksky.radio.defs
44+//
55+// This file was automatically generated from Lexicon schemas.
66+// Any manual changes will be overwritten on the next regeneration.
77+88+/// A declaration of a radio station.
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 Radio<'a> {
2222+ /// The date when the radio station was created.
2323+ pub created_at: jacquard_common::types::string::Datetime,
2424+ /// A description of the radio station.
2525+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2626+ #[builder(into)]
2727+ #[serde(borrow)]
2828+ pub description: Option<jacquard_common::CowStr<'a>>,
2929+ /// The genre of the radio station.
3030+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3131+ #[builder(into)]
3232+ #[serde(borrow)]
3333+ pub genre: Option<jacquard_common::CowStr<'a>>,
3434+ /// The logo of the radio station.
3535+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3636+ #[builder(into)]
3737+ #[serde(borrow)]
3838+ pub logo: Option<jacquard_common::types::blob::Blob<'a>>,
3939+ /// The name of the radio station.
4040+ #[serde(borrow)]
4141+ #[builder(into)]
4242+ pub name: jacquard_common::CowStr<'a>,
4343+ /// The URL of the radio station.
4444+ #[serde(borrow)]
4545+ pub url: jacquard_common::types::string::Uri<'a>,
4646+ /// The website of the radio station.
4747+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
4848+ #[builder(into)]
4949+ #[serde(borrow)]
5050+ pub website: Option<jacquard_common::types::string::Uri<'a>>,
5151+}
5252+5353+/// Typed wrapper for GetRecord response with this collection's record type.
5454+#[derive(
5555+ serde::Serialize,
5656+ serde::Deserialize,
5757+ Debug,
5858+ Clone,
5959+ PartialEq,
6060+ Eq,
6161+ jacquard_derive::IntoStatic
6262+)]
6363+#[serde(rename_all = "camelCase")]
6464+pub struct RadioGetRecordOutput<'a> {
6565+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
6666+ #[serde(borrow)]
6767+ pub cid: std::option::Option<jacquard_common::types::string::Cid<'a>>,
6868+ #[serde(borrow)]
6969+ pub uri: jacquard_common::types::string::AtUri<'a>,
7070+ #[serde(borrow)]
7171+ pub value: Radio<'a>,
7272+}
7373+7474+/// Marker type for deserializing records from this collection.
7575+pub struct RadioRecord;
7676+impl jacquard_common::xrpc::XrpcResp for RadioRecord {
7777+ const NSID: &'static str = "app.rocksky.radio";
7878+ const ENCODING: &'static str = "application/json";
7979+ type Output<'de> = RadioGetRecordOutput<'de>;
8080+ type Err<'de> = jacquard_common::types::collection::RecordError<'de>;
8181+}
8282+8383+impl jacquard_common::types::collection::Collection for Radio<'_> {
8484+ const NSID: &'static str = "app.rocksky.radio";
8585+ type Record = RadioRecord;
8686+}
8787+8888+impl From<RadioGetRecordOutput<'_>> for Radio<'_> {
8989+ fn from(output: RadioGetRecordOutput<'_>) -> Self {
9090+ use jacquard_common::IntoStatic;
9191+ output.value.into_static()
9292+ }
9393+}
9494+9595+#[jacquard_derive::lexicon]
9696+#[derive(
9797+ serde::Serialize,
9898+ serde::Deserialize,
9999+ Debug,
100100+ Clone,
101101+ PartialEq,
102102+ Eq,
103103+ jacquard_derive::IntoStatic,
104104+ Default
105105+)]
106106+#[serde(rename_all = "camelCase")]
107107+pub struct RadioViewBasic<'a> {
108108+ /// The date and time when the radio was created.
109109+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
110110+ pub created_at: std::option::Option<jacquard_common::types::string::Datetime>,
111111+ /// A brief description of the radio.
112112+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
113113+ #[serde(borrow)]
114114+ pub description: std::option::Option<jacquard_common::CowStr<'a>>,
115115+ /// The unique identifier of the radio.
116116+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
117117+ #[serde(borrow)]
118118+ pub id: std::option::Option<jacquard_common::CowStr<'a>>,
119119+ /// The name of the radio.
120120+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
121121+ #[serde(borrow)]
122122+ pub name: std::option::Option<jacquard_common::CowStr<'a>>,
123123+}
124124+125125+#[jacquard_derive::lexicon]
126126+#[derive(
127127+ serde::Serialize,
128128+ serde::Deserialize,
129129+ Debug,
130130+ Clone,
131131+ PartialEq,
132132+ Eq,
133133+ jacquard_derive::IntoStatic,
134134+ Default
135135+)]
136136+#[serde(rename_all = "camelCase")]
137137+pub struct RadioViewDetailed<'a> {
138138+ /// The date and time when the radio was created.
139139+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
140140+ pub created_at: std::option::Option<jacquard_common::types::string::Datetime>,
141141+ /// A brief description of the radio.
142142+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
143143+ #[serde(borrow)]
144144+ pub description: std::option::Option<jacquard_common::CowStr<'a>>,
145145+ /// The genre of the radio.
146146+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
147147+ #[serde(borrow)]
148148+ pub genre: std::option::Option<jacquard_common::CowStr<'a>>,
149149+ /// The unique identifier of the radio.
150150+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
151151+ #[serde(borrow)]
152152+ pub id: std::option::Option<jacquard_common::CowStr<'a>>,
153153+ /// The logo of the radio station.
154154+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
155155+ #[serde(borrow)]
156156+ pub logo: std::option::Option<jacquard_common::CowStr<'a>>,
157157+ /// The name of the radio.
158158+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
159159+ #[serde(borrow)]
160160+ pub name: std::option::Option<jacquard_common::CowStr<'a>>,
161161+ /// The streaming URL of the radio.
162162+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
163163+ #[serde(borrow)]
164164+ pub url: std::option::Option<jacquard_common::types::string::Uri<'a>>,
165165+ /// The website of the radio.
166166+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
167167+ #[serde(borrow)]
168168+ pub website: std::option::Option<jacquard_common::types::string::Uri<'a>>,
169169+}
+291
crates/jacquard-api/src/app_rocksky/scrobble.rs
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: app.rocksky.scrobble.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 create_scrobble;
99+pub mod get_scrobble;
1010+pub mod get_scrobbles;
1111+1212+/// A declaration of a scrobble.
1313+#[jacquard_derive::lexicon]
1414+#[derive(
1515+ serde::Serialize,
1616+ serde::Deserialize,
1717+ Debug,
1818+ Clone,
1919+ PartialEq,
2020+ Eq,
2121+ jacquard_derive::IntoStatic,
2222+ bon::Builder
2323+)]
2424+#[serde(rename_all = "camelCase")]
2525+pub struct Scrobble<'a> {
2626+ /// The album of the song.
2727+ #[serde(borrow)]
2828+ #[builder(into)]
2929+ pub album: jacquard_common::CowStr<'a>,
3030+ /// The album art of the song.
3131+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3232+ #[builder(into)]
3333+ #[serde(borrow)]
3434+ pub album_art: Option<jacquard_common::types::blob::Blob<'a>>,
3535+ /// The album artist of the song.
3636+ #[serde(borrow)]
3737+ #[builder(into)]
3838+ pub album_artist: jacquard_common::CowStr<'a>,
3939+ /// The Apple Music link of the song.
4040+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
4141+ #[builder(into)]
4242+ #[serde(borrow)]
4343+ pub apple_music_link: Option<jacquard_common::types::string::Uri<'a>>,
4444+ /// The artist of the song.
4545+ #[serde(borrow)]
4646+ #[builder(into)]
4747+ pub artist: jacquard_common::CowStr<'a>,
4848+ /// The composer of the song.
4949+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5050+ #[builder(into)]
5151+ #[serde(borrow)]
5252+ pub composer: Option<jacquard_common::CowStr<'a>>,
5353+ /// The copyright message of the song.
5454+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5555+ #[builder(into)]
5656+ #[serde(borrow)]
5757+ pub copyright_message: Option<jacquard_common::CowStr<'a>>,
5858+ /// The date when the song was created.
5959+ pub created_at: jacquard_common::types::string::Datetime,
6060+ /// The disc number of the song in the album.
6161+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
6262+ #[builder(into)]
6363+ pub disc_number: Option<i64>,
6464+ /// The duration of the song in seconds.
6565+ pub duration: i64,
6666+ /// The genre of the song.
6767+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
6868+ #[builder(into)]
6969+ #[serde(borrow)]
7070+ pub genre: Option<jacquard_common::CowStr<'a>>,
7171+ /// The label of the song.
7272+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
7373+ #[builder(into)]
7474+ #[serde(borrow)]
7575+ pub label: Option<jacquard_common::CowStr<'a>>,
7676+ /// The lyrics of the song.
7777+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
7878+ #[builder(into)]
7979+ #[serde(borrow)]
8080+ pub lyrics: Option<jacquard_common::CowStr<'a>>,
8181+ /// The MusicBrainz ID of the song.
8282+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
8383+ #[builder(into)]
8484+ #[serde(borrow)]
8585+ pub mbid: Option<jacquard_common::CowStr<'a>>,
8686+ /// The release date of the song.
8787+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
8888+ #[builder(into)]
8989+ pub release_date: Option<jacquard_common::types::string::Datetime>,
9090+ /// The Spotify link of the song.
9191+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
9292+ #[builder(into)]
9393+ #[serde(borrow)]
9494+ pub spotify_link: Option<jacquard_common::types::string::Uri<'a>>,
9595+ /// The tags of the song.
9696+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
9797+ #[builder(into)]
9898+ #[serde(borrow)]
9999+ pub tags: Option<Vec<jacquard_common::CowStr<'a>>>,
100100+ /// The Tidal link of the song.
101101+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
102102+ #[builder(into)]
103103+ #[serde(borrow)]
104104+ pub tidal_link: Option<jacquard_common::types::string::Uri<'a>>,
105105+ /// The title of the song.
106106+ #[serde(borrow)]
107107+ #[builder(into)]
108108+ pub title: jacquard_common::CowStr<'a>,
109109+ /// The track number of the song in the album.
110110+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
111111+ #[builder(into)]
112112+ pub track_number: Option<i64>,
113113+ /// Informations about the song
114114+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
115115+ #[builder(into)]
116116+ #[serde(borrow)]
117117+ pub wiki: Option<jacquard_common::CowStr<'a>>,
118118+ /// The year the song was released.
119119+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
120120+ #[builder(into)]
121121+ pub year: Option<i64>,
122122+ /// The YouTube link of the song.
123123+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
124124+ #[builder(into)]
125125+ #[serde(borrow)]
126126+ pub youtube_link: Option<jacquard_common::types::string::Uri<'a>>,
127127+}
128128+129129+/// Typed wrapper for GetRecord response with this collection's record type.
130130+#[derive(
131131+ serde::Serialize,
132132+ serde::Deserialize,
133133+ Debug,
134134+ Clone,
135135+ PartialEq,
136136+ Eq,
137137+ jacquard_derive::IntoStatic
138138+)]
139139+#[serde(rename_all = "camelCase")]
140140+pub struct ScrobbleGetRecordOutput<'a> {
141141+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
142142+ #[serde(borrow)]
143143+ pub cid: std::option::Option<jacquard_common::types::string::Cid<'a>>,
144144+ #[serde(borrow)]
145145+ pub uri: jacquard_common::types::string::AtUri<'a>,
146146+ #[serde(borrow)]
147147+ pub value: Scrobble<'a>,
148148+}
149149+150150+/// Marker type for deserializing records from this collection.
151151+pub struct ScrobbleRecord;
152152+impl jacquard_common::xrpc::XrpcResp for ScrobbleRecord {
153153+ const NSID: &'static str = "app.rocksky.scrobble";
154154+ const ENCODING: &'static str = "application/json";
155155+ type Output<'de> = ScrobbleGetRecordOutput<'de>;
156156+ type Err<'de> = jacquard_common::types::collection::RecordError<'de>;
157157+}
158158+159159+impl jacquard_common::types::collection::Collection for Scrobble<'_> {
160160+ const NSID: &'static str = "app.rocksky.scrobble";
161161+ type Record = ScrobbleRecord;
162162+}
163163+164164+impl From<ScrobbleGetRecordOutput<'_>> for Scrobble<'_> {
165165+ fn from(output: ScrobbleGetRecordOutput<'_>) -> Self {
166166+ use jacquard_common::IntoStatic;
167167+ output.value.into_static()
168168+ }
169169+}
170170+171171+#[jacquard_derive::lexicon]
172172+#[derive(
173173+ serde::Serialize,
174174+ serde::Deserialize,
175175+ Debug,
176176+ Clone,
177177+ PartialEq,
178178+ Eq,
179179+ jacquard_derive::IntoStatic,
180180+ Default
181181+)]
182182+#[serde(rename_all = "camelCase")]
183183+pub struct ScrobbleViewBasic<'a> {
184184+ /// The album of the song.
185185+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
186186+ #[serde(borrow)]
187187+ pub album: std::option::Option<jacquard_common::CowStr<'a>>,
188188+ /// The URI of the album.
189189+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
190190+ #[serde(borrow)]
191191+ pub album_uri: std::option::Option<jacquard_common::types::string::AtUri<'a>>,
192192+ /// The artist of the song.
193193+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
194194+ #[serde(borrow)]
195195+ pub artist: std::option::Option<jacquard_common::CowStr<'a>>,
196196+ /// The URI of the artist.
197197+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
198198+ #[serde(borrow)]
199199+ pub artist_uri: std::option::Option<jacquard_common::types::string::AtUri<'a>>,
200200+ /// The album art URL of the song.
201201+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
202202+ #[serde(borrow)]
203203+ pub cover: std::option::Option<jacquard_common::types::string::Uri<'a>>,
204204+ /// The timestamp when the scrobble was created.
205205+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
206206+ pub date: std::option::Option<jacquard_common::types::string::Datetime>,
207207+ /// The unique identifier of the scrobble.
208208+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
209209+ #[serde(borrow)]
210210+ pub id: std::option::Option<jacquard_common::CowStr<'a>>,
211211+ /// The SHA256 hash of the scrobble data.
212212+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
213213+ #[serde(borrow)]
214214+ pub sha256: std::option::Option<jacquard_common::CowStr<'a>>,
215215+ /// The title of the scrobble.
216216+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
217217+ #[serde(borrow)]
218218+ pub title: std::option::Option<jacquard_common::CowStr<'a>>,
219219+ /// The URI of the scrobble.
220220+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
221221+ #[serde(borrow)]
222222+ pub uri: std::option::Option<jacquard_common::types::string::Uri<'a>>,
223223+ /// The handle of the user who created the scrobble.
224224+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
225225+ #[serde(borrow)]
226226+ pub user: std::option::Option<jacquard_common::CowStr<'a>>,
227227+}
228228+229229+#[jacquard_derive::lexicon]
230230+#[derive(
231231+ serde::Serialize,
232232+ serde::Deserialize,
233233+ Debug,
234234+ Clone,
235235+ PartialEq,
236236+ Eq,
237237+ jacquard_derive::IntoStatic,
238238+ Default
239239+)]
240240+#[serde(rename_all = "camelCase")]
241241+pub struct ScrobbleViewDetailed<'a> {
242242+ /// The album of the song.
243243+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
244244+ #[serde(borrow)]
245245+ pub album: std::option::Option<jacquard_common::CowStr<'a>>,
246246+ /// The URI of the album.
247247+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
248248+ #[serde(borrow)]
249249+ pub album_uri: std::option::Option<jacquard_common::types::string::AtUri<'a>>,
250250+ /// The artist of the song.
251251+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
252252+ #[serde(borrow)]
253253+ pub artist: std::option::Option<jacquard_common::CowStr<'a>>,
254254+ /// The URI of the artist.
255255+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
256256+ #[serde(borrow)]
257257+ pub artist_uri: std::option::Option<jacquard_common::types::string::AtUri<'a>>,
258258+ /// The album art URL of the song.
259259+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
260260+ #[serde(borrow)]
261261+ pub cover: std::option::Option<jacquard_common::types::string::Uri<'a>>,
262262+ /// The timestamp when the scrobble was created.
263263+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
264264+ pub date: std::option::Option<jacquard_common::types::string::Datetime>,
265265+ /// The unique identifier of the scrobble.
266266+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
267267+ #[serde(borrow)]
268268+ pub id: std::option::Option<jacquard_common::CowStr<'a>>,
269269+ /// The number of listeners
270270+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
271271+ pub listeners: std::option::Option<i64>,
272272+ /// The number of scrobbles for this song
273273+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
274274+ pub scrobbles: std::option::Option<i64>,
275275+ /// The SHA256 hash of the scrobble data.
276276+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
277277+ #[serde(borrow)]
278278+ pub sha256: std::option::Option<jacquard_common::CowStr<'a>>,
279279+ /// The title of the scrobble.
280280+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
281281+ #[serde(borrow)]
282282+ pub title: std::option::Option<jacquard_common::CowStr<'a>>,
283283+ /// The URI of the scrobble.
284284+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
285285+ #[serde(borrow)]
286286+ pub uri: std::option::Option<jacquard_common::types::string::Uri<'a>>,
287287+ /// The handle of the user who created the scrobble.
288288+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
289289+ #[serde(borrow)]
290290+ pub user: std::option::Option<jacquard_common::CowStr<'a>>,
291291+}
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: app.rocksky.scrobble.createScrobble
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+ Default
1818+)]
1919+#[serde(rename_all = "camelCase")]
2020+pub struct CreateScrobble<'a> {
2121+ /// The album of the track being scrobbled
2222+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2323+ #[serde(borrow)]
2424+ pub album: std::option::Option<jacquard_common::CowStr<'a>>,
2525+ /// The URL of the album art for the track
2626+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2727+ #[serde(borrow)]
2828+ pub album_art: std::option::Option<jacquard_common::types::string::Uri<'a>>,
2929+ /// The Apple Music link for the track, if available
3030+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3131+ #[serde(borrow)]
3232+ pub apple_music_link: std::option::Option<jacquard_common::types::string::Uri<'a>>,
3333+ /// The artist of the track being scrobbled
3434+ #[serde(borrow)]
3535+ pub artist: jacquard_common::CowStr<'a>,
3636+ /// The URL of the artist's picture, if available
3737+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3838+ #[serde(borrow)]
3939+ pub artist_picture: std::option::Option<jacquard_common::types::string::Uri<'a>>,
4040+ /// The composer of the track, if available
4141+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
4242+ #[serde(borrow)]
4343+ pub composer: std::option::Option<jacquard_common::CowStr<'a>>,
4444+ /// The copyright message for the track, if available
4545+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
4646+ #[serde(borrow)]
4747+ pub copyright_message: std::option::Option<jacquard_common::CowStr<'a>>,
4848+ /// The Deezer link for the track, if available
4949+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5050+ #[serde(borrow)]
5151+ pub deezer_link: std::option::Option<jacquard_common::types::string::Uri<'a>>,
5252+ /// The disc number of the track in the album, if applicable
5353+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5454+ pub disc_number: std::option::Option<i64>,
5555+ /// The duration of the track in seconds
5656+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5757+ pub duration: std::option::Option<i64>,
5858+ /// The record label of the track, if available
5959+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
6060+ #[serde(borrow)]
6161+ pub label: std::option::Option<jacquard_common::CowStr<'a>>,
6262+ /// The Last.fm link for the track, if available
6363+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
6464+ #[serde(borrow)]
6565+ pub lastfm_link: std::option::Option<jacquard_common::types::string::Uri<'a>>,
6666+ /// The lyrics of the track, if available
6767+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
6868+ #[serde(borrow)]
6969+ pub lyrics: std::option::Option<jacquard_common::CowStr<'a>>,
7070+ /// The MusicBrainz ID of the track, if available
7171+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
7272+ #[serde(borrow)]
7373+ pub mb_id: std::option::Option<jacquard_common::CowStr<'a>>,
7474+ /// The release date of the track, formatted as YYYY-MM-DD
7575+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
7676+ #[serde(borrow)]
7777+ pub release_date: std::option::Option<jacquard_common::CowStr<'a>>,
7878+ /// The Spotify link for the track, if available
7979+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
8080+ #[serde(borrow)]
8181+ pub spotify_link: std::option::Option<jacquard_common::types::string::Uri<'a>>,
8282+ /// The Tidal link for the track, if available
8383+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
8484+ #[serde(borrow)]
8585+ pub tidal_link: std::option::Option<jacquard_common::types::string::Uri<'a>>,
8686+ /// The timestamp of the scrobble in milliseconds since epoch
8787+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
8888+ pub timestamp: std::option::Option<i64>,
8989+ /// The title of the track being scrobbled
9090+ #[serde(borrow)]
9191+ pub title: jacquard_common::CowStr<'a>,
9292+ /// The track number of the track in the album
9393+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
9494+ pub track_number: std::option::Option<i64>,
9595+ /// The year the track was released
9696+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
9797+ pub year: std::option::Option<i64>,
9898+ /// The Youtube link for the track, if available
9999+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
100100+ #[serde(borrow)]
101101+ pub youtube_link: std::option::Option<jacquard_common::types::string::Uri<'a>>,
102102+}
103103+104104+#[jacquard_derive::lexicon]
105105+#[derive(
106106+ serde::Serialize,
107107+ serde::Deserialize,
108108+ Debug,
109109+ Clone,
110110+ PartialEq,
111111+ Eq,
112112+ jacquard_derive::IntoStatic
113113+)]
114114+#[serde(rename_all = "camelCase")]
115115+pub struct CreateScrobbleOutput<'a> {
116116+ #[serde(flatten)]
117117+ #[serde(borrow)]
118118+ pub value: crate::app_rocksky::scrobble::ScrobbleViewBasic<'a>,
119119+}
120120+121121+///Response type for
122122+///app.rocksky.scrobble.createScrobble
123123+pub struct CreateScrobbleResponse;
124124+impl jacquard_common::xrpc::XrpcResp for CreateScrobbleResponse {
125125+ const NSID: &'static str = "app.rocksky.scrobble.createScrobble";
126126+ const ENCODING: &'static str = "application/json";
127127+ type Output<'de> = CreateScrobbleOutput<'de>;
128128+ type Err<'de> = jacquard_common::xrpc::GenericError<'de>;
129129+}
130130+131131+impl<'a> jacquard_common::xrpc::XrpcRequest for CreateScrobble<'a> {
132132+ const NSID: &'static str = "app.rocksky.scrobble.createScrobble";
133133+ const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Procedure(
134134+ "application/json",
135135+ );
136136+ type Response = CreateScrobbleResponse;
137137+}
138138+139139+///Endpoint type for
140140+///app.rocksky.scrobble.createScrobble
141141+pub struct CreateScrobbleRequest;
142142+impl jacquard_common::xrpc::XrpcEndpoint for CreateScrobbleRequest {
143143+ const PATH: &'static str = "/xrpc/app.rocksky.scrobble.createScrobble";
144144+ const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Procedure(
145145+ "application/json",
146146+ );
147147+ type Request<'de> = CreateScrobble<'de>;
148148+ type Response = CreateScrobbleResponse;
149149+}
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: app.rocksky.shout.reportShout
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+ Default
1818+)]
1919+#[serde(rename_all = "camelCase")]
2020+pub struct ReportShout<'a> {
2121+ /// The reason for reporting the shout
2222+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2323+ #[serde(borrow)]
2424+ pub reason: std::option::Option<jacquard_common::CowStr<'a>>,
2525+ /// The unique identifier of the shout to report
2626+ #[serde(borrow)]
2727+ pub shout_id: jacquard_common::CowStr<'a>,
2828+}
2929+3030+#[jacquard_derive::lexicon]
3131+#[derive(
3232+ serde::Serialize,
3333+ serde::Deserialize,
3434+ Debug,
3535+ Clone,
3636+ PartialEq,
3737+ Eq,
3838+ jacquard_derive::IntoStatic
3939+)]
4040+#[serde(rename_all = "camelCase")]
4141+pub struct ReportShoutOutput<'a> {
4242+ #[serde(flatten)]
4343+ #[serde(borrow)]
4444+ pub value: crate::app_rocksky::shout::ShoutView<'a>,
4545+}
4646+4747+///Response type for
4848+///app.rocksky.shout.reportShout
4949+pub struct ReportShoutResponse;
5050+impl jacquard_common::xrpc::XrpcResp for ReportShoutResponse {
5151+ const NSID: &'static str = "app.rocksky.shout.reportShout";
5252+ const ENCODING: &'static str = "application/json";
5353+ type Output<'de> = ReportShoutOutput<'de>;
5454+ type Err<'de> = jacquard_common::xrpc::GenericError<'de>;
5555+}
5656+5757+impl<'a> jacquard_common::xrpc::XrpcRequest for ReportShout<'a> {
5858+ const NSID: &'static str = "app.rocksky.shout.reportShout";
5959+ const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Procedure(
6060+ "application/json",
6161+ );
6262+ type Response = ReportShoutResponse;
6363+}
6464+6565+///Endpoint type for
6666+///app.rocksky.shout.reportShout
6767+pub struct ReportShoutRequest;
6868+impl jacquard_common::xrpc::XrpcEndpoint for ReportShoutRequest {
6969+ const PATH: &'static str = "/xrpc/app.rocksky.shout.reportShout";
7070+ const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Procedure(
7171+ "application/json",
7272+ );
7373+ type Request<'de> = ReportShout<'de>;
7474+ type Response = ReportShoutResponse;
7575+}
+315
crates/jacquard-api/src/app_rocksky/song.rs
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: app.rocksky.song.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 create_song;
99+pub mod get_song;
1010+pub mod get_songs;
1111+1212+/// A declaration of a song.
1313+#[jacquard_derive::lexicon]
1414+#[derive(
1515+ serde::Serialize,
1616+ serde::Deserialize,
1717+ Debug,
1818+ Clone,
1919+ PartialEq,
2020+ Eq,
2121+ jacquard_derive::IntoStatic,
2222+ bon::Builder
2323+)]
2424+#[serde(rename_all = "camelCase")]
2525+pub struct Song<'a> {
2626+ /// The album of the song.
2727+ #[serde(borrow)]
2828+ #[builder(into)]
2929+ pub album: jacquard_common::CowStr<'a>,
3030+ /// The album art of the song.
3131+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3232+ #[builder(into)]
3333+ #[serde(borrow)]
3434+ pub album_art: Option<jacquard_common::types::blob::Blob<'a>>,
3535+ /// The album artist of the song.
3636+ #[serde(borrow)]
3737+ #[builder(into)]
3838+ pub album_artist: jacquard_common::CowStr<'a>,
3939+ /// The Apple Music link of the song.
4040+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
4141+ #[builder(into)]
4242+ #[serde(borrow)]
4343+ pub apple_music_link: Option<jacquard_common::types::string::Uri<'a>>,
4444+ /// The artist of the song.
4545+ #[serde(borrow)]
4646+ #[builder(into)]
4747+ pub artist: jacquard_common::CowStr<'a>,
4848+ /// The composer of the song.
4949+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5050+ #[builder(into)]
5151+ #[serde(borrow)]
5252+ pub composer: Option<jacquard_common::CowStr<'a>>,
5353+ /// The copyright message of the song.
5454+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5555+ #[builder(into)]
5656+ #[serde(borrow)]
5757+ pub copyright_message: Option<jacquard_common::CowStr<'a>>,
5858+ /// The date when the song was created.
5959+ pub created_at: jacquard_common::types::string::Datetime,
6060+ /// The disc number of the song in the album.
6161+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
6262+ #[builder(into)]
6363+ pub disc_number: Option<i64>,
6464+ /// The duration of the song in seconds.
6565+ pub duration: i64,
6666+ /// The genre of the song.
6767+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
6868+ #[builder(into)]
6969+ #[serde(borrow)]
7070+ pub genre: Option<jacquard_common::CowStr<'a>>,
7171+ /// The label of the song.
7272+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
7373+ #[builder(into)]
7474+ #[serde(borrow)]
7575+ pub label: Option<jacquard_common::CowStr<'a>>,
7676+ /// The lyrics of the song.
7777+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
7878+ #[builder(into)]
7979+ #[serde(borrow)]
8080+ pub lyrics: Option<jacquard_common::CowStr<'a>>,
8181+ /// The MusicBrainz ID of the song.
8282+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
8383+ #[builder(into)]
8484+ #[serde(borrow)]
8585+ pub mbid: Option<jacquard_common::CowStr<'a>>,
8686+ /// The release date of the song.
8787+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
8888+ #[builder(into)]
8989+ pub release_date: Option<jacquard_common::types::string::Datetime>,
9090+ /// The Spotify link of the song.
9191+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
9292+ #[builder(into)]
9393+ #[serde(borrow)]
9494+ pub spotify_link: Option<jacquard_common::types::string::Uri<'a>>,
9595+ /// The tags of the song.
9696+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
9797+ #[builder(into)]
9898+ #[serde(borrow)]
9999+ pub tags: Option<Vec<jacquard_common::CowStr<'a>>>,
100100+ /// The Tidal link of the song.
101101+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
102102+ #[builder(into)]
103103+ #[serde(borrow)]
104104+ pub tidal_link: Option<jacquard_common::types::string::Uri<'a>>,
105105+ /// The title of the song.
106106+ #[serde(borrow)]
107107+ #[builder(into)]
108108+ pub title: jacquard_common::CowStr<'a>,
109109+ /// The track number of the song in the album.
110110+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
111111+ #[builder(into)]
112112+ pub track_number: Option<i64>,
113113+ /// Informations about the song
114114+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
115115+ #[builder(into)]
116116+ #[serde(borrow)]
117117+ pub wiki: Option<jacquard_common::CowStr<'a>>,
118118+ /// The year the song was released.
119119+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
120120+ #[builder(into)]
121121+ pub year: Option<i64>,
122122+ /// The YouTube link of the song.
123123+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
124124+ #[builder(into)]
125125+ #[serde(borrow)]
126126+ pub youtube_link: Option<jacquard_common::types::string::Uri<'a>>,
127127+}
128128+129129+/// Typed wrapper for GetRecord response with this collection's record type.
130130+#[derive(
131131+ serde::Serialize,
132132+ serde::Deserialize,
133133+ Debug,
134134+ Clone,
135135+ PartialEq,
136136+ Eq,
137137+ jacquard_derive::IntoStatic
138138+)]
139139+#[serde(rename_all = "camelCase")]
140140+pub struct SongGetRecordOutput<'a> {
141141+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
142142+ #[serde(borrow)]
143143+ pub cid: std::option::Option<jacquard_common::types::string::Cid<'a>>,
144144+ #[serde(borrow)]
145145+ pub uri: jacquard_common::types::string::AtUri<'a>,
146146+ #[serde(borrow)]
147147+ pub value: Song<'a>,
148148+}
149149+150150+/// Marker type for deserializing records from this collection.
151151+pub struct SongRecord;
152152+impl jacquard_common::xrpc::XrpcResp for SongRecord {
153153+ const NSID: &'static str = "app.rocksky.song";
154154+ const ENCODING: &'static str = "application/json";
155155+ type Output<'de> = SongGetRecordOutput<'de>;
156156+ type Err<'de> = jacquard_common::types::collection::RecordError<'de>;
157157+}
158158+159159+impl jacquard_common::types::collection::Collection for Song<'_> {
160160+ const NSID: &'static str = "app.rocksky.song";
161161+ type Record = SongRecord;
162162+}
163163+164164+impl From<SongGetRecordOutput<'_>> for Song<'_> {
165165+ fn from(output: SongGetRecordOutput<'_>) -> Self {
166166+ use jacquard_common::IntoStatic;
167167+ output.value.into_static()
168168+ }
169169+}
170170+171171+#[jacquard_derive::lexicon]
172172+#[derive(
173173+ serde::Serialize,
174174+ serde::Deserialize,
175175+ Debug,
176176+ Clone,
177177+ PartialEq,
178178+ Eq,
179179+ jacquard_derive::IntoStatic,
180180+ Default
181181+)]
182182+#[serde(rename_all = "camelCase")]
183183+pub struct SongViewBasic<'a> {
184184+ /// The album of the song.
185185+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
186186+ #[serde(borrow)]
187187+ pub album: std::option::Option<jacquard_common::CowStr<'a>>,
188188+ /// The URL of the album art image.
189189+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
190190+ #[serde(borrow)]
191191+ pub album_art: std::option::Option<jacquard_common::types::string::Uri<'a>>,
192192+ /// The artist of the album the song belongs to.
193193+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
194194+ #[serde(borrow)]
195195+ pub album_artist: std::option::Option<jacquard_common::CowStr<'a>>,
196196+ /// The URI of the album the song belongs to.
197197+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
198198+ #[serde(borrow)]
199199+ pub album_uri: std::option::Option<jacquard_common::types::string::AtUri<'a>>,
200200+ /// The artist of the song.
201201+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
202202+ #[serde(borrow)]
203203+ pub artist: std::option::Option<jacquard_common::CowStr<'a>>,
204204+ /// The URI of the artist of the song.
205205+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
206206+ #[serde(borrow)]
207207+ pub artist_uri: std::option::Option<jacquard_common::types::string::AtUri<'a>>,
208208+ /// The timestamp when the song was created.
209209+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
210210+ pub created_at: std::option::Option<jacquard_common::types::string::Datetime>,
211211+ /// The disc number of the song in the album.
212212+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
213213+ pub disc_number: std::option::Option<i64>,
214214+ /// The duration of the song in milliseconds.
215215+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
216216+ pub duration: std::option::Option<i64>,
217217+ /// The unique identifier of the song.
218218+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
219219+ #[serde(borrow)]
220220+ pub id: std::option::Option<jacquard_common::CowStr<'a>>,
221221+ /// The number of times the song has been played.
222222+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
223223+ pub play_count: std::option::Option<i64>,
224224+ /// The SHA256 hash of the song.
225225+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
226226+ #[serde(borrow)]
227227+ pub sha256: std::option::Option<jacquard_common::CowStr<'a>>,
228228+ /// The title of the song.
229229+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
230230+ #[serde(borrow)]
231231+ pub title: std::option::Option<jacquard_common::CowStr<'a>>,
232232+ /// The track number of the song in the album.
233233+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
234234+ pub track_number: std::option::Option<i64>,
235235+ /// The number of unique listeners who have played the song.
236236+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
237237+ pub unique_listeners: std::option::Option<i64>,
238238+ /// The URI of the song.
239239+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
240240+ #[serde(borrow)]
241241+ pub uri: std::option::Option<jacquard_common::types::string::AtUri<'a>>,
242242+}
243243+244244+#[jacquard_derive::lexicon]
245245+#[derive(
246246+ serde::Serialize,
247247+ serde::Deserialize,
248248+ Debug,
249249+ Clone,
250250+ PartialEq,
251251+ Eq,
252252+ jacquard_derive::IntoStatic,
253253+ Default
254254+)]
255255+#[serde(rename_all = "camelCase")]
256256+pub struct SongViewDetailed<'a> {
257257+ /// The album of the song.
258258+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
259259+ #[serde(borrow)]
260260+ pub album: std::option::Option<jacquard_common::CowStr<'a>>,
261261+ /// The URL of the album art image.
262262+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
263263+ #[serde(borrow)]
264264+ pub album_art: std::option::Option<jacquard_common::types::string::Uri<'a>>,
265265+ /// The artist of the album the song belongs to.
266266+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
267267+ #[serde(borrow)]
268268+ pub album_artist: std::option::Option<jacquard_common::CowStr<'a>>,
269269+ /// The URI of the album the song belongs to.
270270+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
271271+ #[serde(borrow)]
272272+ pub album_uri: std::option::Option<jacquard_common::types::string::AtUri<'a>>,
273273+ /// The artist of the song.
274274+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
275275+ #[serde(borrow)]
276276+ pub artist: std::option::Option<jacquard_common::CowStr<'a>>,
277277+ /// The URI of the artist of the song.
278278+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
279279+ #[serde(borrow)]
280280+ pub artist_uri: std::option::Option<jacquard_common::types::string::AtUri<'a>>,
281281+ /// The timestamp when the song was created.
282282+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
283283+ pub created_at: std::option::Option<jacquard_common::types::string::Datetime>,
284284+ /// The disc number of the song in the album.
285285+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
286286+ pub disc_number: std::option::Option<i64>,
287287+ /// The duration of the song in milliseconds.
288288+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
289289+ pub duration: std::option::Option<i64>,
290290+ /// The unique identifier of the song.
291291+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
292292+ #[serde(borrow)]
293293+ pub id: std::option::Option<jacquard_common::CowStr<'a>>,
294294+ /// The number of times the song has been played.
295295+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
296296+ pub play_count: std::option::Option<i64>,
297297+ /// The SHA256 hash of the song.
298298+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
299299+ #[serde(borrow)]
300300+ pub sha256: std::option::Option<jacquard_common::CowStr<'a>>,
301301+ /// The title of the song.
302302+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
303303+ #[serde(borrow)]
304304+ pub title: std::option::Option<jacquard_common::CowStr<'a>>,
305305+ /// The track number of the song in the album.
306306+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
307307+ pub track_number: std::option::Option<i64>,
308308+ /// The number of unique listeners who have played the song.
309309+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
310310+ pub unique_listeners: std::option::Option<i64>,
311311+ /// The URI of the song.
312312+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
313313+ #[serde(borrow)]
314314+ pub uri: std::option::Option<jacquard_common::types::string::AtUri<'a>>,
315315+}
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: app.rocksky.song.createSong
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+ Default
1818+)]
1919+#[serde(rename_all = "camelCase")]
2020+pub struct CreateSong<'a> {
2121+ /// The album of the song, if applicable
2222+ #[serde(borrow)]
2323+ pub album: jacquard_common::CowStr<'a>,
2424+ /// The URL of the album art for the song
2525+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2626+ #[serde(borrow)]
2727+ pub album_art: std::option::Option<jacquard_common::types::string::Uri<'a>>,
2828+ /// The album artist of the song, if different from the main artist
2929+ #[serde(borrow)]
3030+ pub album_artist: jacquard_common::CowStr<'a>,
3131+ /// The artist of the song
3232+ #[serde(borrow)]
3333+ pub artist: jacquard_common::CowStr<'a>,
3434+ /// The disc number of the song in the album, if applicable
3535+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3636+ pub disc_number: std::option::Option<i64>,
3737+ /// The duration of the song in seconds
3838+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3939+ pub duration: std::option::Option<i64>,
4040+ /// The lyrics of the song, if available
4141+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
4242+ #[serde(borrow)]
4343+ pub lyrics: std::option::Option<jacquard_common::CowStr<'a>>,
4444+ /// The MusicBrainz ID of the song, if available
4545+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
4646+ #[serde(borrow)]
4747+ pub mb_id: std::option::Option<jacquard_common::CowStr<'a>>,
4848+ /// The release date of the song, formatted as YYYY-MM-DD
4949+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5050+ #[serde(borrow)]
5151+ pub release_date: std::option::Option<jacquard_common::CowStr<'a>>,
5252+ /// The title of the song
5353+ #[serde(borrow)]
5454+ pub title: jacquard_common::CowStr<'a>,
5555+ /// The track number of the song in the album, if applicable
5656+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
5757+ pub track_number: std::option::Option<i64>,
5858+ /// The year the song was released
5959+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
6060+ pub year: std::option::Option<i64>,
6161+}
6262+6363+#[jacquard_derive::lexicon]
6464+#[derive(
6565+ serde::Serialize,
6666+ serde::Deserialize,
6767+ Debug,
6868+ Clone,
6969+ PartialEq,
7070+ Eq,
7171+ jacquard_derive::IntoStatic
7272+)]
7373+#[serde(rename_all = "camelCase")]
7474+pub struct CreateSongOutput<'a> {
7575+ #[serde(flatten)]
7676+ #[serde(borrow)]
7777+ pub value: crate::app_rocksky::song::SongViewDetailed<'a>,
7878+}
7979+8080+///Response type for
8181+///app.rocksky.song.createSong
8282+pub struct CreateSongResponse;
8383+impl jacquard_common::xrpc::XrpcResp for CreateSongResponse {
8484+ const NSID: &'static str = "app.rocksky.song.createSong";
8585+ const ENCODING: &'static str = "application/json";
8686+ type Output<'de> = CreateSongOutput<'de>;
8787+ type Err<'de> = jacquard_common::xrpc::GenericError<'de>;
8888+}
8989+9090+impl<'a> jacquard_common::xrpc::XrpcRequest for CreateSong<'a> {
9191+ const NSID: &'static str = "app.rocksky.song.createSong";
9292+ const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Procedure(
9393+ "application/json",
9494+ );
9595+ type Response = CreateSongResponse;
9696+}
9797+9898+///Endpoint type for
9999+///app.rocksky.song.createSong
100100+pub struct CreateSongRequest;
101101+impl jacquard_common::xrpc::XrpcEndpoint for CreateSongRequest {
102102+ const PATH: &'static str = "/xrpc/app.rocksky.song.createSong";
103103+ const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Procedure(
104104+ "application/json",
105105+ );
106106+ type Request<'de> = CreateSong<'de>;
107107+ type Response = CreateSongResponse;
108108+}
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: app.rocksky.song.getSongs
44+//
55+// This file was automatically generated from Lexicon schemas.
66+// Any manual changes will be overwritten on the next regeneration.
77+88+#[derive(
99+ serde::Serialize,
1010+ serde::Deserialize,
1111+ Debug,
1212+ Clone,
1313+ PartialEq,
1414+ Eq,
1515+ bon::Builder,
1616+ jacquard_derive::IntoStatic
1717+)]
1818+#[builder(start_fn = new)]
1919+#[serde(rename_all = "camelCase")]
2020+pub struct GetSongs {
2121+ ///(min: 1)
2222+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2323+ pub limit: std::option::Option<i64>,
2424+ ///(min: 0)
2525+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2626+ pub offset: std::option::Option<i64>,
2727+}
2828+2929+#[jacquard_derive::lexicon]
3030+#[derive(
3131+ serde::Serialize,
3232+ serde::Deserialize,
3333+ Debug,
3434+ Clone,
3535+ PartialEq,
3636+ Eq,
3737+ jacquard_derive::IntoStatic,
3838+ Default
3939+)]
4040+#[serde(rename_all = "camelCase")]
4141+pub struct GetSongsOutput<'a> {
4242+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
4343+ #[serde(borrow)]
4444+ pub songs: std::option::Option<Vec<crate::app_rocksky::song::SongViewBasic<'a>>>,
4545+}
4646+4747+///Response type for
4848+///app.rocksky.song.getSongs
4949+pub struct GetSongsResponse;
5050+impl jacquard_common::xrpc::XrpcResp for GetSongsResponse {
5151+ const NSID: &'static str = "app.rocksky.song.getSongs";
5252+ const ENCODING: &'static str = "application/json";
5353+ type Output<'de> = GetSongsOutput<'de>;
5454+ type Err<'de> = jacquard_common::xrpc::GenericError<'de>;
5555+}
5656+5757+impl jacquard_common::xrpc::XrpcRequest for GetSongs {
5858+ const NSID: &'static str = "app.rocksky.song.getSongs";
5959+ const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Query;
6060+ type Response = GetSongsResponse;
6161+}
6262+6363+///Endpoint type for
6464+///app.rocksky.song.getSongs
6565+pub struct GetSongsRequest;
6666+impl jacquard_common::xrpc::XrpcEndpoint for GetSongsRequest {
6767+ const PATH: &'static str = "/xrpc/app.rocksky.song.getSongs";
6868+ const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Query;
6969+ type Request<'de> = GetSongs;
7070+ type Response = GetSongsResponse;
7171+}
+51
crates/jacquard-api/src/app_rocksky/spotify.rs
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: app.rocksky.spotify.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_currently_playing;
99+pub mod next;
1010+pub mod pause;
1111+pub mod play;
1212+pub mod previous;
1313+pub mod seek;
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 SpotifyTrackView<'a> {
2828+ /// The name of the album.
2929+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3030+ #[serde(borrow)]
3131+ pub album: std::option::Option<jacquard_common::CowStr<'a>>,
3232+ /// The name of the artist.
3333+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3434+ #[serde(borrow)]
3535+ pub artist: std::option::Option<jacquard_common::CowStr<'a>>,
3636+ /// The duration of the track in milliseconds.
3737+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3838+ pub duration: std::option::Option<i64>,
3939+ /// The unique identifier of the Spotify track.
4040+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
4141+ #[serde(borrow)]
4242+ pub id: std::option::Option<jacquard_common::CowStr<'a>>,
4343+ /// The name of the track.
4444+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
4545+ #[serde(borrow)]
4646+ pub name: std::option::Option<jacquard_common::CowStr<'a>>,
4747+ /// A URL to a preview of the track.
4848+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
4949+ #[serde(borrow)]
5050+ pub preview_url: std::option::Option<jacquard_common::CowStr<'a>>,
5151+}
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: app.rocksky.spotify.seek
44+//
55+// This file was automatically generated from Lexicon schemas.
66+// Any manual changes will be overwritten on the next regeneration.
77+88+#[derive(
99+ serde::Serialize,
1010+ serde::Deserialize,
1111+ Debug,
1212+ Clone,
1313+ PartialEq,
1414+ Eq,
1515+ bon::Builder,
1616+ jacquard_derive::IntoStatic
1717+)]
1818+#[builder(start_fn = new)]
1919+#[serde(rename_all = "camelCase")]
2020+pub struct SeekParams {
2121+ pub position: i64,
2222+}
2323+2424+/// XRPC request marker type
2525+#[derive(
2626+ Debug,
2727+ Clone,
2828+ Copy,
2929+ PartialEq,
3030+ Eq,
3131+ serde::Serialize,
3232+ serde::Deserialize,
3333+ jacquard_derive::IntoStatic
3434+)]
3535+pub struct Seek;
3636+///Response type for
3737+///app.rocksky.spotify.seek
3838+pub struct SeekResponse;
3939+impl jacquard_common::xrpc::XrpcResp for SeekResponse {
4040+ const NSID: &'static str = "app.rocksky.spotify.seek";
4141+ const ENCODING: &'static str = "application/json";
4242+ type Output<'de> = ();
4343+ type Err<'de> = jacquard_common::xrpc::GenericError<'de>;
4444+}
4545+4646+impl jacquard_common::xrpc::XrpcRequest for Seek {
4747+ const NSID: &'static str = "app.rocksky.spotify.seek";
4848+ const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Procedure(
4949+ "application/json",
5050+ );
5151+ type Response = SeekResponse;
5252+}
5353+5454+///Endpoint type for
5555+///app.rocksky.spotify.seek
5656+pub struct SeekRequest;
5757+impl jacquard_common::xrpc::XrpcEndpoint for SeekRequest {
5858+ const PATH: &'static str = "/xrpc/app.rocksky.spotify.seek";
5959+ const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Procedure(
6060+ "application/json",
6161+ );
6262+ type Request<'de> = Seek;
6363+ type Response = SeekResponse;
6464+}
+38
crates/jacquard-api/src/app_rocksky/stats.rs
···11+// @generated by jacquard-lexicon. DO NOT EDIT.
22+//
33+// Lexicon: app.rocksky.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_stats;
99+1010+#[jacquard_derive::lexicon]
1111+#[derive(
1212+ serde::Serialize,
1313+ serde::Deserialize,
1414+ Debug,
1515+ Clone,
1616+ PartialEq,
1717+ Eq,
1818+ jacquard_derive::IntoStatic,
1919+ Default
2020+)]
2121+#[serde(rename_all = "camelCase")]
2222+pub struct StatsView<'a> {
2323+ /// The total number of unique albums scrobbled.
2424+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2525+ pub albums: std::option::Option<i64>,
2626+ /// The total number of unique artists scrobbled.
2727+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
2828+ pub artists: std::option::Option<i64>,
2929+ /// The total number of tracks marked as loved.
3030+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3131+ pub loved_tracks: std::option::Option<i64>,
3232+ /// The total number of scrobbles.
3333+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3434+ pub scrobbles: std::option::Option<i64>,
3535+ /// The total number of unique tracks scrobbled.
3636+ #[serde(skip_serializing_if = "std::option::Option::is_none")]
3737+ pub tracks: std::option::Option<i64>,
3838+}