Safe Haskell | None |
---|---|
Language | Haskell2010 |
Introduction
This module is intended for parsing connection strings in a manner that is consistent with .NET's DbConnectionStringBuilder class.
The syntax of a connection string appears quite simple at first glance, and consists of a list of key-value pairs separated by semicolons:
>>>
toList <$> parse "key=value; key2 = value2"
Right [("key","value"),("key2","value2")]
However, the format can be more complicated than expected.
Examples
A value may be single-quoted (single quotes can be escaped inside a single-quoted string by doubling them):
>>>
toList <$> parse "squote='value with '' quotes'"
Right [("squote","value with ' quotes")]
Or double-quoted (double quotes can also be escaped inside a double-quoted string by doubling them):
>>>
let (Right quoted) = parse "dquote=\"value with \"\" quotes\""
>>>
toList quoted
[("dquote","value with \" quotes")]>>>
quoted
"dquote='value with \" quotes'"
- - ^ TODO: Note that this is for exact compatibility
Quotes of both kinds may be present in keys:
>>>
toList <$> parse "'quote\"=value"
Right [("'quote\"","value")]
Whitespace is ignored everywhere except in quoted strings and inside keys or unquoted values:
>>>
toList <$> parse "; a key = v v\t\n;\t key 2 = \"v v\"\n;\t key 3 = 'v v'; "
Right [("a key","v v"),("key 2","v v"),("key 3","v v")]
Equals signs may be escaped in keys by doubling them:
>>>
toList <$> parse "1==2=false"
Right [("1=2","false")]
Keys are case-insensitive (and converted to lower-case on output):
>>>
toList <$> parse "BIG=small"
Right [("big","small")]
Later values override earlier ones:
>>>
toList <$> parse "key=value;key=value2"
Right [("key","value2")]
Assigning a key no value will remove it:
>>>
toList <$> parse "key=value;key="
Right []
However, you can assign an empty value by giving it a quoted value:
>>>
toList <$> parse "key=value;key=''"
Right [("key","")]
- - TODO ^ there appears to be a bug here in .NET
On the other hand, not providing a key doesn't make any sense:
>>>
parse "key=value;=value"
Left "1:11:\nunexpected '='\nexpecting ';', end of input, or white space\n"
>>>
parse "=value"
Left "1:1:\nunexpected '='\nexpecting ';', end of input, or white space\n"
Another quirk is that keys can contain semicolons:
>>>
toList <$> parse "key=value;key2;extended=value"
Right [("key","value"),("key2;extended","value")]
This module implements all of these quirks for you!
- data ConnectionString s
- toList :: ConnectionString s -> [(s, s)]
- keys :: ConnectionString s -> [s]
- values :: ConnectionString s -> [s]
- (!) :: (FoldCase s, Ord s, IsList s, Item s ~ Char) => ConnectionString s -> s -> Maybe s
- toString :: forall s. (IsString s, IsList s, Item s ~ Char) => ConnectionString s -> s
- parse :: Parseable s => s -> Either String (ConnectionString s)
- type Parseable s = (Stream s, Token s ~ Char, IsString s, Ord s, FoldCase s)
- parser :: Parseable s => Parsec Void s [(Key s, Maybe s)]
Documentation
data ConnectionString s Source #
A connection string is a set of keys that map to values.
toList :: ConnectionString s -> [(s, s)] Source #
keys :: ConnectionString s -> [s] Source #
values :: ConnectionString s -> [s] Source #
(!) :: (FoldCase s, Ord s, IsList s, Item s ~ Char) => ConnectionString s -> s -> Maybe s Source #
Tries to find the given key in the connection string,
and returns either the value or Nothing
.
toString :: forall s. (IsString s, IsList s, Item s ~ Char) => ConnectionString s -> s Source #
Render a ConnectionString
as the string type.
parse :: Parseable s => s -> Either String (ConnectionString s) Source #
Parses a connection string, or fails with an error.
You can parse String
inputs:
>>>
parse ("key=value;key2=value2")
Right "key=value;key2=value2"
Or you can parse Text
inputs:
>>>
:set -XOverloadedStrings
>>>
import Data.Text
>>>
parse ("key=value;key2=value2" :: Text)
Right "key=value;key2=value2"
In either case, parse
will produce a ConnectionString
that
has values of the same type as the input.