{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DerivingVia #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE UndecidableInstances #-} module Types.Prim where import Data.Aeson (FromJSON, ToJSON) import Data.String (IsString) import Data.Text (Text) import GHC.Generics (Generic) #ifndef ghcjs_HOST_OS import Database.Beam (FromBackendRow, HasSqlEqualityCheck) import Database.Beam.Backend.SQL.SQL92 (HasSqlValueSyntax (..), autoSqlValueSyntax) import Database.Beam.Sqlite (Sqlite) import Database.Beam.Sqlite.Syntax (SqliteValueSyntax) import Database.SQLite.Simple.FromField (FromField (..)) #endif import Servant.API (FromHttpApiData, ToHttpApiData) import Shpadoinkle (text) import Shpadoinkle.Widgets.Types (Humanize (..), Present (..)) newtype SKU = SKU { unSKU :: Int } deriving stock Generic deriving newtype (Real, Enum, Integral, Eq, Ord, Show, Read, Num, ToJSON, FromJSON) deriving anyclass (Humanize, Present) #ifndef ghcjs_HOST_OS deriving newtype (FromBackendRow Sqlite, HasSqlValueSyntax SqliteValueSyntax, HasSqlEqualityCheck Sqlite) #endif instance Semigroup SKU where SKU x <> SKU y = SKU $ x + y instance Monoid SKU where mempty = SKU 0 newtype Description = Description { unDescription :: Text } deriving stock (Generic) deriving newtype (Eq, Ord, Show, Read, IsString, ToJSON, FromJSON, Humanize, Semigroup, Monoid) deriving anyclass (Present) #ifndef ghcjs_HOST_OS deriving newtype (FromBackendRow Sqlite, HasSqlValueSyntax SqliteValueSyntax, HasSqlEqualityCheck Sqlite) #endif instance Humanize (Maybe Description) where humanize = maybe "N/A" humanize newtype SerialNumber = SerialNumber { unSerialNumber :: Int } deriving stock Generic deriving newtype (Enum, Bounded, Real, Integral, Eq, Ord, Show, Num, ToJSON, FromJSON) deriving anyclass (Humanize, Present) #ifndef ghcjs_HOST_OS deriving newtype (FromBackendRow Sqlite, HasSqlValueSyntax SqliteValueSyntax, HasSqlEqualityCheck Sqlite) #endif instance Semigroup SerialNumber where SerialNumber x <> SerialNumber y = SerialNumber $ x + y instance Monoid SerialNumber where mempty = SerialNumber 0 newtype SpaceCraftId = SpaceCraftId { unSpaceCraftId :: Int } deriving newtype ( Eq, Ord, Show, Num, ToJSON, FromJSON, FromHttpApiData, ToHttpApiData) deriving anyclass (Humanize, Present) #ifndef ghcjs_HOST_OS deriving newtype (FromBackendRow Sqlite, HasSqlValueSyntax SqliteValueSyntax, HasSqlEqualityCheck Sqlite) #endif data Operable = Operational | Inoperable deriving (Eq, Ord, Enum, Bounded, Read, Show, Humanize, Present, Generic, ToJSON, FromJSON) #ifndef ghcjs_HOST_OS deriving (FromBackendRow Sqlite, HasSqlEqualityCheck Sqlite) instance HasSqlValueSyntax be String => HasSqlValueSyntax be Operable where sqlValueSyntax = autoSqlValueSyntax #endif instance Semigroup Operable where (<>) = min instance Monoid Operable where mempty = maxBound data Squadron = AwayTeam | StrikeForce | Scout deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic, ToJSON, FromJSON) #ifndef ghcjs_HOST_OS deriving (FromBackendRow Sqlite) instance HasSqlValueSyntax be String => HasSqlValueSyntax be Squadron where sqlValueSyntax = autoSqlValueSyntax #endif instance Semigroup Squadron where x <> _ = x #ifndef ghcjs_HOST_OS instance FromField Operable where fromField = fmap read <$> fromField instance FromField Squadron where fromField = fmap read <$> fromField #endif instance Humanize Squadron where humanize = \case AwayTeam -> "Away Team" StrikeForce -> "Strike Force" Scout -> "Scouting" instance Present Squadron where present = pure . text . humanize instance Humanize (Maybe Squadron) where humanize = maybe "N/A" humanize