{- |
   Module      : Data.UUID.V4
   Copyright   : (c) 2012-2016 Antoine Latter

   License     : BSD-style

   Maintainer  : aslatter@gmail.com
   Stability   : experimental
   Portability : portable

   This module implements Version 4 UUIDs as specified
   in RFC 4122.

   These UUIDs are generated from a pseddo-random generator.
   We use 'getEntropy' method from <https://hackage.haskell.org/package/entropy entropy> package,
   which should provide cryptographically secure random data.
-}
module Data.UUID.V4 (nextRandom) where

import Data.UUID
import Data.UUID.Types.Internal ( buildFromBytes )

import System.Entropy ( getEntropy )
import Data.ByteString ( unpack )

-- | Generate a crytographically secure, random UUID. Introduced in version
-- 1.2.6.
nextRandom :: IO UUID
nextRandom :: IO UUID
nextRandom = do
  [Word8
b0, Word8
b1, Word8
b2, Word8
b3, Word8
b4, Word8
b5, Word8
b6, Word8
b7, Word8
b8, Word8
b9, Word8
ba, Word8
bb, Word8
bc, Word8
bd, Word8
be, Word8
bf]
    <- ByteString -> [Word8]
unpack (ByteString -> [Word8]) -> IO ByteString -> IO [Word8]
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` Int -> IO ByteString
getEntropy Int
16
  UUID -> IO UUID
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (UUID -> IO UUID) -> UUID -> IO UUID
forall a b. (a -> b) -> a -> b
$ Word8
-> Word8
-> Word8
-> Word8
-> Word8
-> Word8
-> Word8
-> Word8
-> Word8
-> Word8
-> Word8
-> Word8
-> Word8
-> Word8
-> Word8
-> Word8
-> Word8
-> UUID
buildFromBytes Word8
4 Word8
b0 Word8
b1 Word8
b2 Word8
b3 Word8
b4 Word8
b5 Word8
b6 Word8
b7 Word8
b8 Word8
b9 Word8
ba Word8
bb Word8
bc Word8
bd Word8
be Word8
bf