packages feed

ini (empty) → 0.0.0

raw patch · 4 files changed

+169/−0 lines, 4 filesdep +aesondep +attoparsecdep +basesetup-changed

Dependencies added: aeson, attoparsec, base, text, unordered-containers

Files

+ LICENSE view
@@ -0,0 +1,24 @@+Copyright (c) 2013, ini+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:+    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.+    * Redistributions in binary form must reproduce the above copyright+      notice, this list of conditions and the following disclaimer in the+      documentation and/or other materials provided with the distribution.+    * Neither the name of ini nor the+      names of its contributors may be used to endorse or promote products+      derived from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ ini.cabal view
@@ -0,0 +1,23 @@+name:                ini+version:             0.0.0+synopsis:            Quick and easy configuration files in the INI format.+description:         Simple, easy and fast configuration files in the INI format.+license:             BSD3+license-file:        LICENSE+author:              Chris Done+maintainer:          chrisdone@gmail.com+copyright:           2013 Chris Done+category:            Data, Configuration+build-type:          Simple+cabal-version:       >=1.8++library+  hs-source-dirs:    src/+  ghc-options:       -Wall -O2+  extensions:        OverloadedStrings+  exposed-modules:   Data.Ini+  build-depends:     base >= 4 && <5,+                     attoparsec,+                     text,+                     aeson,+                     unordered-containers
+ src/Data/Ini.hs view
@@ -0,0 +1,120 @@+-- | Clean configuration files in the INI format.+--+-- Format rules and recommendations:+--+--  * The @: @ syntax is space-sensitive.+--+--  * Keys are case-sensitive.+--+--  * Lower-case is recommended.+--+--  * Values can be empty.+--+--  * Keys cannot contain @:@, @=@, @[@, or @]@.+--+--  * Comments are not supported at this time.+--+-- An example configuration file:+--+-- @+-- [SERVER]+-- port=6667+-- hostname=localhost+-- [AUTH]+-- user: hello+-- pass: world+-- salt:+-- @+--+-- Parsing example:+--+-- >>> parseIni "[SERVER]\nport: 6667\nhostname: localhost"+-- Right (Ini {unIni = fromList [("SERVER",fromList [("hostname","localhost"),("port","6667")])]})+--++module Data.Ini+  (-- * Reading+   parseIniFile+  ,parseIni+   -- * Writing+  ,writeIniFile+  ,printIni+   -- * Types+  ,Ini(..)+   -- * Parsers+  ,iniParser+  ,sectionParser+  ,keyValueParser+  )+  where++import           Control.Monad+import           Data.Attoparsec.Combinator+import           Data.Attoparsec.Text+import           Data.Char+import           Data.HashMap.Strict (HashMap)+import qualified Data.HashMap.Strict as M+import           Data.Monoid+import           Data.Text (Text)+import qualified Data.Text as T+import qualified Data.Text.IO as T+import           Prelude hiding (takeWhile)++-- | An INI configuration.+newtype Ini = Ini { unIni :: HashMap Text (HashMap Text Text) }+  deriving (Show)++-- | Parse an INI file.+parseIniFile :: FilePath -> IO (Either String Ini)+parseIniFile = fmap parseIni . T.readFile++-- | Parse an INI config.+parseIni :: Text -> Either String Ini+parseIni = parseOnly iniParser++-- | Print the INI config to a file.+writeIniFile :: FilePath -> Ini -> IO ()+writeIniFile fp = T.writeFile fp . printIni++-- | Print an INI config.+printIni :: Ini -> Text+printIni (Ini sections) =+  T.concat (map buildSection (M.toList sections))+  where buildSection (name,pairs) =+          "[" <> name <> "]\n" <>+          T.concat (map buildPair (M.toList pairs))+        buildPair (name,value) =+          name <> ": " <> value++-- | Parser for an INI.+iniParser :: Parser Ini+iniParser = fmap Ini (fmap M.fromList (many1 sectionParser))++-- | A section. Format: @[foo]@. Conventionally, @[FOO]@.+sectionParser :: Parser (Text,HashMap Text Text)+sectionParser =+  do char '['+     name <- takeWhile (\c -> c /=']' && c /= '[')+     char ']'+     skipEndOfLine+     values <- many1 keyValueParser+     return (name,M.fromList values)++-- | A key-value pair. Either @foo: bar@ or @foo=bar@.+keyValueParser :: Parser (Text,Text)+keyValueParser =+  do key <- takeWhile1 (\c -> not (isDelim c || c == '[' || c == ']'))+     delim <- satisfy isDelim+     value <- fmap (clean delim) (takeWhile (not . isEndOfLine))+     skipEndOfLine+     return (key,value)+  where clean ':' = T.drop 1+        clean _   = id++-- | Is the given character a delimiter?+isDelim :: Char -> Bool+isDelim x = x == '=' || x == ':'++-- | Skip end of line and whitespace beyond.+skipEndOfLine :: Parser ()+skipEndOfLine = skipWhile (\c -> isEndOfLine c || isSpace c)