Added basic README
Getty Ritter
8 years ago
1 | # `config-ini` | |
2 | ||
3 | The `config-ini` library is a Haskell library for doing elementary INI file parsing in a quick and painless way. | |
4 | ||
5 | ## Basic Usage | |
6 | ||
7 | The `config-ini` library exports some simple monadic functions to make parsing INI-like configuration easier. INI files have a two-level structure: the top-level named chunks of configuration, and the individual key-value pairs contained within those chunks. For example, the following INI file has two sections, `NETWORK` and `LOCAL`, and each section contains its own key-value pairs separated by either `=` or `:`. Comments, which begin with `#` or `;`, are ignored: | |
8 | ||
9 | ~~~.ini | |
10 | [NETWORK] | |
11 | host = example.com | |
12 | port = 7878 | |
13 | ||
14 | # here is a comment | |
15 | [LOCAL] | |
16 | user = terry | |
17 | ~~~ | |
18 | ||
19 | The combinators provided here are designed to write quick and idiomatic parsers for basic INI files. Sections are parsed by `IniParser` computations, like `section` and its variations, while the fields within sections are parsed by `SectionParser` computations, like `field` and its variations. If we want to parse an INI file like the one above, treating the entire `LOCAL` section as optional, we can write it like this: | |
20 | ||
21 | ~~~.haskell | |
22 | data Config = Config | |
23 | { cfNetwork :: NetworkConfig, cfLocal :: Maybe LocalConfig } | |
24 | deriving (Eq, Show) | |
25 | ||
26 | data NetworkConfig = NetworkConfig | |
27 | { netHost :: String, netPort :: Int } | |
28 | deriving (Eq, Show) | |
29 | ||
30 | data LocalConfig = LocalConfig | |
31 | { localUser :: Text } | |
32 | deriving (Eq, Show) | |
33 | ||
34 | configParser :: IniParser Config | |
35 | configParser = do | |
36 | netCf <- section "NETWORK" $ do | |
37 | host <- fieldOf "host" string | |
38 | port <- fieldOf "port" number | |
39 | return NetworkConfig { netHost = host, netPort = port } | |
40 | locCf <- sectionMb "LOCAL" $ | |
41 | LocalConfig <$field "user" | |
42 | return Config { cfNetwork = netCf, cfLocal = locCf } | |
43 | ~~~ | |
44 | ||
45 | We can run our computation with `parseIniFile`, which, when run on our example file above, would produce the following: | |
46 | ||
47 | ~~~.haskell | |
48 | >>> parseIniFile example configParser | |
49 | Right (Config {cfNetwork = NetworkConfig {netHost = "example.com", netPort = 7878}, cfLocal = Just (LocalConfig {localUser = "terry"})}) | |
50 | ~~~ | |
51 | ||
52 | ## Combinators and Conventions | |
53 | ||
54 | There are several variations on the same basic functionality that appear in `config-ini`. All functions that start with `section` are for parsing section-level chunks of an INI file, while all functions that start with `field` are for parsing key-value pairs within a section. Because it's reasonably common, there are also special `fieldFlag` functions which return `Bool` values, parsed in a relatively loose way. | |
55 | ||
56 | All functions which end in `Mb` return a `Maybe` value, returning `Nothing` if the section or key was not found. All functions which end in `Def` take an additional default value, returning it if the section or key was not found. All functions which contain `Of` take a function of the type `Text -> Either String a`, which is used to attempt to decode or parse the extracted value. | |
57 | ||
58 | In total, there are three section-level parsers (`section`, `sectionMb`, and `sectionDef`) and eight field-level parsers (`field`, `fieldOf`, `fieldMb`, `fieldMbOf`, `fieldDef`, `fieldDefOf`, `fieldFlag`, `fieldFlagDef`). For the `_Of` functions, `config-ini` also provides several built-in parser functions which provide nice error messages on failure. |