module PostgREST.Request.Preferences
( Preferences(..)
, PreferCount(..)
, PreferParameters(..)
, PreferRepresentation(..)
, PreferResolution(..)
, PreferTransaction(..)
, fromHeaders
, ToAppliedHeader(..)
) where
import qualified Data.ByteString.Char8 as BS
import qualified Data.Map as Map
import qualified Network.HTTP.Types.Header as HTTP
import Protolude
data Preferences
= Preferences
{ Preferences -> Maybe PreferResolution
preferResolution :: Maybe PreferResolution
, Preferences -> Maybe PreferRepresentation
preferRepresentation :: Maybe PreferRepresentation
, Preferences -> Maybe PreferParameters
preferParameters :: Maybe PreferParameters
, Preferences -> Maybe PreferCount
preferCount :: Maybe PreferCount
, Preferences -> Maybe PreferTransaction
preferTransaction :: Maybe PreferTransaction
}
fromHeaders :: [HTTP.Header] -> Preferences
[Header]
headers =
Preferences :: Maybe PreferResolution
-> Maybe PreferRepresentation
-> Maybe PreferParameters
-> Maybe PreferCount
-> Maybe PreferTransaction
-> Preferences
Preferences
{ preferResolution :: Maybe PreferResolution
preferResolution = [PreferResolution] -> Maybe PreferResolution
forall a. ToHeaderValue a => [a] -> Maybe a
parsePrefs [PreferResolution
MergeDuplicates, PreferResolution
IgnoreDuplicates]
, preferRepresentation :: Maybe PreferRepresentation
preferRepresentation = [PreferRepresentation] -> Maybe PreferRepresentation
forall a. ToHeaderValue a => [a] -> Maybe a
parsePrefs [PreferRepresentation
Full, PreferRepresentation
None, PreferRepresentation
HeadersOnly]
, preferParameters :: Maybe PreferParameters
preferParameters = [PreferParameters] -> Maybe PreferParameters
forall a. ToHeaderValue a => [a] -> Maybe a
parsePrefs [PreferParameters
SingleObject, PreferParameters
MultipleObjects]
, preferCount :: Maybe PreferCount
preferCount = [PreferCount] -> Maybe PreferCount
forall a. ToHeaderValue a => [a] -> Maybe a
parsePrefs [PreferCount
ExactCount, PreferCount
PlannedCount, PreferCount
EstimatedCount]
, preferTransaction :: Maybe PreferTransaction
preferTransaction = [PreferTransaction] -> Maybe PreferTransaction
forall a. ToHeaderValue a => [a] -> Maybe a
parsePrefs [PreferTransaction
Commit, PreferTransaction
Rollback]
}
where
prefHeaders :: [Header]
prefHeaders = (Header -> Bool) -> [Header] -> [Header]
forall a. (a -> Bool) -> [a] -> [a]
filter (HeaderName -> HeaderName -> Bool
forall a. Eq a => a -> a -> Bool
(==) HeaderName
HTTP.hPrefer (HeaderName -> Bool) -> (Header -> HeaderName) -> Header -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Header -> HeaderName
forall a b. (a, b) -> a
fst) [Header]
headers
prefs :: [ByteString]
prefs = (ByteString -> ByteString) -> [ByteString] -> [ByteString]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteString -> ByteString
BS.strip ([ByteString] -> [ByteString])
-> ([Header] -> [ByteString]) -> [Header] -> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Header -> [ByteString]) -> [Header] -> [ByteString]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Char -> ByteString -> [ByteString]
BS.split Char
',' (ByteString -> [ByteString])
-> (Header -> ByteString) -> Header -> [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Header -> ByteString
forall a b. (a, b) -> b
snd) ([Header] -> [ByteString]) -> [Header] -> [ByteString]
forall a b. (a -> b) -> a -> b
$ [Header]
prefHeaders
parsePrefs :: ToHeaderValue a => [a] -> Maybe a
parsePrefs :: [a] -> Maybe a
parsePrefs [a]
vals =
[a] -> Maybe a
forall (f :: * -> *) a. Foldable f => f a -> Maybe a
head ([a] -> Maybe a) -> [a] -> Maybe a
forall a b. (a -> b) -> a -> b
$ (ByteString -> Maybe a) -> [ByteString] -> [a]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe ((ByteString -> Map ByteString a -> Maybe a)
-> Map ByteString a -> ByteString -> Maybe a
forall a b c. (a -> b -> c) -> b -> a -> c
flip ByteString -> Map ByteString a -> Maybe a
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (Map ByteString a -> ByteString -> Maybe a)
-> Map ByteString a -> ByteString -> Maybe a
forall a b. (a -> b) -> a -> b
$ [a] -> Map ByteString a
forall a. ToHeaderValue a => [a] -> Map ByteString a
prefMap [a]
vals) [ByteString]
prefs
prefMap :: ToHeaderValue a => [a] -> Map.Map ByteString a
prefMap :: [a] -> Map ByteString a
prefMap = [(ByteString, a)] -> Map ByteString a
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([(ByteString, a)] -> Map ByteString a)
-> ([a] -> [(ByteString, a)]) -> [a] -> Map ByteString a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> (ByteString, a)) -> [a] -> [(ByteString, a)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\a
pref -> (a -> ByteString
forall a. ToHeaderValue a => a -> ByteString
toHeaderValue a
pref, a
pref))
class a where
:: a -> ByteString
class ToHeaderValue a => a where
:: a -> HTTP.Header
toAppliedHeader a
x = (HeaderName
HTTP.hPreferenceApplied, a -> ByteString
forall a. ToHeaderValue a => a -> ByteString
toHeaderValue a
x)
data PreferResolution
= MergeDuplicates
| IgnoreDuplicates
instance ToHeaderValue PreferResolution where
toHeaderValue :: PreferResolution -> ByteString
toHeaderValue PreferResolution
MergeDuplicates = ByteString
"resolution=merge-duplicates"
toHeaderValue PreferResolution
IgnoreDuplicates = ByteString
"resolution=ignore-duplicates"
instance ToAppliedHeader PreferResolution
data PreferRepresentation
= Full
|
| None
deriving PreferRepresentation -> PreferRepresentation -> Bool
(PreferRepresentation -> PreferRepresentation -> Bool)
-> (PreferRepresentation -> PreferRepresentation -> Bool)
-> Eq PreferRepresentation
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PreferRepresentation -> PreferRepresentation -> Bool
$c/= :: PreferRepresentation -> PreferRepresentation -> Bool
== :: PreferRepresentation -> PreferRepresentation -> Bool
$c== :: PreferRepresentation -> PreferRepresentation -> Bool
Eq
instance ToHeaderValue PreferRepresentation where
toHeaderValue :: PreferRepresentation -> ByteString
toHeaderValue PreferRepresentation
Full = ByteString
"return=representation"
toHeaderValue PreferRepresentation
None = ByteString
"return=minimal"
toHeaderValue PreferRepresentation
HeadersOnly = ByteString
"return=headers-only"
data PreferParameters
= SingleObject
| MultipleObjects
deriving PreferParameters -> PreferParameters -> Bool
(PreferParameters -> PreferParameters -> Bool)
-> (PreferParameters -> PreferParameters -> Bool)
-> Eq PreferParameters
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PreferParameters -> PreferParameters -> Bool
$c/= :: PreferParameters -> PreferParameters -> Bool
== :: PreferParameters -> PreferParameters -> Bool
$c== :: PreferParameters -> PreferParameters -> Bool
Eq
instance ToHeaderValue PreferParameters where
toHeaderValue :: PreferParameters -> ByteString
toHeaderValue PreferParameters
SingleObject = ByteString
"params=single-object"
toHeaderValue PreferParameters
MultipleObjects = ByteString
"params=multiple-objects"
data PreferCount
= ExactCount
| PlannedCount
| EstimatedCount
deriving PreferCount -> PreferCount -> Bool
(PreferCount -> PreferCount -> Bool)
-> (PreferCount -> PreferCount -> Bool) -> Eq PreferCount
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PreferCount -> PreferCount -> Bool
$c/= :: PreferCount -> PreferCount -> Bool
== :: PreferCount -> PreferCount -> Bool
$c== :: PreferCount -> PreferCount -> Bool
Eq
instance ToHeaderValue PreferCount where
toHeaderValue :: PreferCount -> ByteString
toHeaderValue PreferCount
ExactCount = ByteString
"count=exact"
toHeaderValue PreferCount
PlannedCount = ByteString
"count=planned"
toHeaderValue PreferCount
EstimatedCount = ByteString
"count=estimated"
data PreferTransaction
= Commit
| Rollback
deriving PreferTransaction -> PreferTransaction -> Bool
(PreferTransaction -> PreferTransaction -> Bool)
-> (PreferTransaction -> PreferTransaction -> Bool)
-> Eq PreferTransaction
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PreferTransaction -> PreferTransaction -> Bool
$c/= :: PreferTransaction -> PreferTransaction -> Bool
== :: PreferTransaction -> PreferTransaction -> Bool
$c== :: PreferTransaction -> PreferTransaction -> Bool
Eq
instance ToHeaderValue PreferTransaction where
toHeaderValue :: PreferTransaction -> ByteString
toHeaderValue PreferTransaction
Commit = ByteString
"tx=commit"
toHeaderValue PreferTransaction
Rollback = ByteString
"tx=rollback"
instance ToAppliedHeader PreferTransaction