spotify-0.1.0.0: types/Spotify/Types/Misc.hs
{- HLINT ignore "Use newtype instead of data" -}
{-# LANGUAGE UndecidableInstances #-}
module Spotify.Types.Misc where
import Spotify.Types.Internal.CustomJSON
import Spotify.Types.Internal.EnumJSON
import Data.Aeson (FromJSON, ToJSON)
import Data.List.Extra (enumerate)
import Data.Map (Map)
import Data.Proxy (Proxy (Proxy))
import Data.Set qualified as Set
import Data.String (IsString)
import Data.Text (Text)
import Data.Text qualified as T
import GHC.Generics (Generic)
import GHC.Records (HasField)
import GHC.TypeLits (KnownSymbol, Symbol, symbolVal)
import Servant.API (ToHttpApiData)
data Copyright = Copyright
{ text :: Text
, type_ :: CopyrightType
}
deriving (Eq, Ord, Show, Generic)
deriving (FromJSON) via CustomJSON Copyright
data CopyrightType
= C
| P
deriving (Eq, Ord, Show, Generic)
deriving (FromJSON)
data Error = Error
{ status :: HTTPError
, message :: Text
}
deriving (Eq, Ord, Show, Generic)
deriving (FromJSON) via CustomJSON Error
data Followers = Followers
{ href :: Maybe Text
, total :: Int
}
deriving (Eq, Ord, Show, Generic)
deriving (FromJSON) via CustomJSON Followers
data Image = Image
{ height :: Maybe Int
, url :: Text
, width :: Maybe Int
}
deriving (Eq, Ord, Show, Generic)
deriving (FromJSON) via CustomJSON Image
data Paging a = Paging
{ href :: Href
, items :: [a]
, limit :: Int
, next :: Maybe Text
, offset :: Int
, previous :: Maybe Text
, total :: Int
}
deriving (Eq, Ord, Show, Generic)
deriving (FromJSON) via CustomJSON (Paging a)
data Tracks = Tracks
{ href :: Maybe Text
, total :: Int
}
deriving (Eq, Ord, Show, Generic)
deriving (FromJSON) via CustomJSON Tracks
data DatePrecision
= DatePrecisionYear
| DatePrecisionMonth
| DatePrecisionDay
deriving (Eq, Ord, Show, Generic)
deriving (FromJSON) via CustomJSON DatePrecision
data Key
= KeyC
| KeyCSharp
| KeyD
| KeyDSharp
| KeyE
| KeyF
| KeyFSharp
| KeyG
| KeyGSharp
| KeyA
| KeyASharp
| KeyB
deriving (Eq, Ord, Show, Generic, Enum)
deriving (FromJSON) via EnumJSON Key
data TrackLink = TrackLink
{ externalUrls :: ExternalURLs
, href :: Href
, id :: TrackID
, url :: Maybe Text
}
deriving (Eq, Ord, Show, Generic)
deriving (FromJSON) via CustomJSON TrackLink
data AlbumGroup
= GroupAlbum
| GroupSingle
| GroupCompilation
| AppearsOn
deriving (Eq, Ord, Show, Generic)
deriving (FromJSON) via CustomJSON AlbumGroup
data AlbumType
= AlbumTypeAlbum
| AlbumTypeSingle
| AlbumTypeCompilation
deriving (Eq, Ord, Show, Generic)
deriving (FromJSON) via CustomJSON AlbumType
data ExplicitContent = ExplicitContent
{ filterEnabled :: Bool
, filterLocked :: Bool
}
deriving (Eq, Ord, Show, Generic)
deriving (FromJSON) via CustomJSON ExplicitContent
data Product
= Premium
| Free
deriving (Eq, Ord, Show, Generic)
deriving (FromJSON) via CustomJSON Product
data Offset = Offset
{ position :: Int
, uri :: Maybe URI
}
deriving (Eq, Ord, Show, Generic)
deriving (ToJSON)
newtype Market = Market {unwrap :: Text}
deriving newtype (Eq, Ord, Show, ToHttpApiData, IsString)
newtype Genre = Genre {unwrap :: Text}
deriving newtype (Eq, Ord, Show, FromJSON, IsString)
newtype Href = Href {unwrap :: Text}
deriving newtype (Eq, Ord, Show, FromJSON, IsString)
class ToURI a where
toURI :: a -> URI
newtype URIPrefix (s :: Symbol) a = URIPrefix a
instance (KnownSymbol s, HasField "unwrap" a Text) => ToURI (URIPrefix s a) where
toURI (URIPrefix x) = URI $ "spotify:" <> T.pack (symbolVal (Proxy @s)) <> ":" <> x.unwrap
newtype DeviceID = DeviceID {unwrap :: Text}
deriving newtype (Eq, Ord, Show, FromJSON, ToJSON, ToHttpApiData, IsString)
newtype AlbumID = AlbumID {unwrap :: Text}
deriving newtype (Eq, Ord, Show, FromJSON, ToJSON, ToHttpApiData, IsString)
deriving (ToURI) via URIPrefix "album" AlbumID
newtype ArtistID = ArtistID {unwrap :: Text}
deriving newtype (Eq, Ord, Show, FromJSON, ToJSON, ToHttpApiData, IsString)
deriving (ToURI) via URIPrefix "artist" ArtistID
newtype EpisodeID = EpisodeID {unwrap :: Text}
deriving newtype (Eq, Ord, Show, FromJSON, ToJSON, ToHttpApiData, IsString)
deriving (ToURI) via URIPrefix "episode" EpisodeID
newtype TrackID = TrackID {unwrap :: Text}
deriving newtype (Eq, Ord, Show, FromJSON, ToJSON, ToHttpApiData, IsString)
deriving (ToURI) via URIPrefix "track" TrackID
newtype UserID = UserID {unwrap :: Text}
deriving newtype (Eq, Ord, Show, FromJSON, ToJSON, ToHttpApiData, IsString)
deriving (ToURI) via URIPrefix "user" UserID
newtype PlaylistID = PlaylistID {unwrap :: Text}
deriving newtype (Eq, Ord, Show, FromJSON, ToJSON, ToHttpApiData, IsString)
deriving (ToURI) via URIPrefix "playlist" PlaylistID
newtype CategoryID = CategoryID {unwrap :: Text}
deriving newtype (Eq, Ord, Show, FromJSON, ToJSON, ToHttpApiData, IsString)
newtype SnapshotID = SnapshotID {unwrap :: Text}
deriving newtype (Eq, Ord, Show, FromJSON, ToJSON, ToHttpApiData, IsString)
newtype URL = URL {unwrap :: Text}
deriving newtype (Eq, Ord, Show, FromJSON, IsString, ToHttpApiData)
newtype URI = URI {unwrap :: Text}
deriving newtype (Eq, Ord, Show, FromJSON, ToJSON, IsString)
newtype Country = Country {unwrap :: Text}
deriving newtype (Eq, Ord, Show, FromJSON, ToJSON, ToHttpApiData, IsString)
newtype Locale = Locale {unwrap :: Text}
deriving newtype (Eq, Ord, Show, FromJSON, ToJSON, ToHttpApiData, IsString)
newtype HTTPError = HTTPError {unwrap :: Int}
deriving (Show)
deriving newtype (Eq, Ord, FromJSON)
newtype Restrictions = Restrictions {unwrap :: Map Text Text}
deriving (Show)
deriving newtype (Eq, Ord, FromJSON)
newtype ExternalIDs = ExternalIDs {unwrap :: Map Text Text}
deriving (Show)
deriving newtype (Eq, Ord, FromJSON)
newtype ExternalURLs = ExternalURLs {unwrap :: Map Text Text}
deriving (Show)
deriving newtype (Eq, Ord, FromJSON)
data Scope
= UgcImageUpload
| UserModifyPlaybackState
| UserReadPlaybackState
| UserReadCurrentlyPlaying
| UserFollowModify
| UserFollowRead
| UserReadRecentlyPlayed
| UserReadPlaybackPosition
| UserTopRead
| PlaylistReadCollaborative
| PlaylistModifyPublic
| PlaylistReadPrivate
| PlaylistModifyPrivate
| AppRemoteControl
| Streaming
| UserReadEmail
| UserReadPrivate
| UserLibraryModify
| UserLibraryRead
deriving (Eq, Ord, Show, Enum, Bounded)
allScopes :: Set.Set Scope
allScopes = Set.fromList enumerate
showScope :: Scope -> Text
showScope = \case
UgcImageUpload -> "ugc-image-upload"
UserModifyPlaybackState -> "user-modify-playback-state"
UserReadPlaybackState -> "user-read-playback-state"
UserReadCurrentlyPlaying -> "user-read-currently-playing"
UserFollowModify -> "user-follow-modify"
UserFollowRead -> "user-follow-read"
UserReadRecentlyPlayed -> "user-read-recently-played"
UserReadPlaybackPosition -> "user-read-playback-position"
UserTopRead -> "user-top-read"
PlaylistReadCollaborative -> "playlist-read-collaborative"
PlaylistModifyPublic -> "playlist-modify-public"
PlaylistReadPrivate -> "playlist-read-private"
PlaylistModifyPrivate -> "playlist-modify-private"
AppRemoteControl -> "app-remote-control"
Streaming -> "streaming"
UserReadEmail -> "user-read-email"
UserReadPrivate -> "user-read-private"
UserLibraryModify -> "user-library-modify"
UserLibraryRead -> "user-library-read"