Giter VIP home page Giter VIP logo

ini's Introduction

ini Hackage

Quick and easy configuration files in the INI format for Haskell.

Format rules and recommendations:

  • foo: bar or foo=bar are allowed.
  • The : syntax is space-sensitive.
  • Keys are case-sensitive.
  • Lower-case is recommended.
  • Values can be empty.
  • Keys cannot contain :, =, [, or ].
  • Comments must start at the beginning of the line with ; or #.

An example configuration file:

# Some comment.
[SERVER]
port=6667
hostname=localhost
[AUTH]
user=hello
pass=world
# Salt can be an empty string.
salt=

Parsing example:

> parseIni "[SERVER]\nport: 6667\nhostname: localhost"
Right (Ini {unIni = fromList [("SERVER",fromList [("hostname","localhost")
                                                 ,("port","6667")])]})

Extracting values:

> parseIni "[SERVER]\nport: 6667\nhostname: localhost" >>=
  lookupValue "SERVER" "hostname"
Right "localhost"

Parsing:

> parseIni "[SERVER]\nport: 6667\nhostname: localhost" >>=
  readValue "SERVER" "port" decimal
Right 6667

Import Data.Text.Read to use decimal.

Related packages

ini-qq provides a quasiquoter for INI.

ini's People

Contributors

akc avatar bmjames avatar chris-martin avatar chrisdone avatar cuklev avatar dacto avatar gwils avatar jaspervdj avatar jcristovao avatar joehillen avatar k-bx avatar neilmayhew avatar pmlodawski avatar pozix604 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

ini's Issues

Preserve section order

There are some INI files where the order of the sections is relevant.
Look for example at the pacman.conf of the Arch Linux package manager (which is my use case).
I don't think giving up on the HashMap as an underlying datastructure is the right way since it's sufficient for probably most of the use cases, but would an order-preserving version in a separate module be acceptable? Or a parameterized Ini type and Ini simply be a type alias like

newtype Ini' f = Ini' { unIni :: f Text (HashMap Text Text) }
type Ini = Ini' HashMap

If there's any chance such an extension were accepted I'd volunteer for the implementation.
Thanks!

Install package by cabal error

$ cabal install ini
Resolving dependencies...
Notice: installing into a sandbox located at
/home/unclechu/Fedora22/dev/haskell/ini-test/.cabal-sandbox
Downloading ini-0.3.4...
Configuring ini-0.3.4...
Building ini-0.3.4...
Failed to install ini-0.3.4
Last 10 lines of the build log ( /home/unclechu/Fedora22/dev/haskell/ini-test/.cabal-sandbox/logs/ini-0.3.4.log ):
Building ini-0.3.4...
Preprocessing library ini-0.3.4...
[1 of 1] Compiling Data.Ini         ( src/Data/Ini.hs, dist/dist-sandbox-2b19b00c/build/Data/Ini.o )

src/Data/Ini.hs:125:48:
    Not in scope: ‘<*’
    Perhaps you meant one of these:
      ‘*’ (imported from Prelude), ‘<>’ (imported from Data.Monoid),
      ‘<*.’ (imported from Data.Attoparsec.Text)
cabal: Error: some packages failed to install:
ini-0.3.4 failed during the building phase. The exception was:
ExitFailure 1
$ lsb_release -a
LSB Version:    :core-4.1-amd64:core-4.1-noarch
Distributor ID: Fedora
Description:    Fedora release 23 (Twenty Three)
Release:        23
Codename:       TwentyThree
$ uname -a
Linux ***HOSTNAME*** 4.4.4-301.fc23.x86_64 #1 SMP Fri Mar 4 17:42:42 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

Can't parse an empty file or empty section

I had expected that, if I read a completely empty file with readIniFile, it would return Ini (fromList []). Instead, the parser fails with "not enough input".

A similar problem occurs with a file that contains an empty section.

ghci> writeIniFile "foo.ini" $ Ini (fromList [])
ghci> readIniFile "foo.ini"
Left "not enough input"
ghci> writeIniFile "foo.ini" $ Ini (fromList [("foo", empty)])
ghci> readIniFile "foo.ini"
Left "not enough input"

Ini file returning an empty Ini structure?

Sorry for the lack of narrowing this down, but I didn't want to just let things pass without letting you know about this issue. If you want to flag this as an unsupported format and close it, that'd be fine by me.

I'm trying to parse ini files from deviationTx (deviationTx.com), which uses some odd features of the ini file format. Tried feeding one to readIniFile to see if I could use this Data.Ini, and got back an empty list (Right (Ini {unIni = fromList []}).

Editing INI file?

Hi. Thanks for writing this library.
This is not as much of an issue as it is a question - how does one edit the parsed ini file? I need to replace some values and put the data in the file it was read from. Iterating over the structure to find 2 changes and write it back, line-by-line seems over the top. Newbie to haskell so I am not sure if functionality of editing the ini file is even something that can be done.

Thanks.

Semigroup backwards compatibility

0.3.6 loads Data.Semigroup without specifying semigroups as a dependency in its cabal file, nor specifying a base dependency for ghc 8 or greater which would cause the resolver to seek a working version automatically.

This means that people on 7.10 and lower can't use the package easily.

If I may, I would suggest adding

  if !impl(ghc >= 8)
    build-depends: semigroups >= 0.10 && < 0.19

to your cabal file.

Doesn't detect invalid input

λ> :{
λ| parseIni
λ|   "Name=Foo\n\
λ|   \Name[en_GB]=Fubar\n"
λ| :}
Right (Ini {iniSections = fromList [], iniGlobals = [("Name","Foo")]})

Semigroup could combine sections

When semigroupally combining Ini values that both define the same section, I was surprised to find that one of the sections is discarded. The monoid instance currently looks like this:

mappend x y = Ini {iniGlobals = mempty, iniSections = iniSections x <> iniSections y}

I was expecting sections of the same name to be merged.

Also, why discard all the globals?

Proposed change to the monoid instance:

mappend x y = Ini {
    iniGlobals = Map.unionWith (<>) (iniGlobals x) (iniGlobals y),
    iniSections = Map.unionWith (<>) (iniSections x) (iniSections y) }

Either way, whether you are interested in changing the instance or not, I'd be happy to send a PR with some documentation to mention how the instance behaves.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.