1{-# LANGUAGE DeriveFunctor #-} 2{-# LANGUAGE DeriveFoldable #-} 3{-# LANGUAGE DeriveTraversable #-} 4-- | Cabal-like file AST types: 'Field', 'Section' etc 5-- 6-- These types are parametrized by an annotation. 7module Distribution.Fields.Field ( 8 -- * Cabal file 9 Field (..), 10 fieldName, 11 fieldAnn, 12 fieldUniverse, 13 FieldLine (..), 14 fieldLineAnn, 15 fieldLineBS, 16 SectionArg (..), 17 sectionArgAnn, 18 -- * Name 19 FieldName, 20 Name (..), 21 mkName, 22 getName, 23 nameAnn, 24 ) where 25 26import Prelude () 27import Distribution.Compat.Prelude 28import Data.ByteString (ByteString) 29import qualified Data.ByteString.Char8 as B 30import qualified Data.Char as Char 31 32------------------------------------------------------------------------------- 33-- Cabal file 34------------------------------------------------------------------------------- 35 36-- | A Cabal-like file consists of a series of fields (@foo: bar@) and sections (@library ...@). 37data Field ann 38 = Field !(Name ann) [FieldLine ann] 39 | Section !(Name ann) [SectionArg ann] [Field ann] 40 deriving (Eq, Show, Functor, Foldable, Traversable) 41 42-- | Section of field name 43fieldName :: Field ann -> Name ann 44fieldName (Field n _ ) = n 45fieldName (Section n _ _) = n 46 47fieldAnn :: Field ann -> ann 48fieldAnn = nameAnn . fieldName 49 50-- | All transitive descendants of 'Field', including itself. 51-- 52-- /Note:/ the resulting list is never empty. 53-- 54fieldUniverse :: Field ann -> [Field ann] 55fieldUniverse f@(Section _ _ fs) = f : concatMap fieldUniverse fs 56fieldUniverse f@(Field _ _) = [f] 57 58-- | A line of text representing the value of a field from a Cabal file. 59-- A field may contain multiple lines. 60-- 61-- /Invariant:/ 'ByteString' has no newlines. 62data FieldLine ann = FieldLine !ann !ByteString 63 deriving (Eq, Show, Functor, Foldable, Traversable) 64 65-- | @since 3.0.0.0 66fieldLineAnn :: FieldLine ann -> ann 67fieldLineAnn (FieldLine ann _) = ann 68 69-- | @since 3.0.0.0 70fieldLineBS :: FieldLine ann -> ByteString 71fieldLineBS (FieldLine _ bs) = bs 72 73-- | Section arguments, e.g. name of the library 74data SectionArg ann 75 = SecArgName !ann !ByteString 76 -- ^ identifier, or something which looks like number. Also many dot numbers, i.e. "7.6.3" 77 | SecArgStr !ann !ByteString 78 -- ^ quoted string 79 | SecArgOther !ann !ByteString 80 -- ^ everything else, mm. operators (e.g. in if-section conditionals) 81 deriving (Eq, Show, Functor, Foldable, Traversable) 82 83-- | Extract annotation from 'SectionArg'. 84sectionArgAnn :: SectionArg ann -> ann 85sectionArgAnn (SecArgName ann _) = ann 86sectionArgAnn (SecArgStr ann _) = ann 87sectionArgAnn (SecArgOther ann _) = ann 88 89------------------------------------------------------------------------------- 90-- Name 91------------------------------------------------------------------------------- 92 93type FieldName = ByteString 94 95-- | A field name. 96-- 97-- /Invariant/: 'ByteString' is lower-case ASCII. 98data Name ann = Name !ann !FieldName 99 deriving (Eq, Show, Functor, Foldable, Traversable) 100 101mkName :: ann -> FieldName -> Name ann 102mkName ann bs = Name ann (B.map Char.toLower bs) 103 104getName :: Name ann -> FieldName 105getName (Name _ bs) = bs 106 107nameAnn :: Name ann -> ann 108nameAnn (Name ann _) = ann 109