{-# LANGUAGE FlexibleInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}

module Data.Configurator.Instances () where

import Control.Applicative
import Data.Configurator.Types.Internal
import Data.Complex (Complex)
import Data.Fixed (Fixed, HasResolution)
import Data.Int (Int8, Int16, Int32, Int64)
import Data.Text.Encoding (encodeUtf8)
import Data.Ratio (Ratio, denominator, numerator)
import Data.Word (Word, Word8, Word16, Word32, Word64)
import Foreign.C.Types (CDouble, CFloat)
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as LB
import qualified Data.Text as T
import qualified Data.Text.Lazy as L

instance Configured Value where
    convert :: Value -> Maybe Value
convert = forall a. a -> Maybe a
Just

instance Configured Bool where
    convert :: Value -> Maybe Bool
convert (Bool Bool
v) = forall a. a -> Maybe a
Just Bool
v
    convert Value
_        = forall a. Maybe a
Nothing

convertNumberToNum :: (Num a) => Value -> Maybe a
convertNumberToNum :: forall a. Num a => Value -> Maybe a
convertNumberToNum (Number Rational
r)
    | forall a. Ratio a -> a
denominator Rational
r forall a. Eq a => a -> a -> Bool
== Integer
1 = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. Num a => Integer -> a
fromInteger forall a b. (a -> b) -> a -> b
$ forall a. Ratio a -> a
numerator Rational
r
convertNumberToNum Value
_ = forall a. Maybe a
Nothing

instance Configured Int where
    convert :: Value -> Maybe Int
convert = forall a. Num a => Value -> Maybe a
convertNumberToNum

instance Configured Integer where
    convert :: Value -> Maybe Integer
convert = forall a. Num a => Value -> Maybe a
convertNumberToNum

instance Configured Int8 where
    convert :: Value -> Maybe Int8
convert = forall a. Num a => Value -> Maybe a
convertNumberToNum

instance Configured Int16 where
    convert :: Value -> Maybe Int16
convert = forall a. Num a => Value -> Maybe a
convertNumberToNum

instance Configured Int32 where
    convert :: Value -> Maybe Int32
convert = forall a. Num a => Value -> Maybe a
convertNumberToNum

instance Configured Int64 where
    convert :: Value -> Maybe Int64
convert = forall a. Num a => Value -> Maybe a
convertNumberToNum

instance Configured Word where
    convert :: Value -> Maybe Word
convert = forall a. Num a => Value -> Maybe a
convertNumberToNum

instance Configured Word8 where
    convert :: Value -> Maybe Word8
convert = forall a. Num a => Value -> Maybe a
convertNumberToNum

instance Configured Word16 where
    convert :: Value -> Maybe Word16
convert = forall a. Num a => Value -> Maybe a
convertNumberToNum

instance Configured Word32 where
    convert :: Value -> Maybe Word32
convert = forall a. Num a => Value -> Maybe a
convertNumberToNum

instance Configured Word64 where
    convert :: Value -> Maybe Word64
convert = forall a. Num a => Value -> Maybe a
convertNumberToNum

convertNumberToFractional :: (Fractional a) => Value -> Maybe a
convertNumberToFractional :: forall a. Fractional a => Value -> Maybe a
convertNumberToFractional (Number Rational
r) = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. Fractional a => Rational -> a
fromRational Rational
r
convertNumberToFractional Value
_ = forall a. Maybe a
Nothing

instance Configured Double where
    convert :: Value -> Maybe Double
convert = forall a. Fractional a => Value -> Maybe a
convertNumberToFractional

instance Configured Float where
    convert :: Value -> Maybe Float
convert = forall a. Fractional a => Value -> Maybe a
convertNumberToFractional

instance Configured CDouble where
    convert :: Value -> Maybe CDouble
convert = forall a. Fractional a => Value -> Maybe a
convertNumberToFractional

instance Configured CFloat where
    convert :: Value -> Maybe CFloat
convert = forall a. Fractional a => Value -> Maybe a
convertNumberToFractional

instance Integral a => Configured (Ratio a) where
    convert :: Value -> Maybe (Ratio a)
convert = forall a. Fractional a => Value -> Maybe a
convertNumberToFractional

instance RealFloat a => Configured (Complex a) where
    convert :: Value -> Maybe (Complex a)
convert = forall a. Fractional a => Value -> Maybe a
convertNumberToFractional

instance HasResolution a => Configured (Fixed a) where
    convert :: Value -> Maybe (Fixed a)
convert = forall a. Fractional a => Value -> Maybe a
convertNumberToFractional

instance Configured T.Text where
    convert :: Value -> Maybe Text
convert (String Text
v) = forall a. a -> Maybe a
Just Text
v
    convert Value
_          = forall a. Maybe a
Nothing

instance Configured Char where
    convert :: Value -> Maybe Char
convert (String Text
txt) | Text -> Int
T.length Text
txt forall a. Eq a => a -> a -> Bool
== Int
1 = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Text -> Char
T.head Text
txt
    convert Value
_ = forall a. Maybe a
Nothing

    convertList :: Value -> Maybe [Char]
convertList = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> [Char]
T.unpack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Configured a => Value -> Maybe a
convert

instance Configured L.Text where
    convert :: Value -> Maybe Text
convert = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Text
L.fromStrict forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Configured a => Value -> Maybe a
convert

instance Configured B.ByteString where
    convert :: Value -> Maybe ByteString
convert = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> ByteString
encodeUtf8 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Configured a => Value -> Maybe a
convert

instance Configured LB.ByteString where
    convert :: Value -> Maybe ByteString
convert = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([ByteString] -> ByteString
LB.fromChunks forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. a -> [a] -> [a]
:[])) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Configured a => Value -> Maybe a
convert

instance (Configured a, Configured b) => Configured (a,b) where
    convert :: Value -> Maybe (a, b)
convert (List [Value
a,Value
b]) = (,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Configured a => Value -> Maybe a
convert Value
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Configured a => Value -> Maybe a
convert Value
b
    convert Value
_            = forall a. Maybe a
Nothing

instance (Configured a, Configured b, Configured c) => Configured (a,b,c) where
    convert :: Value -> Maybe (a, b, c)
convert (List [Value
a,Value
b,Value
c]) = (,,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Configured a => Value -> Maybe a
convert Value
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Configured a => Value -> Maybe a
convert Value
b forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Configured a => Value -> Maybe a
convert Value
c
    convert Value
_              = forall a. Maybe a
Nothing

instance (Configured a, Configured b, Configured c, Configured d)
    => Configured (a,b,c,d) where
    convert :: Value -> Maybe (a, b, c, d)
convert (List [Value
a,Value
b,Value
c,Value
d]) = (,,,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Configured a => Value -> Maybe a
convert Value
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Configured a => Value -> Maybe a
convert Value
b forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Configured a => Value -> Maybe a
convert Value
c
                                     forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Configured a => Value -> Maybe a
convert Value
d
    convert Value
_                = forall a. Maybe a
Nothing