you're telling me a puppy coded this??
{-# LANGUAGE TemplateHaskell #-}

-- | An effect for generating random values.
module Puppy.Crypto.RNG (
  -- * Effect
  RNG,
  -- * Handler
  runRNG,
  -- * Actions
  genUUID,
  genRSA,
  genBytes,
) where

import Effectful
import Effectful.Dispatch.Dynamic
import Effectful.TH (makeEffect)
import Crypto.Random (MonadRandom (..))
import Data.UUID (UUID)
import qualified Crypto.PubKey.RSA as RSA
import qualified Data.ByteString   as BS
import qualified Data.UUID.V4      as UUID

-- | An effect for generating random values.
data RNG :: Effect where
  GenRSA   :: RNG m (RSA.PublicKey, RSA.PrivateKey)
  GenUUID  :: RNG m UUID
  GenBytes :: Int -> RNG m BS.ByteString

type instance DispatchOf RNG = 'Dynamic

-- | A handler for the `RNG` effect.
runRNG
  :: (IOE :> es)
  => Eff (RNG : es) a
  -> Eff es a
runRNG = interpret $ \_ -> \case
  GenRSA  -> liftIO (RSA.generate 1024 65537)
  GenUUID -> liftIO UUID.nextRandom
  GenBytes len -> liftIO (getRandomBytes len)

makeEffect ''RNG