packages feed

fluent-1.0.0: src/Language/Fluent/Value.hs

module Language.Fluent.Value where

import Data.List.NonEmpty (NonEmpty)
import Data.Scientific (Scientific, fromFloatDigits)
import Data.String (IsString (..))
import Data.Text (Text)
import Data.Text qualified as Text
import Data.Time (UTCTime)
import Language.Fluent.Locale (Locale (..))
import Language.Fluent.Number (NumberOptions, numberOptions)
import Language.Fluent.Time (TimeOptions, timeOptions)
import Prelude

data CustomValue = forall v. (Value v) => CustomValue v

class Value v where
    value :: v -> SomeValue
    format :: (Locale l) => NonEmpty l -> v -> Either String Text
    format locale = format locale . value

data SomeValue
    = StringValue Text
    | NumberValue Scientific NumberOptions
    | TimeValue UTCTime TimeOptions
    | SomeValue CustomValue

instance Value Text where
    value = StringValue
    format _ = Right

instance Value String where value = StringValue . Text.pack

instance Value Scientific where value = flip NumberValue numberOptions

instance Value Int where value = value . fromIntegral @Int @Scientific

instance Value Integer where value = value . fromIntegral @Integer @Scientific

instance Value Word where value = value . fromIntegral @Word @Scientific

instance Value Double where value = value . fromFloatDigits

instance Value UTCTime where value = flip TimeValue timeOptions

instance Value CustomValue where
    value = SomeValue

    format locale (CustomValue v) = format locale v

instance IsString SomeValue where fromString = value

instance Show SomeValue where
    show (StringValue t) = "StringValue " <> Text.unpack t
    show (NumberValue n _) = "NumberValue " <> show n
    show (TimeValue t _) = "TimeValue " <> show t
    show SomeValue{} = "SomeValue"

instance Value SomeValue where
    value = id
    format locales (StringValue s) = format locales s
    format locales (NumberValue n o) = formatNumber locales n o
    format locales (TimeValue t o) = formatTime locales t o
    format locales (SomeValue v) = format locales v