Skip to content

Commit

Permalink
refactor(lib): Make MonadPass more flexible
Browse files Browse the repository at this point in the history
  • Loading branch information
sgillespie committed Jan 17, 2024
1 parent e749c33 commit bda1591
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 23 deletions.
1 change: 1 addition & 0 deletions gibberish.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ library
Data.Elocrypt.Trigraph,
Data.Elocrypt.Utils,
Data.Gibberish.Format,
Data.Gibberish.GenPass,
Data.Gibberish.GenTrigraph,
Data.Gibberish.MonadPass,
Data.Gibberish.Types
Expand Down
6 changes: 2 additions & 4 deletions src/Data/Gibberish/Format.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ module Data.Gibberish.Format
MaxHeight (..),
Separator (..),
ExactNumberWords (..),
Word (..),
formatWords,
formatLine,
) where

import Data.Gibberish.Types

import Data.List (intersperse)
import Data.Text (Text ())
import Data.Text qualified as Text
Expand Down Expand Up @@ -37,9 +38,6 @@ newtype ExactNumberWords = ExactNumberWords {unExactWords :: Int}
deriving stock (Eq, Show)
deriving newtype (Enum, Integral, Num, Ord, Real)

newtype Word = Word {unWord :: Text}
deriving stock (Eq, Show)

newtype FormatText = FormatText {fmtLines :: [FormatLine]}
deriving stock (Eq, Show)

Expand Down
53 changes: 37 additions & 16 deletions src/Data/Gibberish/MonadPass.hs
Original file line number Diff line number Diff line change
@@ -1,36 +1,57 @@
module Data.Gibberish.MonadPass
( PassT (..),
( Pass (),
PassT (..),
runPass,
evalPass,
usingPass,
runPassT,
evalPassT,
usingPassT,
) where

import Data.Gibberish.Types (GenPassOptions ())

import Control.Monad.Random.Class (MonadRandom ())
import Control.Monad.Reader (MonadReader (), ReaderT (), runReaderT)
import Control.Monad.Trans.Random (RandT (), runRandT)
import Control.Monad.Trans.Random (RandT (), evalRandT, runRandT)
import Data.Functor.Identity (Identity (..))

-- | Password/Passphrase generation monad parameterized by the type @gen@ of the generator
-- to carry
type Pass gen = PassT gen Identity

-- | Run a generation computation with the given options and initial generator
runPass :: Pass gen a -> gen -> (a, gen)
runPass action = runIdentity . runPassT action

-- | Evaluate a generation computation with the given options and initial
-- generator, discarding the final generator
evalPass :: Pass gen a -> gen -> a
evalPass action = runIdentity . evalPassT action

-- | Shorter and more readable alias for @flip runPassT@.
usingPass :: gen -> Pass gen a -> (a, gen)
usingPass = flip runPass

-- | Password/Passphrase generation monad
newtype PassT g m a = PassT {unPass :: ReaderT GenPassOptions (RandT g m) a}
-- | Password/Passphrase generation transformer monad parameterized by :
--
-- * @gen@ - the generator.
-- * @m@ - the inner monad.
newtype PassT gen m a = PassT {unPass :: RandT gen m a}
deriving newtype
( Applicative,
Functor,
Monad,
MonadFail,
MonadRandom,
MonadReader GenPassOptions
MonadRandom
)

-- | Run a generation computation with the given options and initial generator
runPassT :: PassT g m a -> GenPassOptions -> g -> m (a, g)
runPassT act = runRandT . runReaderT (unPass act)
runPassT :: PassT g m a -> g -> m (a, g)
runPassT = runRandT . unPass

-- | Evaluate a generation computation with the given options and initial
-- generator, discarding the final generator
evalPassT :: Functor m => PassT g m a -> GenPassOptions -> g -> m a
evalPassT act opts gen = fst <$> runPassT act opts gen
evalPassT :: Monad m => PassT g m a -> g -> m a
evalPassT = evalRandT . unPass

-- | Like @runGenT@, but the computation is the last argument
usingPassT :: GenPassOptions -> g -> PassT g m a -> m (a, g)
usingPassT opts gen act = runPassT act opts gen
-- | Shorter and more readable alias for @flip runPassT@.
usingPassT :: g -> PassT g m a -> m (a, g)
usingPassT = flip runPassT
14 changes: 11 additions & 3 deletions src/Data/Gibberish/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module Data.Gibberish.Types
Frequency (..),
Frequencies (..),
Trigraph (..),
Word (..),
) where

import Control.DeepSeq (NFData)
Expand All @@ -18,15 +19,18 @@ import Data.Map (Map ())
import Data.Text (Text ())
import GHC.Generics (Generic ())
import TextShow (TextShow (..), fromString)
import Prelude hiding (Word ())

-- | Password/Passphrase generation options
data GenPassOptions = GenPassOptions
{ -- | Include capitals?
genCapitals :: !Bool,
optsCapitals :: !Bool,
-- | Include numerals?
genDigits :: !Bool,
optsDigits :: !Bool,
-- | Include special characters?
genSpecials :: !Bool
optsSpecials :: !Bool,
-- | The trigraph to use
optsTrigraph :: Trigraph
}
deriving stock (Eq, Show)

Expand Down Expand Up @@ -62,6 +66,10 @@ newtype Trigraph = Trigraph {unTrigraph :: Map Digram Frequencies}
deriving stock (Eq, Show)
deriving newtype (FromJSON, ToJSON, NFData)

-- | A natural language word
newtype Word = Word {unWord :: Text}
deriving stock (Eq, Show)

instance TextShow Digram where
showb (Digram c1 c2) = fromString [c1, c2]

Expand Down

0 comments on commit bda1591

Please sign in to comment.