{-# LANGUAGE LambdaCase #-} {-# LANGUAGE FlexibleInstances #-} module Database.PostgreSQL.Opium.FromField (FromField (..)) where import Data.Attoparsec.Text ( Parser , decimal , parseOnly , signed ) import Data.Text (Text) import Database.PostgreSQL.LibPQ (Oid) import qualified Data.Text as Text import qualified Database.PostgreSQL.Opium.Oid as Oid (\/) :: (a -> Bool) -> (a -> Bool) -> a -> Bool p \/ q = \x -> p x || q x eitherToMaybe :: Either b a -> Maybe a eitherToMaybe = \case Left _ -> Nothing Right x -> Just x fromParser :: (Oid -> Bool) -> Parser a -> Oid -> Text -> Maybe a fromParser validOid parser oid value | validOid oid = eitherToMaybe $ parseOnly parser value | otherwise = Nothing class FromField a where fromField :: Oid -> Text -> Maybe a instance FromField Int where fromField = fromParser (Oid.smallint \/ Oid.integer \/ Oid.bigint) (signed decimal) instance FromField Text where fromField oid text = if Oid.text oid || Oid.character oid || Oid.characterVarying oid then Just text else Nothing instance FromField String where fromField oid text = Text.unpack <$> fromField oid text