Address.hs 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. {-# LANGUAGE OverloadedStrings #-}
  2. module Data.SMTP.Parser.Address (
  3. parseAddress,
  4. parseMetadataAddress,
  5. renderMetadataAddress
  6. ) where
  7. import Data.Attoparsec.ByteString.Char8
  8. import qualified Data.SMTP.URI as URI
  9. import Data.SMTP.Account
  10. import Data.SMTP.Types.Address
  11. import qualified Data.SMTP.Seal as Seal
  12. import Data.Attoparsec.ByteString.Char8.Extras
  13. import Data.ByteString (ByteString)
  14. import qualified Data.ByteString as BS
  15. import qualified Data.ByteString.Base64 as B64
  16. import Control.Applicative ((<|>))
  17. parseAddress :: Parser Address
  18. parseAddress = ((\x -> Address (Just x) (URI.account x) Nothing) <$> URI.parseURI) <|>
  19. ((\x -> Address Nothing x Nothing) <$> parseAccount)
  20. renderMetadataAddress :: Address -> ByteString
  21. renderMetadataAddress add@(Address _ _ s) =
  22. BS.intercalate "; " $ asToURI add : case s of
  23. Nothing -> []
  24. Just (Seal.Seal cp code nonce) -> [
  25. BS.append "CP=" $ B64.encode cp
  26. ] ++ nc nonce ++ [
  27. BS.append "SEAL=" $ B64.encode code
  28. ]
  29. where
  30. nc nonce = case nonce of
  31. Nothing -> []
  32. Just n -> [BS.append "Nonce=" $ B64.encode n]
  33. parseMetadataAddress :: Parser Address
  34. parseMetadataAddress = do
  35. a <- parseAddress
  36. (cp, nonce, code) <- parserFold addrParams (Nothing, Nothing, Nothing)
  37. let r = do
  38. cp' <- cp
  39. code' <- code
  40. return a{seal=Just $ Seal.Seal cp' code' nonce}
  41. case r of
  42. Nothing -> return a
  43. Just r' -> return r'
  44. where
  45. addrParams = choice [
  46. do
  47. c <- cmdSep "CP" decodeBase64
  48. return $ \(_, n, s) -> (Just c, n, s),
  49. do
  50. n <- cmdSep "Nonce" decodeBase64
  51. return $ \(c, _, s) -> (c, Just n, s),
  52. do
  53. s <- cmdSep "Seal" decodeBase64
  54. return $ \(c, n, _) -> (c, n, Just s)
  55. ]
  56. cmdSep c p = do
  57. skipWhile isCHorizontalSpace
  58. stringCI c
  59. skipWhile isCHorizontalSpace
  60. char ':'
  61. skipWhile isCHorizontalSpace
  62. p