-- | Globally Unique IDentifiers. module Data.CQRS.GUID ( GUID , fromByteString , base64Decode , base64Encode , hexDecode , hexEncode , newGUID , toByteString ) where import Control.DeepSeq (NFData(..)) import Data.ByteString (ByteString) import qualified Data.ByteString as B import qualified Data.ByteString.Base16 as B16 import qualified Data.ByteString.Base64 as B64 import Data.ByteString.Char8 () import Data.Data (Data) import Data.DeriveTH (derive, makeNFData) import Data.Typeable (Typeable) import Data.Word (Word8) import System.Random (randomRIO) import Data.CQRS.Serializable -- | A Globally Unique IDentifier. newtype GUID = GUID ByteString deriving (Typeable, Eq, Ord, Data) -- | Get a random byte. randomWord8 :: IO Word8 randomWord8 = fmap fromInteger $ randomRIO (0,255) -- | Create a new random GUID. newGUID :: IO GUID newGUID = do uuid <- sequence $ replicate 16 randomWord8 return $ GUID $ B.pack uuid -- | Serialize instance. instance Serializable GUID where serialize = toByteString deserialize = Just . GUID -- | Hex encode a GUID. hexEncode :: GUID -> ByteString hexEncode (GUID s) = B16.encode s -- | Base64 encode a GUID. base64Encode :: GUID -> ByteString base64Encode (GUID s) = B64.encode s -- | Showing a GUID. instance Show GUID where show = show . base64Encode -- | Decode a GUID from hex representation. hexDecode :: ByteString -> Maybe GUID hexDecode s = case B16.decode s of (a,b) | B.length b == 0 -> Just $ GUID a _ -> Nothing -- | Decode a GUID from base64 representation. base64Decode :: ByteString -> Maybe GUID base64Decode s = case B64.decode s of Right a -> Just $ GUID a Left _ -> Nothing -- | Convert from ByteString. fromByteString :: ByteString -> GUID fromByteString = GUID -- | Convert to ByteString. toByteString :: GUID -> ByteString toByteString (GUID g) = g -- Instances $(derive makeNFData ''GUID)