{-|

Copyright:
  This file is part of the package zxcvbn-hs. It is subject to the
  license terms in the LICENSE file found in the top-level directory
  of this distribution and at:

    https://code.devalot.com/sthenauth/zxcvbn-hs

  No part of this package, including this file, may be copied,
  modified, propagated, or distributed except according to the terms
  contained in the LICENSE file.

License: MIT

-}
module Text.Password.Strength.Internal.Dictionary (
  -- * Frequency Dictionary Matching
  Dictionary,
  Rank,
  rank
  ) where

--------------------------------------------------------------------------------
-- Library Imports:
import qualified Data.HashMap.Strict as HashMap
import Data.Maybe (mapMaybe)
import Data.Text (Text)

--------------------------------------------------------------------------------
-- Project Imports:
import Text.Password.Strength.Internal.Config

--------------------------------------------------------------------------------
-- | Type to represent a ranking.
type Rank = Int

--------------------------------------------------------------------------------
-- | Look up the given value in all configured dictionaries,
-- transforming each input with the given function.  The lowest ranked
-- score is return if it is found.
rank :: Config -> (a -> Text) -> a -> Maybe Rank
rank :: forall a. Config -> (a -> Text) -> a -> Maybe Rank
rank Config
c a -> Text
f a
a =
  case [Dictionary] -> [Rank]
check (Config -> [Dictionary]
dictionaries Config
c) of
    [] -> forall a. Maybe a
Nothing
    [Rank]
xs -> forall a. a -> Maybe a
Just (forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum [Rank]
xs)
  where
    check :: [Dictionary] -> [Rank]
    check :: [Dictionary] -> [Rank]
check = forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup Text
key)

    key :: Text
    key :: Text
key = a -> Text
f a
a