config-value 0.7.0.1 → 0.8.3
raw patch · 13 files changed
Files
- CHANGELOG.md +31/−0
- README.md +16/−7
- config-value.cabal +7/−5
- config-value.vim +8/−0
- src/Config.hs +13/−16
- src/Config/Lexer.x +22/−20
- src/Config/LexerUtils.hs +3/−6
- src/Config/Macro.hs +260/−0
- src/Config/Number.hs +5/−5
- src/Config/Parser.y +12/−8
- src/Config/Pretty.hs +24/−10
- src/Config/Tokens.hs +4/−3
- src/Config/Value.hs +2/−2
CHANGELOG.md view
@@ -1,3 +1,34 @@+0.8.3+---+* Add `prettyInline` for layout-free pretty-printing++0.8.2.1+---+* Fix pretty-printing bug with long string literals++0.8.2+---+* Add `+` and `-` to the set of layout-based list syntax bullets.+ All elements of the list are checked to see that a consistent+ bullet is used. Different bullets might be used to help make+ nested lists more understandable. `-` might be used to make things+ look more like YAML++0.8.1+---+* Allow underscores in number literals+ Copied from <https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0076-numeric-underscores.rst#new-syntax-this-proposal>++ Underscores are allowed and ignored+ - in the *middle* of integer-parts of the literal syntax+ - between base-markers (0x, 0o, 0b) and number part+ - before the `eEpP` part of an exponent++0.8+---+* Allow atoms and section names to start with `@` or `$`+* Add `Config.Macro` module+ 0.7.0.1 ---
README.md view
@@ -1,10 +1,12 @@ # config-value -[](https://hackage.haskell.org/package/config-value) [](http://travis-ci.org/glguy/config-value)+[](https://hackage.haskell.org/package/config-value) [](http://travis-ci.com/glguy/config-value) This package implements a simple, layout-based value definition language used for supplying configuration values to various applications. +Before starting to use config-value, you probably want to read the documentation for [config-schema](https://github.com/glguy/config-schema) to see the user-friendly way to wrap this library.+ Live Demo -------- @@ -19,6 +21,8 @@ configuration: {} -- empty section + inline-maps: {key1: value1, key2: value2}+ sections: "glguy" @@ -28,14 +32,16 @@ so you can comment out otherwise valid portions of your config -}- atoms : yes+ atoms: yes - decimal : -1234+ decimal: -1234 hexadecimal: 0x1234- octal : 0o1234- binary : 0b1010- floating : 12.34e56+ octal: 0o1234+ binary: 0b1010 + floats: [1e2, 0x3p-5, 24.48]+ underscores: 1_000_000+ lists: * sections: in-lists next-section: still-in-list@@ -45,7 +51,10 @@ * "lists" * 3 -unicode : "standard Haskell format strings (1 ≤ 2)\x2228(2 ≤ 3)"+unicode: "standard Haskell format strings (1 ≤ 2)x2228(2 ≤ 3)"++multiline: "haskell style\+ \string gaps" ``` Format
config-value.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: config-value-version: 0.7.0.1+version: 0.8.3 synopsis: Simple, layout-based value language similar to YAML or JSON license: MIT license-file: LICENSE@@ -15,7 +15,7 @@ with fewer special cases and fewer dependencies. It emphasizes layout structure for sections and lists, and requires quotes around strings.-tested-with: GHC==8.0.2, GHC==8.2.2, GHC==8.4.4, GHC==8.6.5, GHC==8.8.1+tested-with: GHC==8.0.2, GHC==8.2.2, GHC==8.4.4, GHC==8.6.5, GHC==8.8.4, GHC==8.10.2, GHC==9.0.1 extra-source-files: README.md@@ -28,6 +28,7 @@ Config Config.Lens Config.Number+ Config.Macro other-modules: Config.Lexer@@ -39,14 +40,15 @@ Config.Value build-depends:- base >= 4.8 && < 4.14,+ base >= 4.8 && < 4.18, array >= 0.4 && < 0.6,+ containers >= 0.5 && < 0.7, pretty >= 1.1.1.0 && < 1.2,- text >= 1.2.0.4 && < 1.3+ text >= 1.2.0.4 && < 2.1, build-tool-depends: alex:alex ^>= 3.2.4,- happy:happy ^>= 1.19.12,+ happy:happy >= 1.19 && <1.21, hs-source-dirs: src default-language: Haskell2010
config-value.vim view
@@ -17,11 +17,15 @@ syn match cvFloat "-\=[0-9]\+\.[0-9]\+\([eE][-+]\=[0-9]\+\)\=\>" syn match cvFloat "-\=[0-9]\+[eE][-+]\=[0-9]\+\>" +syn match cvVariable "$[a-zA-Z0-9\._\-]*\>"+syn match cvDirective "@[a-zA-Z0-9\._\-]*\>" syn match cvAtom "\<[a-zA-Z][a-zA-Z0-9\._\-]*\>" syn match cvLineComment "--.*$" syn region cvBlockComment start="{-" end="-}" contains=cvString,cvBlockComment +hi def link cvVariable Macro+hi def link cvDirective Include hi def link cvAtom Identifier hi def link cvDelimiter Delimiter @@ -35,3 +39,7 @@ hi def link cvComment Comment let b:current_syntax = "config-value"++setlocal commentstring=--%s+setlocal comments=:--+let b:undo_ftplugin = "setl com< commentstring<"
src/Config.hs view
@@ -91,8 +91,8 @@ indented to the right of the key. The lexical syntax for section names is identical to the lexical syntax-of /atoms/. Section names are nonempty sequences starting with an /alpha/-character followed by zero or more /alpha/, /digit/, /period/ (.),+of /atoms/. Section names are nonempty sequences starting with an /alpha/,+@$@ or @\@@ character followed by zero or more /alpha/, /digit/, /period/ (.), underscore (_), or dash (-). Section lists can be nested.@@ -128,9 +128,11 @@ Example: @[1, 2, 3]@ -Layout list entries are started with a leading @*@. Each leading @*@ must occur-in the some column of the file. Lists can be nested by starting the new list-on a column to the right of the current list.+Layout list entries are started with a leading @*@, @+@, or @-@. Each leading bullet+must occur in the some column of the file. Lists can be nested by starting the new+list on a column to the right of the current list. A single list must use the same+bullet token for every element of the list. Nested lists can choose a different+bullet. This can help visually distinguish nested lists. Layout based lists can not occur inside inline list syntax. Layout based section lists can occur inside layout based lists@@ -205,8 +207,9 @@ /Atoms/ are unquoted strings that are distinct from normal /text/ values. This type is intended to represent enumerations in a configuration file. -Atoms are nonempty sequences starting with an /alpha/ character followed by-zero or more /alpha/, /digit/, /period/ (.), underscore (_), or dash (-).+Atoms are nonempty sequences starting with an /alpha/, @$@, or @\@@ character+followed by zero or more /alpha/, /digit/, /period/ (.), underscore (_), or+dash (-). Lexical syntax: @$alpha [$alpha $digit $unidigit \\. _ \\-]*@ @@ -243,6 +246,7 @@ -- * Pretty-printing , pretty+ , prettyInline -- * Types , Section(..)@@ -264,14 +268,12 @@ import Config.Number (Number, numberToInteger, numberToRational, integerToNumber, rationalToNumber) import Config.Value (Atom(..), Value(..), Section(..), valueAnn) import Config.Parser (parseValue)-import Config.Pretty (pretty)+import Config.Pretty (pretty, prettyInline) import Config.Lexer (scanTokens) import Config.Tokens (Error(..), Position(..), Located(..), layoutPass, Token) import qualified Config.Tokens as T import Control.Exception (Exception(..))-import Numeric (showIntAtBase)-import Data.Char (intToDigit) import Data.Text (Text) import qualified Data.Text as Text @@ -306,7 +308,7 @@ T.Error e -> explainError e T.Atom atom -> "parse error: unexpected atom: `" ++ Text.unpack atom ++ "`" T.String str -> "parse error: unexpected string: " ++ show (Text.unpack str)- T.Bullet -> "parse error: unexpected bullet '*'"+ T.Bullet s -> "parse error: unexpected bullet '" ++ Text.unpack s ++ "'" T.Comma -> "parse error: unexpected comma ','" T.Section s -> "parse error: unexpected section: `" ++ Text.unpack s ++ "`" T.Number{} -> "parse error: unexpected number"@@ -317,11 +319,6 @@ T.LayoutSep -> "parse error: unexpected end of block" T.LayoutEnd -> "parse error: unexpected end of block" T.EOF -> "parse error: unexpected end of file"--showIntAtBase' :: (Show a, Integral a) => String -> a -> (Int -> Char) -> a -> ShowS-showIntAtBase' pfx base toDigit n- | n < 0 = showChar '-' . showString pfx . showIntAtBase base toDigit (negate n)- | otherwise = showString pfx . showIntAtBase base toDigit n explainError :: Error -> String explainError e =
src/Config/Lexer.x view
@@ -21,19 +21,20 @@ $asciialpha = [A-Z a-z] $digit = [0-9]-$octdigit = [0-7]-$hexdigit = [0-9a-fA-F]-$bindigit = [0-1]+$octit = [0-7]+$hexit = [0-9a-fA-F]+$binit = [0-1] $white_no_nl = $white # \n-$charesc = [abfnrtv\\\"']+$charesc = [abfnrtv\\\"'&] $cntrl = [A-Z@\[\\\]\^_] $alpha = [$unilower $uniupper $asciialpha] +@spacer = _* -@decimal = $digit+-@octal = $octdigit+-@binary = $bindigit+-@hexadecimal = $hexdigit++@decimal = $digit (@spacer $digit)*+@octal = $octit (@spacer $octit)*+@binary = $binit (@spacer $binit)*+@hexadecimal = $hexit (@spacer $hexit)* -- Copied from Haskell 2010 @ascii = \^ $cntrl@@ -44,15 +45,14 @@ | SP | DEL @escape = $charesc | @ascii- | @decimal- | o @octal- | x @hexadecimal- | &+ | $digit++ | o $octit++ | x $hexit+ -@atom = $alpha [$alpha $digit $unidigit \. _ \-]*+@atom = [$alpha \$ \@] [$alpha $digit $unidigit \. _ \-]* -@exponent = [Ee] [\-\+]? @decimal-@hexexponent = [Pp] [\-\+]? @decimal+@exponent = @spacer [Ee] [\-\+]? @decimal+@hexexponent = @spacer [Pp] [\-\+]? @decimal config :- @@ -65,12 +65,14 @@ "[" { token_ OpenList } "," { token_ Comma } "]" { token_ CloseList }-"*" { token_ Bullet }+"*" { token Bullet }+"-" { token Bullet }+"+" { token Bullet } -"-"? 0 [Xx] @hexadecimal ("." @hexadecimal?)? @hexexponent? { token number }-"-"? 0 [Oo] @octal ("." @octal ?)? { token number }-"-"? 0 [Bb] @binary ("." @binary ?)? { token number }-"-"? @decimal ("." @decimal ?)? @exponent? { token number }+"-"? 0 [Xx] @spacer @hexadecimal ("." @hexadecimal?)? @hexexponent? { token number }+"-"? 0 [Oo] @spacer @octal ("." @octal ?)? { token number }+"-"? 0 [Bb] @spacer @binary ("." @binary ?)? { token number }+"-"? @decimal ("." @decimal ?)? @exponent? { token number } @atom { token Atom } @atom $white_no_nl* : { token section } \" { startString }
src/Config/LexerUtils.hs view
@@ -27,16 +27,12 @@ , errorAction ) where -import Control.Applicative-import Data.Char (GeneralCategory(..), generalCategory, digitToInt,- isAscii, isSpace, ord, isDigit, isHexDigit)+import Data.Char (GeneralCategory(..), generalCategory, isAscii, isSpace, ord) import Data.Text (Text) import Data.Word (Word8)-import Numeric (readInt, readHex) import qualified Data.Text as Text import Config.Tokens-import Config.Number import qualified Config.NumberParser ------------------------------------------------------------------------@@ -152,7 +148,8 @@ number :: Text {- ^ sign-prefix-digits -} -> Token-number = Number . Config.NumberParser.number . Text.unpack . Text.toUpper+number = Number . Config.NumberParser.number+ . Text.unpack . Text.toUpper . Text.filter ('_' /=) -- | Process a section heading token section :: Text -> Token
+ src/Config/Macro.hs view
@@ -0,0 +1,260 @@+{-# LANGUAGE Safe, OverloadedStrings, DeriveTraversable, RankNTypes #-}+{-|+Module : Config.Macro+Description : Configuration pre-processor adding support for aliases and common sections+Copyright : (c) Eric Mertens, 2020+License : ISC+Maintainer : emertens@gmail.com++This module provides assigns meaning to atoms and section names that start with @\@@+and @$@. It provides processing pass for configuration to use local variables and+inclusion to better structure configuration.++= Sigils++* @$@ starts a variable.+* @\@@ starts a directive.++Merge key-value mappings using @\@splice@.++Load external configuration with @\@load@.++= Variables++Variables are atoms that start with a @$@ sigil. Variables are defined by+setting a variable as a section name. This variable will remain in+scope for the remainder of the sections being defined.++Variables used in a value position will be replaced with their previously+defined values.++@+$example: 42+field1: $example+field2: [0, $example]+@++expands to++@+field1: 42+field2: [0, 42]+@++Later variable definitions will shadow earlier definitions.++@+{ $x: 1, $x: 2, k: $x }+@++expands to++@+{ k: 2 }+@++Scoping examples:++@+top1:+ a: $x -- BAD: $x not defined yet+ $x: 42 -- $x is now defined to be 42+ b: $x -- OK: $x was defined above+ c: {sub1: $x, sub2: [$x]} -- OK: $x in scope in subsections+ -- note: $x now goes out of scope+top2: $x -- BAD: $x no longer in scope+@++Macros are expanded at their definition site. All variables are resolved before+adding the new variable into the environment. Variables are lexically scoped+rather than dynamically scoped.++Allowed:++@+$x: 1+$y: $x -- OK, y is now 1+@++Not allowed:++@+$y: $x -- BAD: $x was not in scope+$x: 1+z: $y+@++= Sections splicing++One sections value can be spliced into another sections value using the @\@splice@+directive. It is an error to splice a value that is not a key-value sections.++@+$xy: { x: 0, y: 1 }+example:+ \@splice: $xy+ z: 2+@++expands to++@+example:+ x: 0+ y: 1+ z: 2+@++= File loading++The @\@load@ directive is intended including configuration from other sources.+'loadFileWithMacros' provides an interpretation of this directive that loads+other files. An arbitrary interpretation can be defined with 'expandMacros''++To load a value define a key-value mapping with a single @\@load@ key with a+value specifying the location to load from.++@+x: @load: "fourty-two.cfg"+@++could expand to++@+x: 42+@++-}+module Config.Macro (+ -- * Macro expansion primitives+ MacroError(..),+ expandMacros,+ expandMacros',++ -- * File loader with inclusion+ LoadFileError(..),+ FilePosition(..),+ loadFileWithMacros+ ) where++import Data.Text (Text)+import qualified Data.Text as Text+import qualified Data.Text.IO as Text+import Control.Exception+import Config+import Data.Map (Map)+import Data.Typeable (Typeable)+import qualified Data.Map as Map++-- | Errors from macro expansion annotated with the 'valueAnn' from+-- the 'Value' nearest to the problem (typically a file position).+data MacroError a+ = UndeclaredVariable a Text -- ^ Variable used before its defintion+ | UnknownDirective a Text -- ^ Unknown directive+ | BadSplice a -- ^ Incorrect use of @\@splice@+ | BadLoad a -- ^ Incorrect use of @\@load@+ deriving+ (Eq, Read, Show, Functor, Foldable, Traversable)++instance (Typeable a, Show a) => Exception (MacroError a)++data Special = Plain | Variable Text | Splice | Load++processAtom :: a -> Text -> Either (MacroError a) Special+processAtom a txt =+ case Text.uncons txt of+ Just ('@',"splice") -> Right Splice+ Just ('@',"load" ) -> Right Load+ Just ('@',t ) -> Left (UnknownDirective a t)+ Just ('$',t ) -> Right (Variable t)+ _ -> Right Plain++-- | Expand macros in a configuration value.+--+-- @\@load@ not supported and results in a 'BadLoad' error.+expandMacros :: Value a -> Either (MacroError a) (Value a)+expandMacros = expandMacros' Left (Left . BadLoad . valueAnn) Map.empty++-- | Expand macros in a configuration value using a pre-populated environment.+expandMacros' ::+ Monad m =>+ (forall b. MacroError a -> m b) {- ^ failure -} ->+ (Value a -> m (Value a)) {- ^ @\@load@ implementation -} ->+ Map Text (Value a) {- ^ variable environment -} ->+ Value a {- ^ value to expand -} ->+ m (Value a) {- ^ expanded value -}+expandMacros' failure load = go+ where+ proc a txt = either failure pure (processAtom a txt)++ go env v =+ case v of+ Number a x -> pure (Number a x)+ Text a x -> pure (Text a x)+ List a x -> List a <$> traverse (go env) x++ Sections _ [Section _ "@load" arg] -> load =<< go env arg+ Sections a x -> Sections a <$> elaborateSections env x++ Atom a x ->+ do x' <- proc a (atomName x)+ case x' of+ Plain -> pure (Atom a x)+ Splice -> failure (BadSplice a)+ Load -> failure (BadLoad a)+ Variable var ->+ case Map.lookup var env of+ Nothing -> failure (UndeclaredVariable a var)+ Just y -> pure y++ elaborateSections _ [] = pure []+ elaborateSections env (Section a k v : xs) =+ do special <- proc a k+ v' <- go env v+ case special of+ Load -> failure (BadLoad a)+ Variable var -> elaborateSections (Map.insert var v' env) xs+ Plain -> (Section a k v' :) <$> elaborateSections env xs+ Splice ->+ case v' of+ Sections _ ys -> (ys++) <$> elaborateSections env xs+ _ -> failure (BadSplice a)++-- | A pair of filepath and position+data FilePosition = FilePosition FilePath Position+ deriving (Read, Show, Ord, Eq)++-- | Errors thrown by 'loadFileWithMacros'+data LoadFileError+ = LoadFileParseError FilePath ParseError -- ^ failure to parse a file+ | LoadFileMacroError (MacroError FilePosition) -- ^ failure to expand macros+ deriving (Eq, Read, Show)++instance Exception LoadFileError++-- | Load a configuration value from a given file path.+--+-- @\@load@ will compute included file path from the given function given the+-- load argument and current configuration file path.+--+-- Valid @\@load@ arguments are string literals use as arguments to+-- the path resolution function.+--+-- Throws `IOError` from file loads and `LoadFileError`+loadFileWithMacros ::+ (Text -> FilePath -> IO FilePath) {- ^ inclusion path resolution -} ->+ FilePath {- ^ starting file path -} ->+ IO (Value FilePosition) {- ^ macro-expanded config value -}+loadFileWithMacros findPath = go+ where+ go path =+ do txt <- Text.readFile path+ v1 <- case parse txt of+ Left e -> throwIO (LoadFileParseError path e)+ Right v -> pure v+ let v2 = FilePosition path <$> v1+ let loadImpl pathVal =+ case pathVal of+ Text _ str -> go =<< findPath str path+ _ -> throwIO (LoadFileMacroError (BadLoad (valueAnn pathVal)))+ expandMacros' (throwIO . LoadFileMacroError) loadImpl Map.empty v2
src/Config/Number.hs view
@@ -1,4 +1,4 @@-{-# Language DeriveDataTypeable, DeriveGeneric #-}+{-# Language DeriveDataTypeable, DeriveGeneric, Safe #-} {-| Module : Config.Number Description : Scientific-notation numbers with explicit radix@@ -61,17 +61,17 @@ Radix16{} -> 16 -- | Convert a number to a 'Rational'. Warning: This can use a--- lot of member in the case of very large exponent parts.+-- lot of memory in the case of very large exponent parts. numberToRational :: Number -> Rational numberToRational (MkNumber r c) = case r of Radix2 -> c Radix8 -> c Radix10 e -> c * 10 ^^ e- Radix16 e -> c * 2 ^^ e+ Radix16 e -> c * 2 ^^ e -- | Convert a number to a 'Integer'. Warning: This can use a--- lot of member in the case of very large exponent parts.+-- lot of memory in the case of very large exponent parts. numberToInteger :: Number -> Maybe Integer numberToInteger n | denominator r == 1 = Just $! numerator r@@ -85,4 +85,4 @@ -- | 'Rational' to a radix 10 'Number' with no exponent rationalToNumber :: Rational -> Number-rationalToNumber r = (MkNumber (Radix10 0) r)+rationalToNumber = MkNumber (Radix10 0)
src/Config/Parser.y view
@@ -1,5 +1,5 @@ {-{-# LANGUAGE Trustworthy #-}+{-# LANGUAGE Trustworthy, OverloadedStrings #-} module Config.Parser (parseValue) where @@ -15,11 +15,13 @@ STRING { Located _ T.String{} } ATOM { Located _ T.Atom{} } NUMBER { Located _ T.Number{} }-'*' { Located $$ T.Bullet }-'[' { Located $$ T.OpenList }+'*' { Located $$ (T.Bullet "*") }+'+' { Located $$ (T.Bullet "+") }+'-' { Located $$ (T.Bullet "-") }+'[' { Located $$ T.OpenList } ',' { Located _ T.Comma } ']' { Located _ T.CloseList }-'{' { Located $$ T.OpenMap }+'{' { Located $$ T.OpenMap } '}' { Located _ T.CloseMap } SEP { Located _ T.LayoutSep } END { Located _ T.LayoutEnd }@@ -37,7 +39,9 @@ value :: { Value Position } : sections END { sections $1 }- | '*' list END { List $1 (reverse $2) }+ | '*' list('*') END { List $1 (reverse $2) }+ | '-' list('-') END { List $1 (reverse $2) }+ | '+' list('+') END { List $1 (reverse $2) } | simple { $1 } simple :: { Value Position }@@ -70,9 +74,9 @@ section :: { Section Position } : SECTION value { section $1 $2 } -list :: { [Value Position] }- : value { [$1] }- | list SEP '*' value { $4 : $1 }+list(blt) :: { [Value Position] }+ : value { [$1] }+ | list(blt) SEP blt value { $4 : $1 } inlinelist :: { [Value Position] } : { [] }
src/Config/Pretty.hs view
@@ -1,9 +1,10 @@+{-# Language Safe #-} -- | Pretty-printing implementation for 'Value'-module Config.Pretty (pretty) where+module Config.Pretty (pretty, prettyInline) where import Data.Char (isPrint, isDigit,intToDigit) import Data.List (mapAccumL)-import Data.Ratio (numerator, denominator)+import Data.Ratio (denominator) import qualified Data.Text as Text import Text.PrettyPrint import Numeric(showIntAtBase)@@ -37,16 +38,17 @@ where radix = radixToInt r pref = if c < 0 then char '-' else empty- num = text (showIntAtBase (fromIntegral radix) intToDigit whole "") -- XXX- <> fracPart frac- (whole,frac) = properFraction (abs c)+ num = text (showIntAtBase (fromIntegral radix) intToDigit whole "")+ <> fracPart+ (whole,frac) = properFraction (abs c) :: (Integer, Rational) expPart _ 0 = text ""- expPart c i = text (c : show i)- fracPart 0 = text ""- fracPart i = text ('.' : showFrac radix frac)+ expPart p i = text (p : show i)+ fracPart+ | 0 == frac = text ""+ | otherwise = text ('.' : showFrac radix frac) showFrac :: Int -> Rational -> String-showFrac radix 0 = ""+showFrac _ 0 = "" showFrac radix x = intToDigit w : rest where (w,f) = properFraction (x * fromIntegral radix)@@ -55,7 +57,7 @@ | otherwise = "" prettyText :: String -> Doc-prettyText = doubleQuotes . cat . snd . mapAccumL ppChar True+prettyText = doubleQuotes . hcat . snd . mapAccumL ppChar True where ppChar s x | isDigit x = (True, if not s then text "\\&" <> char x else char x)@@ -93,3 +95,15 @@ isBig (Sections _ (_:_)) = True isBig (List _ (_:_)) = True isBig _ = False++-- | Pretty-printer that uses no layout for sections or lists.+prettyInline :: Value a -> Doc+prettyInline value =+ case value of+ Number _ n -> prettyNumber n+ Text _ t -> prettyText (Text.unpack t)+ Atom _ t -> text (Text.unpack (atomName t))+ List _ xs -> brackets (list (map prettyInline xs))+ Sections _ xs -> braces (list [text (Text.unpack k) <> colon <> prettyInline v | Section _ k v <- xs])+ where+ list = hcat . punctuate comma
src/Config/Tokens.hs view
@@ -1,3 +1,4 @@+{-# Language Safe #-} -- | This module provides the token type used in the lexer and -- parser and provides the extra pass to insert layout tokens. module Config.Tokens@@ -10,7 +11,7 @@ ) where import Data.Text (Text)-import Config.Number+import Config.Number (Number) -- | A position in a text file data Position = Position@@ -36,7 +37,7 @@ = Section Text | String Text | Atom Text- | Bullet+ | Bullet Text | Comma | Number Number | OpenList@@ -99,5 +100,5 @@ usesLayout :: Located Token -> Bool usesLayout t | Section{} <- locThing t = True- | Bullet <- locThing t = True+ | Bullet{} <- locThing t = True | otherwise = False
src/Config/Value.hs view
@@ -1,4 +1,4 @@-{-# Language DeriveGeneric, DeriveTraversable, DeriveDataTypeable #-}+{-# Language DeriveGeneric, DeriveTraversable, DeriveDataTypeable, Safe #-} -- | This module provides the types used in this package for configuration. -- Visit "Config.Parser" to parse values of this type in a convenient@@ -21,7 +21,7 @@ -- -- Example: ----- * @my-key: my-value@ is @'Section' _ ('Atom' _ "my-key") ('Atom' _ "my-value")@+-- * @my-key: my-value@ is @'Section' _ "my-key" ('Atom' _ "my-value")@ data Section a = Section { sectionAnn :: a , sectionName :: Text