rfc-prelude-0.0.0.1: src/RFC/Data/UUID.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeSynonymInstances #-}
module RFC.Data.UUID
( module Data.UUID.Types
) where
import ClassyPrelude hiding ( fail )
import Control.Monad.Fail ( MonadFail, fail )
import qualified Data.Text as T
import Data.UUID.Types
import qualified Data.UUID.Types as UUID
import RFC.Prelude.String
#ifdef VERSION_aeson
#if MIN_VERSION_aeson(1,1,0)
-- UUID has ToJSON and FromJSON after Aeson 1.1.0
#else
import Data.Aeson.Types ( FromJSON (..), ToJSON (..), Value (String), typeMismatch )
#endif
#endif
#ifdef VERSION_servant_docs
import Servant.API.Capture
import Servant.Docs
#endif
#ifdef VERSION_servant_docs
instance ToCapture (Capture "id" UUID) where
toCapture _ = DocCapture "id" "UUID identifier"
instance ToSample UUID where
toSamples _ = samples . catMaybes $ UUID.fromString <$>
[ "cf41ac06-3f70-479c-a2ed-d618a5e6dee2"
, "26998bb3-d6c6-4f63-8a36-6b81eb6e6de9"
, "6176b857-e461-4f34-a6a6-aeb8cbf7ffdf"
, "26009820-d2d1-4360-87e0-aa73db3c0433"
]
#endif
#ifdef VERSION_aeson
#if MIN_VERSION_aeson(1,1,0)
-- UUID has ToJSON and FromJSON after Aeson 1.1.0
#else
instance ToJSON UUID where
toJSON = String . T.pack . show
{-# INLINE toJSON #-}
instance FromJSON UUID where
parseJSON json@(String t) =
case UUID.fromText t of
Just uuid -> pure uuid
Nothing -> typeMismatch "UUID" json
parseJSON unknown = typeMismatch "UUID" unknown
{-# INLINE parseJSON #-}
#endif
#endif
instance {-# OVERLAPPING #-} ToText UUID where
toText = UUID.toText
{-# INLINE toText #-}
instance {-# OVERLAPS #-} (MonadFail m) => FromText (m UUID) where
{-# SPECIALISE instance FromText (Maybe UUID) #-}
{-# SPECIALISE instance FromText ([UUID]) #-}
{-# SPECIALISE instance FromText (IO UUID) #-}
fromText :: Text -> m UUID
fromText text =
case UUID.fromText text of
Nothing -> fail $ "Could not parse UUID: " <> (T.unpack text)
Just x -> return x
{-# INLINE fromText #-}