emailparse-0.2.0.6: src/Network/Mail/Parse/Utils.hs
module Network.Mail.Parse.Utils where
import Network.Mail.Parse.Types
import Data.Attoparsec.ByteString
import qualified Data.Attoparsec.ByteString as AP
import qualified Data.ByteString.Char8 as BS
import Data.Word8
import Data.List
import Data.Text (Text)
import qualified Data.Text as T
import Data.Either.Utils (maybeToEither)
-- |If the previous character was a carriage return and the current
-- is a line feed, stop parsing
hadCRLF :: Word8 -> Word8 -> Maybe Word8
hadCRLF prev current =
if prev == _cr && current == _lf
then Nothing
else Just current
-- |Consumes a line until CRLF is hit
consumeTillEndLine :: Parser BS.ByteString
consumeTillEndLine = scan 0 hadCRLF <* satisfy (== _lf)
-- |Can a given character be regarded as a whitespace?
isWhitespace :: Word8 -> Bool
isWhitespace x = x == 9 || x == 32
-- |If the next line is a part of a previous header, parse it.
-- Fail otherwise
isConsequentHeaderLine :: Parser BS.ByteString
isConsequentHeaderLine = satisfy isWhitespace *>
AP.takeWhile isWhitespace *>
consumeTillEndLine
-- |Remove a MIME header comment and return a header without the comment
commentRemover :: Text -> Text
commentRemover contents = T.strip withoutComment
where splitAtComment = T.split (\c -> c == '(' || c == ')') contents
withoutComment = if length splitAtComment > 1
then T.append (head splitAtComment) (last splitAtComment)
else head splitAtComment
-- |Given a header name, it will try to locate it in
-- a list of headers, fail if it's not there
findHeader :: Text -> [Header] -> Either ErrorMessage Header
findHeader hdr headers = maybeToEither notFound header
where notFound = T.concat ["Cound not find header '", T.pack . show $ hdr, "'"]
eigenHeader = T.toLower hdr
header = find (\x -> T.toLower (headerName x) == eigenHeader) headers
eitherToMaybe :: Either a b -> Maybe b
eitherToMaybe (Right a) = Just a
eitherToMaybe (Left _) = Nothing