module Database.Couch.Response where
import Control.Monad ((>>=))
import Data.Aeson (FromJSON, Value (Object), fromJSON)
import qualified Data.Aeson as Aeson (Result (Error, Success))
import Data.Bool (Bool)
import Data.Either (Either (Left, Right))
import Data.Function (($), (.))
import Data.Functor (fmap)
import Data.HashMap.Strict (lookup)
import Data.Maybe (Maybe (Just, Nothing), catMaybes, maybe)
import Data.String (fromString)
import Data.Text (Text, intercalate, splitAt)
import Data.Text.Encoding (encodeUtf8)
import Data.UUID (UUID, fromASCIIBytes)
import Database.Couch.Types (Error (NotFound, ParseFail), Result)
asAnything :: FromJSON a => Result Value -> Result a
asAnything v =
case v of
Left x -> Left x
Right (a, b) -> case fromJSON a of
Aeson.Error e -> (Left . ParseFail . fromString) e
Aeson.Success s -> Right (s, b)
asBool :: Result Value -> Result Bool
asBool = getKey "ok"
asUUID :: Result Value -> Result [UUID]
asUUID v =
case v of
Left x -> Left x
Right (Object o, b) -> maybe (Left (ParseFail "Couldn't convert to UUID type"))
(Right . (,b) . catMaybes . reformat) $ lookup "uuids" o
_ -> Left NotFound
where
reformat i =
case fromJSON i of
Aeson.Error _ -> []
Aeson.Success a -> fmap (fromASCIIBytes . encodeUtf8 . reformatUuid) a
reformatUuid s =
let (first, second') = splitAt 8 s
(second, third') = splitAt 4 second'
(third, fourth') = splitAt 4 third'
(fourth, fifth) = splitAt 4 fourth'
in intercalate "-" [first, second, third, fourth, fifth]
getKey :: FromJSON a => Text -> Result Value -> Result a
getKey k v =
case v of
Left x -> Left x
Right (Object o, b) -> maybe (Left NotFound) (Right . (, b)) $ lookup k o >>= reformat
_ -> Left NotFound
where
reformat i =
case fromJSON i of
Aeson.Error _ -> Nothing
Aeson.Success a -> Just a