Address.hs 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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. import qualified Text.StringConvert as SC
  18. parseAddress :: Parser Address
  19. parseAddress = ((\x -> URIAdd x Nothing) <$> URI.parseURI) <|>
  20. ((\x -> AccountAdd x Nothing) <$> parseAccount)
  21. renderMetadataAddress :: Address -> ByteString
  22. renderMetadataAddress add =
  23. BS.intercalate "; " $ (SC.s . asToURI $ add) : case seal add of
  24. Nothing -> []
  25. Just (Seal.Seal cp code nonce) -> [
  26. BS.append "CP=" $ B64.encode cp
  27. ] ++ nc nonce ++ [
  28. BS.append "SEAL=" $ B64.encode code
  29. ]
  30. where
  31. nc nonce = case nonce of
  32. Nothing -> []
  33. Just n -> [BS.append "Nonce=" $ B64.encode n]
  34. parseMetadataAddress :: Parser Address
  35. parseMetadataAddress = do
  36. a <- parseAddress
  37. (cp, nonce, code) <- parserFold addrParams (Nothing, Nothing, Nothing)
  38. let r = do
  39. cp' <- cp
  40. code' <- code
  41. return . setSeal a . Just $ Seal.Seal cp' code' nonce
  42. case r of
  43. Nothing -> return a
  44. Just r' -> return r'
  45. where
  46. addrParams = choice [
  47. do
  48. c <- cmdSep "CP" decodeBase64
  49. return $ \(_, n, s) -> (Just c, n, s),
  50. do
  51. n <- cmdSep "Nonce" decodeBase64
  52. return $ \(c, _, s) -> (c, Just n, s),
  53. do
  54. s <- cmdSep "Seal" decodeBase64
  55. return $ \(c, n, _) -> (c, n, Just s)
  56. ]
  57. cmdSep c p = do
  58. skipWhile isCHorizontalSpace
  59. stringCI c
  60. skipWhile isCHorizontalSpace
  61. char ':'
  62. skipWhile isCHorizontalSpace
  63. p