module Amazonka.Data.Path
(
Path (..),
RawPath,
EscapedPath,
ToPath (..),
rawPath,
escapePath,
collapsePath,
)
where
import Amazonka.Data.ByteString
import Amazonka.Data.Text
import Amazonka.Prelude
import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as BS8
import qualified Network.HTTP.Types.URI as URI
class ToPath a where
toPath :: a -> ByteString
instance ToPath ByteString where
toPath :: ByteString -> ByteString
toPath = ByteString -> ByteString
forall a. a -> a
id
instance ToPath Text where
toPath :: Text -> ByteString
toPath = Text -> ByteString
forall a. ToByteString a => a -> ByteString
toBS
rawPath :: ToPath a => a -> Path 'NoEncoding
rawPath :: a -> Path 'NoEncoding
rawPath = [ByteString] -> Path 'NoEncoding
Raw ([ByteString] -> Path 'NoEncoding)
-> (a -> [ByteString]) -> a -> Path 'NoEncoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> [ByteString]
strip ([ByteString] -> [ByteString])
-> (a -> [ByteString]) -> a -> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ByteString -> [ByteString]
BS8.split Char
sep (ByteString -> [ByteString])
-> (a -> ByteString) -> a -> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> ByteString
forall a. ToPath a => a -> ByteString
toPath
where
strip :: [ByteString] -> [ByteString]
strip (ByteString
x : [ByteString]
xs)
| ByteString -> Bool
BS.null ByteString
x = [ByteString]
xs
strip [ByteString]
xs = [ByteString]
xs
data Encoding = NoEncoding | Percent
deriving stock (Encoding -> Encoding -> Bool
(Encoding -> Encoding -> Bool)
-> (Encoding -> Encoding -> Bool) -> Eq Encoding
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Encoding -> Encoding -> Bool
$c/= :: Encoding -> Encoding -> Bool
== :: Encoding -> Encoding -> Bool
$c== :: Encoding -> Encoding -> Bool
Eq, Int -> Encoding -> ShowS
[Encoding] -> ShowS
Encoding -> String
(Int -> Encoding -> ShowS)
-> (Encoding -> String) -> ([Encoding] -> ShowS) -> Show Encoding
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Encoding] -> ShowS
$cshowList :: [Encoding] -> ShowS
show :: Encoding -> String
$cshow :: Encoding -> String
showsPrec :: Int -> Encoding -> ShowS
$cshowsPrec :: Int -> Encoding -> ShowS
Show)
data Path :: Encoding -> * where
Raw :: [ByteString] -> Path 'NoEncoding
Encoded :: [ByteString] -> Path 'Percent
deriving stock instance Show (Path a)
deriving stock instance Eq (Path a)
type RawPath = Path 'NoEncoding
type EscapedPath = Path 'Percent
instance Semigroup RawPath where
Raw [ByteString]
xs <> :: Path 'NoEncoding -> Path 'NoEncoding -> Path 'NoEncoding
<> Raw [ByteString]
ys = [ByteString] -> Path 'NoEncoding
Raw ([ByteString]
xs [ByteString] -> [ByteString] -> [ByteString]
forall a. [a] -> [a] -> [a]
++ [ByteString]
ys)
instance Monoid RawPath where
mempty :: Path 'NoEncoding
mempty = [ByteString] -> Path 'NoEncoding
Raw []
mappend :: Path 'NoEncoding -> Path 'NoEncoding -> Path 'NoEncoding
mappend = Path 'NoEncoding -> Path 'NoEncoding -> Path 'NoEncoding
forall a. Semigroup a => a -> a -> a
(<>)
instance ToByteString EscapedPath where
toBS :: EscapedPath -> ByteString
toBS (Encoded []) = ByteString
slash
toBS (Encoded [ByteString]
xs) = ByteString
slash ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString -> [ByteString] -> ByteString
BS8.intercalate ByteString
slash [ByteString]
xs
escapePath :: Path a -> EscapedPath
escapePath :: Path a -> EscapedPath
escapePath (Raw [ByteString]
xs) = [ByteString] -> EscapedPath
Encoded ((ByteString -> ByteString) -> [ByteString] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map (Bool -> ByteString -> ByteString
URI.urlEncode Bool
True) [ByteString]
xs)
escapePath (Encoded [ByteString]
xs) = [ByteString] -> EscapedPath
Encoded [ByteString]
xs
collapsePath :: Path a -> Path a
collapsePath :: Path a -> Path a
collapsePath = \case
Raw [ByteString]
xs -> [ByteString] -> Path 'NoEncoding
Raw ([ByteString] -> [ByteString]
go [ByteString]
xs)
Encoded [ByteString]
xs -> [ByteString] -> EscapedPath
Encoded ([ByteString] -> [ByteString]
go [ByteString]
xs)
where
go :: [ByteString] -> [ByteString]
go = [ByteString] -> [ByteString]
forall a. [a] -> [a]
reverse ([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> [ByteString]
f ([ByteString] -> [ByteString])
-> ([ByteString] -> [ByteString]) -> [ByteString] -> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> [ByteString]
forall a. [a] -> [a]
reverse
f :: [ByteString] -> [ByteString]
f :: [ByteString] -> [ByteString]
f [] = []
f (ByteString
x : [ByteString]
xs)
| ByteString
x ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
dot = [ByteString] -> [ByteString]
f [ByteString]
xs
| ByteString
x ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
dots = Int -> [ByteString] -> [ByteString]
forall a. Int -> [a] -> [a]
drop Int
1 ([ByteString] -> [ByteString]
f [ByteString]
xs)
| Bool
otherwise = ByteString
x ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: [ByteString] -> [ByteString]
f [ByteString]
xs
dot :: ByteString
dot = ByteString
"."
dots :: ByteString
dots = ByteString
".."
slash :: ByteString
slash :: ByteString
slash = Char -> ByteString
BS8.singleton Char
sep
sep :: Char
sep :: Char
sep = Char
'/'