URI.hs 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  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 Text.StringConvert
  6. newtype Path = Path [String] deriving (Eq, Ord, Read, Show)
  7. data Revision = NoRevision | Revision String deriving (Eq, Ord, Read, Show)
  8. data Parameter = Parameter String String deriving (Eq, Ord, Read, Show)
  9. data URI = URI {account :: Account, path :: Path, revision :: Revision, parameters :: [Parameter]}
  10. deriving (Eq, Ord)
  11. {- |
  12. Returns the entire path of the URI.
  13. -}
  14. fullPath :: URI -> String
  15. fullPath URI{path=Path p} = intercalate "/" $ map uriEncode p
  16. {- |
  17. Returns the entire path of the URI, except for the leading slash (/).
  18. -}
  19. relativePath :: URI -> String
  20. relativePath URI{path=Path p} = intercalate "/" . map uriEncode $ drop 1 p
  21. -- | Entire textual representation of the URI
  22. fullURI :: URI -> String
  23. fullURI u@(URI{account=a, revision=r, parameters=pp}) =
  24. concat $ ["FCMTP://", s . fullAccount $ a, fullPath u] ++ (
  25. case r of
  26. NoRevision -> []
  27. Revision r' -> [":", r']
  28. ) ++ (
  29. if null pp
  30. then []
  31. else ["?", intercalate "&" $ map formatParameter pp]
  32. )
  33. where
  34. formatParameter (Parameter nm vl) = concat [uriEncode nm, "=", uriEncode vl]
  35. uriEncode :: String -> String
  36. uriEncode = N.escapeURIString N.isUnescapedInURIComponent
  37. instance Show URI where
  38. show = fullURI
  39. -- | Retrieves a parameter from the URI by key name
  40. getParameter :: String -> URI -> Maybe String
  41. getParameter p u = case map (\(Parameter _ vl) -> vl) .
  42. filter (\(Parameter nm _) -> nm == p) $
  43. parameters u of
  44. [] -> Nothing
  45. (v:_) -> Just v
  46. -- | Return revision string or a default value
  47. fromRevision :: String -> Revision -> String
  48. fromRevision d NoRevision = d
  49. fromRevision _ (Revision r) = r
  50. -- | Appends a new segment at the end of the path
  51. appendPath :: Path -> String -> Path
  52. appendPath (Path pp) e = Path $ pp ++ [e]