module U.Codebase.Config
  ( AuthorName,
    ConfigKey (..),
    allKeys,
    mkAuthorName,
    unAuthorName,
    keyToText,
    keyFromText,
    allKeysText,
  )
where

import Data.Text qualified as Text
import Unison.Prelude
import Unison.Sqlite qualified as Sqlite

data ConfigKey = AuthorNameKey
  deriving stock (ConfigKey -> ConfigKey -> Bool
(ConfigKey -> ConfigKey -> Bool)
-> (ConfigKey -> ConfigKey -> Bool) -> Eq ConfigKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ConfigKey -> ConfigKey -> Bool
== :: ConfigKey -> ConfigKey -> Bool
$c/= :: ConfigKey -> ConfigKey -> Bool
/= :: ConfigKey -> ConfigKey -> Bool
Eq, Int -> ConfigKey
ConfigKey -> Int
ConfigKey -> [ConfigKey]
ConfigKey -> ConfigKey
ConfigKey -> ConfigKey -> [ConfigKey]
ConfigKey -> ConfigKey -> ConfigKey -> [ConfigKey]
(ConfigKey -> ConfigKey)
-> (ConfigKey -> ConfigKey)
-> (Int -> ConfigKey)
-> (ConfigKey -> Int)
-> (ConfigKey -> [ConfigKey])
-> (ConfigKey -> ConfigKey -> [ConfigKey])
-> (ConfigKey -> ConfigKey -> [ConfigKey])
-> (ConfigKey -> ConfigKey -> ConfigKey -> [ConfigKey])
-> Enum ConfigKey
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: ConfigKey -> ConfigKey
succ :: ConfigKey -> ConfigKey
$cpred :: ConfigKey -> ConfigKey
pred :: ConfigKey -> ConfigKey
$ctoEnum :: Int -> ConfigKey
toEnum :: Int -> ConfigKey
$cfromEnum :: ConfigKey -> Int
fromEnum :: ConfigKey -> Int
$cenumFrom :: ConfigKey -> [ConfigKey]
enumFrom :: ConfigKey -> [ConfigKey]
$cenumFromThen :: ConfigKey -> ConfigKey -> [ConfigKey]
enumFromThen :: ConfigKey -> ConfigKey -> [ConfigKey]
$cenumFromTo :: ConfigKey -> ConfigKey -> [ConfigKey]
enumFromTo :: ConfigKey -> ConfigKey -> [ConfigKey]
$cenumFromThenTo :: ConfigKey -> ConfigKey -> ConfigKey -> [ConfigKey]
enumFromThenTo :: ConfigKey -> ConfigKey -> ConfigKey -> [ConfigKey]
Enum, ConfigKey
ConfigKey -> ConfigKey -> Bounded ConfigKey
forall a. a -> a -> Bounded a
$cminBound :: ConfigKey
minBound :: ConfigKey
$cmaxBound :: ConfigKey
maxBound :: ConfigKey
Bounded)

instance Show ConfigKey where
  show :: ConfigKey -> [Char]
show ConfigKey
k = Text -> [Char]
Text.unpack (Text -> [Char]) -> (ConfigKey -> Text) -> ConfigKey -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConfigKey -> Text
keyToText (ConfigKey -> [Char]) -> ConfigKey -> [Char]
forall a b. (a -> b) -> a -> b
$ ConfigKey
k

allKeys :: [ConfigKey]
allKeys :: [ConfigKey]
allKeys = [ConfigKey
forall a. Bounded a => a
minBound .. ConfigKey
forall a. Bounded a => a
maxBound]

allKeysText :: [Text]
allKeysText :: [Text]
allKeysText = ConfigKey -> Text
keyToText (ConfigKey -> Text) -> [ConfigKey] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [ConfigKey]
allKeys

keyToText :: ConfigKey -> Text
keyToText :: ConfigKey -> Text
keyToText = \case
  ConfigKey
AuthorNameKey -> Text
"author.name"

keyFromText :: Text -> Maybe ConfigKey
keyFromText :: Text -> Maybe ConfigKey
keyFromText Text
t = case Text
t of
  Text
"author.name" -> ConfigKey -> Maybe ConfigKey
forall a. a -> Maybe a
Just ConfigKey
AuthorNameKey
  Text
_ -> Maybe ConfigKey
forall a. Maybe a
Nothing

instance Sqlite.ToField ConfigKey where
  toField :: ConfigKey -> SQLData
toField ConfigKey
AuthorNameKey = Text -> SQLData
forall a. ToField a => a -> SQLData
Sqlite.toField (ConfigKey -> Text
keyToText ConfigKey
AuthorNameKey)

mkAuthorName :: Text -> Either Text AuthorName
mkAuthorName :: Text -> Either Text AuthorName
mkAuthorName Text
name
  | Text -> Bool
Text.null (Text -> Text
Text.strip Text
name) = Text -> Either Text AuthorName
forall a b. a -> Either a b
Left Text
"Author name cannot be empty."
  | Text -> Int
Text.length Text
name Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
100 = Text -> Either Text AuthorName
forall a b. a -> Either a b
Left Text
"Author name cannot exceed 100 characters."
  | Bool
otherwise = AuthorName -> Either Text AuthorName
forall a b. b -> Either a b
Right (Text -> AuthorName
AuthorName Text
name)

newtype AuthorName = AuthorName {AuthorName -> Text
unAuthorName :: Text}
  deriving stock (AuthorName -> AuthorName -> Bool
(AuthorName -> AuthorName -> Bool)
-> (AuthorName -> AuthorName -> Bool) -> Eq AuthorName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: AuthorName -> AuthorName -> Bool
== :: AuthorName -> AuthorName -> Bool
$c/= :: AuthorName -> AuthorName -> Bool
/= :: AuthorName -> AuthorName -> Bool
Eq, Int -> AuthorName -> ShowS
[AuthorName] -> ShowS
AuthorName -> [Char]
(Int -> AuthorName -> ShowS)
-> (AuthorName -> [Char])
-> ([AuthorName] -> ShowS)
-> Show AuthorName
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> AuthorName -> ShowS
showsPrec :: Int -> AuthorName -> ShowS
$cshow :: AuthorName -> [Char]
show :: AuthorName -> [Char]
$cshowList :: [AuthorName] -> ShowS
showList :: [AuthorName] -> ShowS
Show)
  deriving newtype (AuthorName -> SQLData
(AuthorName -> SQLData) -> ToField AuthorName
forall a. (a -> SQLData) -> ToField a
$ctoField :: AuthorName -> SQLData
toField :: AuthorName -> SQLData
Sqlite.ToField, FieldParser AuthorName
FieldParser AuthorName -> FromField AuthorName
forall a. FieldParser a -> FromField a
$cfromField :: FieldParser AuthorName
fromField :: FieldParser AuthorName
Sqlite.FromField)