11/* Spotify Web API - Kotlin Wrapper; MIT License, 2019; Original author: Adam Ratzman */
22package com.adamratzman.spotify.models
33
4- import kotlinx.serialization.Decoder
5- import kotlinx.serialization.Encoder
6- import kotlinx.serialization.KSerializer
7- import kotlinx.serialization.SerialDescriptor
84import kotlinx.serialization.Serializable
95import kotlinx.serialization.Serializer
10- import kotlinx.serialization.internal.StringDescriptor
6+ import kotlinx.serialization.Transient
117
128private fun String.matchType (type : String ): String? {
139 val typeRegex = " ^spotify:(?:.*:)*$type :([^:]+)(?::.*)*$|^([^:]+)$" .toRegex()
@@ -29,20 +25,14 @@ private fun String.remove(type: String): String {
2925 throw SpotifyUriException (" Illegal Spotify ID/URI: '$this ' isn't convertible to '$type ' id" )
3026}
3127
32- private class SimpleUriSerializer <T : SpotifyUri >(val ctor : (String ) -> T ) : KSerializer<T> {
33- override val descriptor: SerialDescriptor = StringDescriptor
34- override fun deserialize (decoder : Decoder ): T = ctor(decoder.decodeString())
35- override fun serialize (encoder : Encoder , obj : T ) = encoder.encodeString(obj.uri)
36- }
37-
3828/* *
3929 * Represents a Spotify URI, parsed from either a Spotify ID or taken from an endpoint.
4030 *
4131 * @property uri retrieve this URI as a string
4232 * @property id representation of this uri as an id
4333 */
4434@Serializable
45- sealed class SpotifyUri (val input : String , type : String ) {
35+ sealed class SpotifyUri (val input : String , val type : String ) {
4636 val uri: String
4737 val id: String
4838
@@ -54,7 +44,7 @@ sealed class SpotifyUri(val input: String, type: String) {
5444 }
5545
5646 override fun equals (other : Any? ): Boolean {
57- val spotifyUri = other as ? SpotifyUri ? : return false
47+ val spotifyUri = other as ? SpotifyUri ? : return (other as ? String )?. let { this .uri == it } ? : false
5848 return spotifyUri.uri == this .uri
5949 }
6050
@@ -68,12 +58,7 @@ sealed class SpotifyUri(val input: String, type: String) {
6858 return " SpotifyUri($uri )"
6959 }
7060
71- @Serializer(forClass = SpotifyUri ::class )
72- companion object : KSerializer <SpotifyUri > {
73- override val descriptor: SerialDescriptor = StringDescriptor
74- override fun deserialize (decoder : Decoder ): SpotifyUri = SpotifyUri (decoder.decodeString())
75- override fun serialize (encoder : Encoder , obj : SpotifyUri ) = encoder.encodeString(obj.uri)
76-
61+ companion object {
7762 /* *
7863 * This function safely instantiates a SpotifyUri from given constructor.
7964 * */
@@ -89,9 +74,12 @@ sealed class SpotifyUri(val input: String, type: String) {
8974 * Creates a abstract SpotifyUri of given input. Doesn't allow ambiguity by disallowing creation by id.
9075 * */
9176 operator fun invoke (input : String ): SpotifyUri {
92- val constructors = listOf (::AlbumUri , ::ArtistUri , TrackUri . Companion ::invoke , ::UserUri , ::PlaylistUri )
77+ val constructors = listOf (::AlbumUri , ::ArtistUri , :: LocalTrackUri , ::PlaylistUri , ::SpotifyTrackUri , :: UserUri )
9378 for (ctor in constructors) {
94- safeInitiate(input, ctor)?.takeIf { it.uri == input }?.also { return it }
79+ safeInitiate(input, ctor)?.takeIf {
80+ @Suppress(" ReplaceCallWithBinaryOperator" )
81+ it.equals(input)
82+ }?.also { return it }
9583 }
9684
9785 throw SpotifyUriException (" Illegal Spotify ID/URI: '$input ' isn't convertible to any arbitrary id" )
@@ -129,10 +117,7 @@ sealed class SpotifyUri(val input: String, type: String) {
129117 * Represents a Spotify **Album** URI, parsed from either a Spotify ID or taken from an endpoint.
130118 */
131119@Serializable
132- class AlbumUri (input : String ) : SpotifyUri(input, " album" ) {
133- @Serializer(forClass = AlbumUri ::class )
134- companion object : KSerializer <AlbumUri > by SimpleUriSerializer (::AlbumUri )
135- }
120+ class AlbumUri (@Transient private val _input : String = TRANSIENT_EMPTY_STRING ) : SpotifyUri(_input , " album" )
136121
137122@Deprecated(" renamed" , ReplaceWith (" AlbumUri" , " com.adamratzman.spotify.models.AlbumUri" ))
138123typealias AlbumURI = AlbumUri
@@ -141,22 +126,15 @@ typealias AlbumURI = AlbumUri
141126 * Represents a Spotify **Artist** URI, parsed from either a Spotify ID or taken from an endpoint.
142127 */
143128@Serializable
144- class ArtistUri (input : String ) : SpotifyUri(input, " artist" ) {
145- @Serializer(forClass = ArtistUri ::class )
146- companion object : KSerializer <ArtistUri > by SimpleUriSerializer (::ArtistUri )
147- }
148-
129+ class ArtistUri (@Transient private val _input : String = TRANSIENT_EMPTY_STRING ) : SpotifyUri(_input , " artist" )
149130@Deprecated(" renamed" , ReplaceWith (" ArtistUri" , " com.adamratzman.spotify.models.ArtistUri" ))
150131typealias ArtistURI = ArtistUri
151132
152133/* *
153134 * Represents a Spotify **User** URI, parsed from either a Spotify ID or taken from an endpoint.
154135 */
155136@Serializable
156- class UserUri (input : String ) : SpotifyUri(input, " user" ) {
157- @Serializer(forClass = UserUri ::class )
158- companion object : KSerializer <UserUri > by SimpleUriSerializer (::UserUri )
159- }
137+ class UserUri (@Transient private val _input : String = TRANSIENT_EMPTY_STRING ) : SpotifyUri(_input , " user" )
160138
161139@Deprecated(" renamed" , ReplaceWith (" UserUri" , " com.adamratzman.spotify.models.UserUri" ))
162140typealias UserURI = UserUri
@@ -165,9 +143,17 @@ typealias UserURI = UserUri
165143 * Represents a Spotify **Playlist** URI, parsed from either a Spotify ID or taken from an endpoint.
166144 */
167145@Serializable
168- class PlaylistUri (input : String ) : SpotifyUri(input, " playlist" ) {
169- @Serializer(forClass = PlaylistUri ::class )
170- companion object : KSerializer <PlaylistUri > by SimpleUriSerializer (::PlaylistUri )
146+ class PlaylistUri (@Transient private val _input : String = TRANSIENT_EMPTY_STRING ) : SpotifyUri(_input , " playlist" ) {
147+ override fun equals (other : Any? ): Boolean {
148+ val spotifyUri = other as ? SpotifyUri ? : return (other as ? String )?.endsWith(this .uri.removePrefix(" spotify" )) ? : false
149+ return spotifyUri.uri == this .uri
150+ }
151+
152+ override fun hashCode (): Int {
153+ var result = super .hashCode()
154+ result = 31 * result + _input .hashCode()
155+ return result
156+ }
171157}
172158
173159@Deprecated(" renamed" , ReplaceWith (" PlaylistUri" , " com.adamratzman.spotify.models.PlaylistUri" ))
@@ -178,13 +164,14 @@ typealias PlaylistURI = PlaylistUri
178164 * from an endpoint
179165 * */
180166@Serializable
181- sealed class TrackUri (input : String , type : String ) : SpotifyUri(input, type) {
182- @Serializer(forClass = TrackUri ::class )
183- companion object : KSerializer <TrackUri > {
184- override val descriptor: SerialDescriptor = StringDescriptor
185- override fun deserialize (decoder : Decoder ): TrackUri = TrackUri (decoder.decodeString())
186- override fun serialize (encoder : Encoder , obj : TrackUri ) = encoder.encodeString(obj.uri)
167+ sealed class TrackUri (
168+ @Transient private val _input : String = TRANSIENT_EMPTY_STRING ,
169+ @Transient private val _type : String = TRANSIENT_EMPTY_STRING
170+ ) :
171+ SpotifyUri (_input , _type ) {
187172
173+ @Serializer(forClass = TrackUri ::class )
174+ companion object {
188175 /* *
189176 * Creates a abstract TrackURI of given input. Prefers SpotifyTrackUri if the input is ambiguous.
190177 * */
@@ -205,19 +192,13 @@ typealias TrackURI = TrackUri
205192 * Represents a Spotify **Track** URI, parsed from either a Spotify ID or taken from an endpoint.
206193 */
207194@Serializable
208- class SpotifyTrackUri (input : String ) : TrackUri(input, " track" ) {
209- @Serializer(forClass = SpotifyTrackUri ::class )
210- companion object : KSerializer <SpotifyTrackUri > by SimpleUriSerializer (::SpotifyTrackUri )
211- }
195+ class SpotifyTrackUri (@Transient private val _input : String = TRANSIENT_EMPTY_STRING ) : TrackUri(_input , " track" )
212196
213197/* *
214198 * Represents a Spotify **local track** URI
215199 */
216200@Serializable
217- class LocalTrackUri (input : String ) : TrackUri(input, " local" ) {
218- @Serializer(forClass = LocalTrackUri ::class )
219- companion object : KSerializer <LocalTrackUri > by SimpleUriSerializer (::LocalTrackUri )
220- }
201+ class LocalTrackUri (@Transient private val _input : String = TRANSIENT_EMPTY_STRING ) : TrackUri(_input , " local" )
221202
222203@Deprecated(" renamed" , ReplaceWith (" LocalTrackUri" , " com.adamratzman.spotify.models.LocalTrackUri" ))
223204typealias LocalTrackURI = LocalTrackUri
0 commit comments