{-# LANGUAGE DeriveFunctor #-}
-- | Cabal-like file AST types: 'Field', 'Section' etc
--
-- These types are parametrized by an annotation.
module Distribution.Fields.Field (
    -- * Cabal file
    Field (..),
    fieldName,
    fieldAnn,
    fieldUniverse,
    FieldLine (..),
    SectionArg (..),
    sectionArgAnn,
    -- * Name
    FieldName,
    Name (..),
    mkName,
    getName,
    nameAnn,
    ) where

import           Prelude ()
import           Distribution.Compat.Prelude
import           Data.ByteString             (ByteString)
import qualified Data.ByteString.Char8       as B
import qualified Data.Char                   as Char

-------------------------------------------------------------------------------
-- Cabal file
-------------------------------------------------------------------------------

-- | A Cabal-like file consists of a series of fields (@foo: bar@) and sections (@library ...@).
data Field ann
    = Field   !(Name ann) [FieldLine ann]
    | Section !(Name ann) [SectionArg ann] [Field ann]
  deriving (Field ann -> Field ann -> Bool
(Field ann -> Field ann -> Bool)
-> (Field ann -> Field ann -> Bool) -> Eq (Field ann)
forall ann. Eq ann => Field ann -> Field ann -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Field ann -> Field ann -> Bool
$c/= :: forall ann. Eq ann => Field ann -> Field ann -> Bool
== :: Field ann -> Field ann -> Bool
$c== :: forall ann. Eq ann => Field ann -> Field ann -> Bool
Eq, Int -> Field ann -> ShowS
[Field ann] -> ShowS
Field ann -> String
(Int -> Field ann -> ShowS)
-> (Field ann -> String)
-> ([Field ann] -> ShowS)
-> Show (Field ann)
forall ann. Show ann => Int -> Field ann -> ShowS
forall ann. Show ann => [Field ann] -> ShowS
forall ann. Show ann => Field ann -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Field ann] -> ShowS
$cshowList :: forall ann. Show ann => [Field ann] -> ShowS
show :: Field ann -> String
$cshow :: forall ann. Show ann => Field ann -> String
showsPrec :: Int -> Field ann -> ShowS
$cshowsPrec :: forall ann. Show ann => Int -> Field ann -> ShowS
Show, a -> Field b -> Field a
(a -> b) -> Field a -> Field b
(forall a b. (a -> b) -> Field a -> Field b)
-> (forall a b. a -> Field b -> Field a) -> Functor Field
forall a b. a -> Field b -> Field a
forall a b. (a -> b) -> Field a -> Field b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Field b -> Field a
$c<$ :: forall a b. a -> Field b -> Field a
fmap :: (a -> b) -> Field a -> Field b
$cfmap :: forall a b. (a -> b) -> Field a -> Field b
Functor)

-- | Section of field name
fieldName :: Field ann -> Name ann
fieldName :: Field ann -> Name ann
fieldName (Field n :: Name ann
n _ )    = Name ann
n
fieldName (Section n :: Name ann
n _ _) = Name ann
n

fieldAnn :: Field ann -> ann
fieldAnn :: Field ann -> ann
fieldAnn = Name ann -> ann
forall ann. Name ann -> ann
nameAnn (Name ann -> ann) -> (Field ann -> Name ann) -> Field ann -> ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Field ann -> Name ann
forall ann. Field ann -> Name ann
fieldName

-- | All transitive descendands of 'Field', including itself.
--
-- /Note:/ the resulting list is never empty.
--
fieldUniverse :: Field ann -> [Field ann]
fieldUniverse :: Field ann -> [Field ann]
fieldUniverse f :: Field ann
f@(Section _ _ fs :: [Field ann]
fs) = Field ann
f Field ann -> [Field ann] -> [Field ann]
forall a. a -> [a] -> [a]
: (Field ann -> [Field ann]) -> [Field ann] -> [Field ann]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Field ann -> [Field ann]
forall ann. Field ann -> [Field ann]
fieldUniverse [Field ann]
fs
fieldUniverse f :: Field ann
f@(Field _ _)      = [Field ann
f]

-- | A line of text representing the value of a field from a Cabal file.
-- A field may contain multiple lines.
--
-- /Invariant:/ 'ByteString' has no newlines.
data FieldLine ann  = FieldLine  !ann !ByteString
  deriving (FieldLine ann -> FieldLine ann -> Bool
(FieldLine ann -> FieldLine ann -> Bool)
-> (FieldLine ann -> FieldLine ann -> Bool) -> Eq (FieldLine ann)
forall ann. Eq ann => FieldLine ann -> FieldLine ann -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FieldLine ann -> FieldLine ann -> Bool
$c/= :: forall ann. Eq ann => FieldLine ann -> FieldLine ann -> Bool
== :: FieldLine ann -> FieldLine ann -> Bool
$c== :: forall ann. Eq ann => FieldLine ann -> FieldLine ann -> Bool
Eq, Int -> FieldLine ann -> ShowS
[FieldLine ann] -> ShowS
FieldLine ann -> String
(Int -> FieldLine ann -> ShowS)
-> (FieldLine ann -> String)
-> ([FieldLine ann] -> ShowS)
-> Show (FieldLine ann)
forall ann. Show ann => Int -> FieldLine ann -> ShowS
forall ann. Show ann => [FieldLine ann] -> ShowS
forall ann. Show ann => FieldLine ann -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FieldLine ann] -> ShowS
$cshowList :: forall ann. Show ann => [FieldLine ann] -> ShowS
show :: FieldLine ann -> String
$cshow :: forall ann. Show ann => FieldLine ann -> String
showsPrec :: Int -> FieldLine ann -> ShowS
$cshowsPrec :: forall ann. Show ann => Int -> FieldLine ann -> ShowS
Show, a -> FieldLine b -> FieldLine a
(a -> b) -> FieldLine a -> FieldLine b
(forall a b. (a -> b) -> FieldLine a -> FieldLine b)
-> (forall a b. a -> FieldLine b -> FieldLine a)
-> Functor FieldLine
forall a b. a -> FieldLine b -> FieldLine a
forall a b. (a -> b) -> FieldLine a -> FieldLine b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> FieldLine b -> FieldLine a
$c<$ :: forall a b. a -> FieldLine b -> FieldLine a
fmap :: (a -> b) -> FieldLine a -> FieldLine b
$cfmap :: forall a b. (a -> b) -> FieldLine a -> FieldLine b
Functor)

-- | Section arguments, e.g. name of the library
data SectionArg ann
    = SecArgName  !ann !ByteString
      -- ^ identifier, or omething which loos like number. Also many dot numbers, i.e. "7.6.3"
    | SecArgStr   !ann !ByteString
      -- ^ quoted string
    | SecArgOther !ann !ByteString
      -- ^ everything else, mm. operators (e.g. in if-section conditionals)
  deriving (SectionArg ann -> SectionArg ann -> Bool
(SectionArg ann -> SectionArg ann -> Bool)
-> (SectionArg ann -> SectionArg ann -> Bool)
-> Eq (SectionArg ann)
forall ann. Eq ann => SectionArg ann -> SectionArg ann -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SectionArg ann -> SectionArg ann -> Bool
$c/= :: forall ann. Eq ann => SectionArg ann -> SectionArg ann -> Bool
== :: SectionArg ann -> SectionArg ann -> Bool
$c== :: forall ann. Eq ann => SectionArg ann -> SectionArg ann -> Bool
Eq, Int -> SectionArg ann -> ShowS
[SectionArg ann] -> ShowS
SectionArg ann -> String
(Int -> SectionArg ann -> ShowS)
-> (SectionArg ann -> String)
-> ([SectionArg ann] -> ShowS)
-> Show (SectionArg ann)
forall ann. Show ann => Int -> SectionArg ann -> ShowS
forall ann. Show ann => [SectionArg ann] -> ShowS
forall ann. Show ann => SectionArg ann -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SectionArg ann] -> ShowS
$cshowList :: forall ann. Show ann => [SectionArg ann] -> ShowS
show :: SectionArg ann -> String
$cshow :: forall ann. Show ann => SectionArg ann -> String
showsPrec :: Int -> SectionArg ann -> ShowS
$cshowsPrec :: forall ann. Show ann => Int -> SectionArg ann -> ShowS
Show, a -> SectionArg b -> SectionArg a
(a -> b) -> SectionArg a -> SectionArg b
(forall a b. (a -> b) -> SectionArg a -> SectionArg b)
-> (forall a b. a -> SectionArg b -> SectionArg a)
-> Functor SectionArg
forall a b. a -> SectionArg b -> SectionArg a
forall a b. (a -> b) -> SectionArg a -> SectionArg b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> SectionArg b -> SectionArg a
$c<$ :: forall a b. a -> SectionArg b -> SectionArg a
fmap :: (a -> b) -> SectionArg a -> SectionArg b
$cfmap :: forall a b. (a -> b) -> SectionArg a -> SectionArg b
Functor)

-- | Extract annotation from 'SectionArg'.
sectionArgAnn :: SectionArg ann -> ann
sectionArgAnn :: SectionArg ann -> ann
sectionArgAnn (SecArgName ann :: ann
ann _)  = ann
ann
sectionArgAnn (SecArgStr ann :: ann
ann _)   = ann
ann
sectionArgAnn (SecArgOther ann :: ann
ann _) = ann
ann

-------------------------------------------------------------------------------
-- Name
-------------------------------------------------------------------------------

type FieldName = ByteString

-- | A field name.
--
-- /Invariant/: 'ByteString' is lower-case ASCII.
data Name ann  = Name       !ann !FieldName
  deriving (Name ann -> Name ann -> Bool
(Name ann -> Name ann -> Bool)
-> (Name ann -> Name ann -> Bool) -> Eq (Name ann)
forall ann. Eq ann => Name ann -> Name ann -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Name ann -> Name ann -> Bool
$c/= :: forall ann. Eq ann => Name ann -> Name ann -> Bool
== :: Name ann -> Name ann -> Bool
$c== :: forall ann. Eq ann => Name ann -> Name ann -> Bool
Eq, Int -> Name ann -> ShowS
[Name ann] -> ShowS
Name ann -> String
(Int -> Name ann -> ShowS)
-> (Name ann -> String) -> ([Name ann] -> ShowS) -> Show (Name ann)
forall ann. Show ann => Int -> Name ann -> ShowS
forall ann. Show ann => [Name ann] -> ShowS
forall ann. Show ann => Name ann -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Name ann] -> ShowS
$cshowList :: forall ann. Show ann => [Name ann] -> ShowS
show :: Name ann -> String
$cshow :: forall ann. Show ann => Name ann -> String
showsPrec :: Int -> Name ann -> ShowS
$cshowsPrec :: forall ann. Show ann => Int -> Name ann -> ShowS
Show, a -> Name b -> Name a
(a -> b) -> Name a -> Name b
(forall a b. (a -> b) -> Name a -> Name b)
-> (forall a b. a -> Name b -> Name a) -> Functor Name
forall a b. a -> Name b -> Name a
forall a b. (a -> b) -> Name a -> Name b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Name b -> Name a
$c<$ :: forall a b. a -> Name b -> Name a
fmap :: (a -> b) -> Name a -> Name b
$cfmap :: forall a b. (a -> b) -> Name a -> Name b
Functor)

mkName :: ann -> FieldName -> Name ann
mkName :: ann -> FieldName -> Name ann
mkName ann :: ann
ann bs :: FieldName
bs = ann -> FieldName -> Name ann
forall ann. ann -> FieldName -> Name ann
Name ann
ann ((Char -> Char) -> FieldName -> FieldName
B.map Char -> Char
Char.toLower FieldName
bs)

getName :: Name ann -> FieldName
getName :: Name ann -> FieldName
getName (Name _ bs :: FieldName
bs) = FieldName
bs

nameAnn :: Name ann -> ann
nameAnn :: Name ann -> ann
nameAnn (Name ann :: ann
ann _) = ann
ann