{-# LANGUAGE TemplateHaskell #-}
module Text.Password.Strength.Internal.Token (
Token(..),
allTokens,
tokenChars,
tokenLower,
startIndex,
endIndex,
translateMap
) where
import Control.Lens.TH (makeLenses)
import Data.Text (Text)
import qualified Data.Text as Text
data Token = Token
{ Token -> Text
_tokenChars :: Text
, Token -> Text
_tokenLower :: Text
, Token -> Int
_startIndex :: Int
, Token -> Int
_endIndex :: Int
} deriving (Int -> Token -> ShowS
[Token] -> ShowS
Token -> String
(Int -> Token -> ShowS)
-> (Token -> String) -> ([Token] -> ShowS) -> Show Token
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Token] -> ShowS
$cshowList :: [Token] -> ShowS
show :: Token -> String
$cshow :: Token -> String
showsPrec :: Int -> Token -> ShowS
$cshowsPrec :: Int -> Token -> ShowS
Show, Token -> Token -> Bool
(Token -> Token -> Bool) -> (Token -> Token -> Bool) -> Eq Token
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Token -> Token -> Bool
$c/= :: Token -> Token -> Bool
== :: Token -> Token -> Bool
$c== :: Token -> Token -> Bool
Eq, Eq Token
Eq Token
-> (Token -> Token -> Ordering)
-> (Token -> Token -> Bool)
-> (Token -> Token -> Bool)
-> (Token -> Token -> Bool)
-> (Token -> Token -> Bool)
-> (Token -> Token -> Token)
-> (Token -> Token -> Token)
-> Ord Token
Token -> Token -> Bool
Token -> Token -> Ordering
Token -> Token -> Token
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Token -> Token -> Token
$cmin :: Token -> Token -> Token
max :: Token -> Token -> Token
$cmax :: Token -> Token -> Token
>= :: Token -> Token -> Bool
$c>= :: Token -> Token -> Bool
> :: Token -> Token -> Bool
$c> :: Token -> Token -> Bool
<= :: Token -> Token -> Bool
$c<= :: Token -> Token -> Bool
< :: Token -> Token -> Bool
$c< :: Token -> Token -> Bool
compare :: Token -> Token -> Ordering
$ccompare :: Token -> Token -> Ordering
$cp1Ord :: Eq Token
Ord)
makeLenses ''Token
allTokens :: Text -> [Token]
allTokens :: Text -> [Token]
allTokens = Int -> Text -> [Token]
outer Int
0
where
outer :: Int -> Text -> [Token]
outer :: Int -> Text -> [Token]
outer Int
i Text
t
| Text -> Bool
Text.null Text
t = [ ]
| Bool
otherwise = Int -> Int -> Text -> [Token]
inner Int
i Int
2 Text
t [Token] -> [Token] -> [Token]
forall a. [a] -> [a] -> [a]
++ Int -> Text -> [Token]
outer (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) (Int -> Text -> Text
Text.drop Int
1 Text
t)
inner :: Int -> Int -> Text -> [Token]
inner :: Int -> Int -> Text -> [Token]
inner Int
i Int
j Text
t
| Text -> Int -> Ordering
Text.compareLength Text
t (Int
jInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
LT = [ ]
| Bool
otherwise = Int -> Int -> Text -> Token
mkT Int
i Int
j Text
t Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: Int -> Int -> Text -> [Token]
inner Int
i (Int
jInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) Text
t
mkT :: Int -> Int -> Text -> Token
mkT :: Int -> Int -> Text -> Token
mkT Int
i Int
j Text
t =
let chars :: Text
chars = Int -> Text -> Text
Text.take (Int
jInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) Text
t
in Text -> Text -> Int -> Int -> Token
Token Text
chars (Text -> Text
Text.toLower Text
chars) Int
i (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
j)
translateMap :: (Char -> String) -> Text -> [Text]
translateMap :: (Char -> String) -> Text -> [Text]
translateMap Char -> String
f = (String -> Text) -> [String] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map String -> Text
Text.pack ([String] -> [Text]) -> (Text -> [String]) -> Text -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> [String] -> [String]) -> [String] -> Text -> [String]
forall a. (Char -> a -> a) -> a -> Text -> a
Text.foldr Char -> [String] -> [String]
fork [String
""]
where
fork :: Char -> [String] -> [String]
fork :: Char -> [String] -> [String]
fork Char
c [String]
cs =
case Char -> String
f Char
c of
[]
-> ShowS -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (Char
cChar -> ShowS
forall a. a -> [a] -> [a]
:) [String]
cs
String
xs
-> (Char -> [String]) -> String -> [String]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\Char
c' -> ShowS -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (Char
c'Char -> ShowS
forall a. a -> [a] -> [a]
:) [String]
cs) String
xs