hnormalise-0.4.7.0: src/HNormalise/Common/Parser.hs
{- hnormalise - a log normalisation library
-
- Copyright Andy Georges (c) 2017
-
- 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 Author name here nor the names of other
- 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 THE COPYRIGHT
- OWNER OR CONTRIBUTORS 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.
-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE OverloadedStrings #-}
module HNormalise.Common.Parser where
--------------------------------------------------------------------------------
import Control.Applicative ((<|>))
import Data.Attoparsec.Text
import Data.Char (isSpace)
import Data.Text (Text)
import qualified Data.Text as T
import qualified Net.IPv4.Text as IPv4
import qualified Net.IPv6.Text as IPv6
--------------------------------------------------------------------------------
import HNormalise.Common.Internal
--------------------------------------------------------------------------------
hostnameParser :: Parser Text
hostnameParser = sepBy' (takeWhile1 (inClass "a-z0-9-")) (char '.') >>= \hns -> return $ T.intercalate "." hns
{-# INLINE hostnameParser #-}
--------------------------------------------------------------------------------
hostnameOrIPParser :: Parser Host
hostnameOrIPParser = choice
[ IPv4.parser >>= \ip -> return $ IPv4 ip
, IPv6.parser >>= \ip -> return $ IPv6 ip
, hostnameParser >>= \h -> return $ Hostname h
]
{-# INLINE hostnameOrIPParser #-}
--------------------------------------------------------------------------------
keyParser k = string k *> char '='
{-# INLINE keyParser #-}
--------------------------------------------------------------------------------
kvParser :: Parser (Text, Text)
kvParser = do
key <- takeTill (== '=')
value <- char '=' *> takeTill isSpace
return (key, value)
{-# INLINE kvParser #-}
--------------------------------------------------------------------------------
kvTextParser :: Text -> Parser Text
kvTextParser key = kvTextDelimParser key " \n\t"
{-# INLINE kvTextParser #-}
--------------------------------------------------------------------------------
kvTextDelimParser :: Text -> String -> Parser Text
kvTextDelimParser key ds = keyParser key *> takeTill (`elem` ds)
{-# INLINE kvTextDelimParser #-}
--------------------------------------------------------------------------------
kvNumParser :: Integral a => Text -> Parser a
kvNumParser key = keyParser key *> decimal
{-# INLINE kvNumParser #-}
--------------------------------------------------------------------------------
kvSignedParser :: Integral a => Text -> Parser a
kvSignedParser key = keyParser key *> signed decimal
{-# INLINE kvSignedParser #-}
--------------------------------------------------------------------------------
kvYesNoParser :: Text -> Parser Bool
kvYesNoParser key = do
keyParser key
yn <- asciiCI "yes" <|> asciiCI "no"
return $ case T.toLower yn of
"yes" -> True
"no" -> False
{-# INLINE kvYesNoParser #-}
--------------------------------------------------------------------------------
kvHostOrIPParser :: Text -> Parser Host
kvHostOrIPParser key = keyParser key *> hostnameOrIPParser
{-# INLINE kvHostOrIPParser #-}
--------------------------------------------------------------------------------
maybeOption :: Parser a -> Parser (Maybe a)
maybeOption p = option Nothing (Just <$> p)
{-# INLINE maybeOption #-}