{-# LANGUAGE CPP            #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}

module Nix.Atoms where

#ifdef MIN_VERSION_serialise
import Codec.Serialise
#endif
import           Control.DeepSeq
import           Data.Data
import           Data.Fixed                     (mod')
import           Data.Hashable
import           Data.Text                      ( Text
                                                , pack
                                                )
import           GHC.Generics

-- | Atoms are values that evaluate to themselves. This means that
-- they appear in both the parsed AST (in the form of literals) and
-- the evaluated form.
data NAtom
  -- | An URI like @https://example.com@.
  = NURI Text
  -- | An integer. The c nix implementation currently only supports
  -- integers that fit in the range of 'Int64'.
  | NInt Integer
  -- | A floating point number
  | NFloat Float
  -- | Booleans.
  | NBool Bool
  -- | Null values. There's only one of this variant.
  | NNull
  deriving (NAtom -> NAtom -> Bool
(NAtom -> NAtom -> Bool) -> (NAtom -> NAtom -> Bool) -> Eq NAtom
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NAtom -> NAtom -> Bool
$c/= :: NAtom -> NAtom -> Bool
== :: NAtom -> NAtom -> Bool
$c== :: NAtom -> NAtom -> Bool
Eq, Eq NAtom
Eq NAtom =>
(NAtom -> NAtom -> Ordering)
-> (NAtom -> NAtom -> Bool)
-> (NAtom -> NAtom -> Bool)
-> (NAtom -> NAtom -> Bool)
-> (NAtom -> NAtom -> Bool)
-> (NAtom -> NAtom -> NAtom)
-> (NAtom -> NAtom -> NAtom)
-> Ord NAtom
NAtom -> NAtom -> Bool
NAtom -> NAtom -> Ordering
NAtom -> NAtom -> NAtom
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: NAtom -> NAtom -> NAtom
$cmin :: NAtom -> NAtom -> NAtom
max :: NAtom -> NAtom -> NAtom
$cmax :: NAtom -> NAtom -> NAtom
>= :: NAtom -> NAtom -> Bool
$c>= :: NAtom -> NAtom -> Bool
> :: NAtom -> NAtom -> Bool
$c> :: NAtom -> NAtom -> Bool
<= :: NAtom -> NAtom -> Bool
$c<= :: NAtom -> NAtom -> Bool
< :: NAtom -> NAtom -> Bool
$c< :: NAtom -> NAtom -> Bool
compare :: NAtom -> NAtom -> Ordering
$ccompare :: NAtom -> NAtom -> Ordering
$cp1Ord :: Eq NAtom
Ord, (forall x. NAtom -> Rep NAtom x)
-> (forall x. Rep NAtom x -> NAtom) -> Generic NAtom
forall x. Rep NAtom x -> NAtom
forall x. NAtom -> Rep NAtom x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep NAtom x -> NAtom
$cfrom :: forall x. NAtom -> Rep NAtom x
Generic, Typeable, Typeable NAtom
DataType
Constr
Typeable NAtom =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> NAtom -> c NAtom)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c NAtom)
-> (NAtom -> Constr)
-> (NAtom -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c NAtom))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c NAtom))
-> ((forall b. Data b => b -> b) -> NAtom -> NAtom)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> NAtom -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> NAtom -> r)
-> (forall u. (forall d. Data d => d -> u) -> NAtom -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> NAtom -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> NAtom -> m NAtom)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> NAtom -> m NAtom)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> NAtom -> m NAtom)
-> Data NAtom
NAtom -> DataType
NAtom -> Constr
(forall b. Data b => b -> b) -> NAtom -> NAtom
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NAtom -> c NAtom
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NAtom
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> NAtom -> u
forall u. (forall d. Data d => d -> u) -> NAtom -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> NAtom -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> NAtom -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> NAtom -> m NAtom
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NAtom -> m NAtom
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NAtom
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NAtom -> c NAtom
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c NAtom)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c NAtom)
$cNNull :: Constr
$cNBool :: Constr
$cNFloat :: Constr
$cNInt :: Constr
$cNURI :: Constr
$tNAtom :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> NAtom -> m NAtom
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NAtom -> m NAtom
gmapMp :: (forall d. Data d => d -> m d) -> NAtom -> m NAtom
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> NAtom -> m NAtom
gmapM :: (forall d. Data d => d -> m d) -> NAtom -> m NAtom
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> NAtom -> m NAtom
gmapQi :: Int -> (forall d. Data d => d -> u) -> NAtom -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> NAtom -> u
gmapQ :: (forall d. Data d => d -> u) -> NAtom -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> NAtom -> [u]
gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> NAtom -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> NAtom -> r
gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> NAtom -> r
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> NAtom -> r
gmapT :: (forall b. Data b => b -> b) -> NAtom -> NAtom
$cgmapT :: (forall b. Data b => b -> b) -> NAtom -> NAtom
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c NAtom)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c NAtom)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c NAtom)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c NAtom)
dataTypeOf :: NAtom -> DataType
$cdataTypeOf :: NAtom -> DataType
toConstr :: NAtom -> Constr
$ctoConstr :: NAtom -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NAtom
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c NAtom
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NAtom -> c NAtom
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> NAtom -> c NAtom
$cp1Data :: Typeable NAtom
Data, Int -> NAtom -> ShowS
[NAtom] -> ShowS
NAtom -> String
(Int -> NAtom -> ShowS)
-> (NAtom -> String) -> ([NAtom] -> ShowS) -> Show NAtom
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NAtom] -> ShowS
$cshowList :: [NAtom] -> ShowS
show :: NAtom -> String
$cshow :: NAtom -> String
showsPrec :: Int -> NAtom -> ShowS
$cshowsPrec :: Int -> NAtom -> ShowS
Show, ReadPrec [NAtom]
ReadPrec NAtom
Int -> ReadS NAtom
ReadS [NAtom]
(Int -> ReadS NAtom)
-> ReadS [NAtom]
-> ReadPrec NAtom
-> ReadPrec [NAtom]
-> Read NAtom
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [NAtom]
$creadListPrec :: ReadPrec [NAtom]
readPrec :: ReadPrec NAtom
$creadPrec :: ReadPrec NAtom
readList :: ReadS [NAtom]
$creadList :: ReadS [NAtom]
readsPrec :: Int -> ReadS NAtom
$creadsPrec :: Int -> ReadS NAtom
Read, NAtom -> ()
(NAtom -> ()) -> NFData NAtom
forall a. (a -> ()) -> NFData a
rnf :: NAtom -> ()
$crnf :: NAtom -> ()
NFData,
            Int -> NAtom -> Int
NAtom -> Int
(Int -> NAtom -> Int) -> (NAtom -> Int) -> Hashable NAtom
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: NAtom -> Int
$chash :: NAtom -> Int
hashWithSalt :: Int -> NAtom -> Int
$chashWithSalt :: Int -> NAtom -> Int
Hashable)

#ifdef MIN_VERSION_serialise
instance Serialise NAtom
#endif

-- | Translate an atom into its nix representation.
atomText :: NAtom -> Text
atomText :: NAtom -> Text
atomText (NURI   t :: Text
t) = Text
t
atomText (NInt   i :: Integer
i) = String -> Text
pack (Integer -> String
forall a. Show a => a -> String
show Integer
i)
atomText (NFloat f :: Float
f) = String -> Text
pack (Float -> String
forall a. (Show a, RealFrac a) => a -> String
showNixFloat Float
f)
  where
    showNixFloat :: a -> String
showNixFloat x :: a
x
      | a
x a -> a -> a
forall a. Real a => a -> a -> a
`mod'` 1 a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= 0 = a -> String
forall a. Show a => a -> String
show a
x
      | Bool
otherwise       = Int -> String
forall a. Show a => a -> String
show (a -> Int
forall a b. (RealFrac a, Integral b) => a -> b
truncate a
x :: Int)
atomText (NBool  b :: Bool
b) = if Bool
b then "true" else "false"
atomText NNull      = "null"