URI.hs 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. module Data.SMTP.Types.URI where
  2. import qualified Network.URI as N
  3. import Data.SMTP.Account
  4. import Data.List
  5. import qualified Data.Text as T
  6. import qualified Data.SMTP.Seal as Seal
  7. import qualified Data.Attoparsec.Text as A
  8. import Text.StringConvert
  9. newtype Path = Path [String] deriving (Eq, Ord, Read, Show)
  10. newtype Revision = Revision String deriving (Eq, Ord, Read, Show)
  11. data Parameter = Parameter String String deriving (Eq, Ord, Read, Show)
  12. data URI = URI {account :: Account, path :: Path, revision :: Maybe Revision, parameters :: [Parameter]}
  13. deriving (Eq, Ord, Read)
  14. fullPath :: URI -> String
  15. fullPath URI{path=Path p} = intercalate "/" $ map uriEncode p
  16. fullURI :: URI -> String
  17. fullURI u@(URI{account=a, revision=r, parameters=pp}) =
  18. concat $ ["FCMTP://", s . fullAccount $ a, fullPath u] ++ (
  19. case r of
  20. Nothing -> []
  21. Just (Revision r') -> [":", r']
  22. ) ++ (
  23. if null pp
  24. then []
  25. else ["?", intercalate "&" $ map formatParameter pp]
  26. )
  27. where
  28. formatParameter (Parameter nm vl) = concat [uriEncode nm, "=", uriEncode vl]
  29. uriEncode :: String -> String
  30. uriEncode = N.escapeURIString N.isUnescapedInURIComponent
  31. instance Show URI where
  32. show = fullURI
  33. getParameter :: String -> URI -> Maybe String
  34. getParameter p u = case map (\(Parameter _ vl) -> vl) .
  35. filter (\(Parameter nm _) -> nm == p) $
  36. parameters u of
  37. [] -> Nothing
  38. (v:_) -> Just v
  39. getSeal :: URI -> Maybe Seal.Seal
  40. getSeal u = do
  41. se <- getParameter "seal" u
  42. eitherToMaybe . A.parseOnly Seal.parseURISeal . T.pack $ se
  43. where
  44. eitherToMaybe (Left _) = Nothing
  45. eitherToMaybe (Right v) = Just v