{-# LANGUAGE CPP #-}
module Web.Scotty.Util
( lazyTextToStrictByteString
, strictByteStringToLazyText
, setContent
, setHeaderWith
, setStatus
, mkResponse
, replace
, add
, addIfNotPresent
, socketDescription
) where
import Network.Socket (SockAddr(..), Socket, getSocketName, socketPort)
import Network.Wai
import Network.HTTP.Types
import qualified Data.ByteString as B
import qualified Data.Text.Lazy as T
import qualified Data.Text.Encoding as ES
import qualified Data.Text.Encoding.Error as ES
import Web.Scotty.Internal.Types
lazyTextToStrictByteString :: T.Text -> B.ByteString
lazyTextToStrictByteString :: Text -> ByteString
lazyTextToStrictByteString = Text -> ByteString
ES.encodeUtf8 (Text -> ByteString) -> (Text -> Text) -> Text -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.toStrict
strictByteStringToLazyText :: B.ByteString -> T.Text
strictByteStringToLazyText :: ByteString -> Text
strictByteStringToLazyText = Text -> Text
T.fromStrict (Text -> Text) -> (ByteString -> Text) -> ByteString -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OnDecodeError -> ByteString -> Text
ES.decodeUtf8With OnDecodeError
ES.lenientDecode
setContent :: Content -> ScottyResponse -> ScottyResponse
setContent :: Content -> ScottyResponse -> ScottyResponse
setContent c :: Content
c sr :: ScottyResponse
sr = ScottyResponse
sr { srContent :: Content
srContent = Content
c }
setHeaderWith :: ([(HeaderName, B.ByteString)] -> [(HeaderName, B.ByteString)]) -> ScottyResponse -> ScottyResponse
f :: [(HeaderName, ByteString)] -> [(HeaderName, ByteString)]
f sr :: ScottyResponse
sr = ScottyResponse
sr { srHeaders :: [(HeaderName, ByteString)]
srHeaders = [(HeaderName, ByteString)] -> [(HeaderName, ByteString)]
f (ScottyResponse -> [(HeaderName, ByteString)]
srHeaders ScottyResponse
sr) }
setStatus :: Status -> ScottyResponse -> ScottyResponse
setStatus :: Status -> ScottyResponse -> ScottyResponse
setStatus s :: Status
s sr :: ScottyResponse
sr = ScottyResponse
sr { srStatus :: Status
srStatus = Status
s }
mkResponse :: ScottyResponse -> Response
mkResponse :: ScottyResponse -> Response
mkResponse sr :: ScottyResponse
sr = case ScottyResponse -> Content
srContent ScottyResponse
sr of
ContentBuilder b :: Builder
b -> Status -> [(HeaderName, ByteString)] -> Builder -> Response
responseBuilder Status
s [(HeaderName, ByteString)]
h Builder
b
ContentFile f :: FilePath
f -> Status
-> [(HeaderName, ByteString)]
-> FilePath
-> Maybe FilePart
-> Response
responseFile Status
s [(HeaderName, ByteString)]
h FilePath
f Maybe FilePart
forall a. Maybe a
Nothing
ContentStream str :: StreamingBody
str -> Status -> [(HeaderName, ByteString)] -> StreamingBody -> Response
responseStream Status
s [(HeaderName, ByteString)]
h StreamingBody
str
where s :: Status
s = ScottyResponse -> Status
srStatus ScottyResponse
sr
h :: [(HeaderName, ByteString)]
h = ScottyResponse -> [(HeaderName, ByteString)]
srHeaders ScottyResponse
sr
replace :: Eq a => a -> b -> [(a,b)] -> [(a,b)]
replace :: a -> b -> [(a, b)] -> [(a, b)]
replace k :: a
k v :: b
v = a -> b -> [(a, b)] -> [(a, b)]
forall a b. a -> b -> [(a, b)] -> [(a, b)]
add a
k b
v ([(a, b)] -> [(a, b)])
-> ([(a, b)] -> [(a, b)]) -> [(a, b)] -> [(a, b)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((a, b) -> Bool) -> [(a, b)] -> [(a, b)]
forall a. (a -> Bool) -> [a] -> [a]
filter ((a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= a
k) (a -> Bool) -> ((a, b) -> a) -> (a, b) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a, b) -> a
forall a b. (a, b) -> a
fst)
add :: a -> b -> [(a,b)] -> [(a,b)]
add :: a -> b -> [(a, b)] -> [(a, b)]
add k :: a
k v :: b
v m :: [(a, b)]
m = (a
k,b
v)(a, b) -> [(a, b)] -> [(a, b)]
forall a. a -> [a] -> [a]
:[(a, b)]
m
addIfNotPresent :: Eq a => a -> b -> [(a,b)] -> [(a,b)]
addIfNotPresent :: a -> b -> [(a, b)] -> [(a, b)]
addIfNotPresent k :: a
k v :: b
v = [(a, b)] -> [(a, b)]
go
where go :: [(a, b)] -> [(a, b)]
go [] = [(a
k,b
v)]
go l :: [(a, b)]
l@((x :: a
x,y :: b
y):r :: [(a, b)]
r)
| a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
k = [(a, b)]
l
| Bool
otherwise = (a
x,b
y) (a, b) -> [(a, b)] -> [(a, b)]
forall a. a -> [a] -> [a]
: [(a, b)] -> [(a, b)]
go [(a, b)]
r
socketDescription :: Socket -> IO String
socketDescription :: Socket -> IO FilePath
socketDescription sock :: Socket
sock = do
SockAddr
sockName <- Socket -> IO SockAddr
getSocketName Socket
sock
case SockAddr
sockName of
SockAddrUnix u :: FilePath
u -> FilePath -> IO FilePath
forall (m :: * -> *) a. Monad m => a -> m a
return (FilePath -> IO FilePath) -> FilePath -> IO FilePath
forall a b. (a -> b) -> a -> b
$ "unix socket " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
u
_ -> (PortNumber -> FilePath) -> IO PortNumber -> IO FilePath
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\port :: PortNumber
port -> "port " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ PortNumber -> FilePath
forall a. Show a => a -> FilePath
show PortNumber
port) (IO PortNumber -> IO FilePath) -> IO PortNumber -> IO FilePath
forall a b. (a -> b) -> a -> b
$ Socket -> IO PortNumber
socketPort Socket
sock