gibberish-3.0.0.0: src/Data/Gibberish/Types.hs
{-# LANGUAGE OverloadedLists #-}
module Data.Gibberish.Types
( GenPasswordOpts (..),
GenPassphraseOpts (..),
Language (..),
TrigraphConfig (..),
Unigram (..),
Digram (..),
Trigram (..),
Frequency (..),
Frequencies (..),
Trigraph (..),
Word (..),
) where
import Control.DeepSeq (NFData)
import Data.Aeson (FromJSON (..), FromJSONKey (..), ToJSON (..), ToJSONKey (..))
import Data.Aeson qualified as Aeson
import Data.Aeson.Types (FromJSONKeyFunction (..), Parser (), toJSONKeyText)
import Data.Map (Map ())
import Data.Text (Text ())
import GHC.Generics (Generic ())
import TextShow (TextShow (..), fromString)
import Prelude hiding (Word ())
-- | Password generation options
data GenPasswordOpts = GenPasswordOpts
{ -- | Include capitals?
woptsCapitals :: !Bool,
-- | Include numerals?
woptsDigits :: !Bool,
-- | Include special characters?
woptsSpecials :: !Bool,
-- | The trigraph to use
woptsTrigraph :: Trigraph,
-- | The length of the password
woptsLength :: !Int
}
deriving stock (Eq, Show)
-- | Passphrase generation options
data GenPassphraseOpts = GenPassphraseOpts
{ -- | Include capitals?
poptsCapitals :: !Bool,
-- | Include numerals?
poptsDigits :: !Bool,
-- | Include special characters?
poptsSpecials :: !Bool,
-- | The trigraph to use
poptsTrigraph :: Trigraph,
-- | The mininum length of each word
poptsMinLength :: !Int,
-- | The maximum length of each word
poptsMaxLength :: !Int
}
deriving stock (Eq, Show)
-- | A language indicating the dictionary that generated a trigraph
data Language
= English
| Spanish
| CustomTrigraph TrigraphConfig
deriving stock (Eq, Show)
-- | A path to a trigraph json config file
newtype TrigraphConfig = TrigraphConfig
{unTrigraphConfig :: FilePath}
deriving stock (Eq, Show)
-- | A unigram is a single letter
newtype Unigram = Unigram {unUnigram :: Char}
deriving stock (Eq, Ord, Show)
deriving newtype (FromJSON, FromJSONKey, NFData, ToJSON, ToJSONKey)
-- | A digram is a sequence of two letters
data Digram = Digram Char Char
deriving stock (Eq, Generic, Show)
deriving anyclass (NFData)
-- | A trigrams is a sequence of three letters
data Trigram = Trigram Char Char Char
deriving stock (Eq, Generic, Show)
deriving anyclass (NFData)
-- | A frequency represents the number of times a given trigram occurs
-- in a language
newtype Frequency = Frequency {unFrequency :: Int}
deriving stock (Eq, Show)
deriving newtype (FromJSON, ToJSON, NFData, Enum, Integral, Num, Ord, Real)
-- | Frequencies maps a unigram to a frequency
newtype Frequencies = Frequencies {unFrequencies :: Map Unigram Frequency}
deriving stock (Eq, Show)
deriving newtype (FromJSON, ToJSON, NFData)
-- | A trigraph is a mapping of all digrams to frequencies. That is, for a set of
-- digrams, it contains the frequencies of all possible trigram candidates.
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]
instance ToJSON Digram where
toJSON (Digram c1 c2) = Aeson.String [c1, c2]
instance ToJSONKey Digram where
toJSONKey = toJSONKeyText toText
where
toText :: Digram -> Text
toText = showt
instance FromJSON Digram where
parseJSON = Aeson.withText "Digram" parseDigram
instance FromJSONKey Digram where
fromJSONKey = FromJSONKeyTextParser parseDigram
instance Ord Digram where
(Digram a1 b1) `compare` (Digram a2 b2) =
(a1, b1) `compare` (a2, b2)
instance Ord Trigram where
(Trigram a1 b1 c1) `compare` (Trigram a2 b2 c2) =
(a1, b1, c1) `compare` (a2, b2, c2)
parseDigram :: Text -> Parser Digram
parseDigram = (uncurry Digram <$>) . fromText
where
fromText [ch1, ch2] = pure (ch1, ch2)
fromText _ = fail "Not a string of length 2"