module WithCli.Normalize (
  normalize,
  matches,
 ) where

import           Data.Char

matches :: String -> String -> Bool
matches :: String -> String -> Bool
matches a :: String
a b :: String
b =
  String -> String
normalize String
a String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String -> String
normalize String
b

normalize :: String -> String
normalize :: String -> String
normalize s :: String
s =
  if (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isAllowedChar) String
s
    then String
s
    else
      String -> String
slugify (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$
      (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '-') (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$
      (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
filter Char -> Bool
isAllowedChar (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$
      (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map (\ c :: Char
c -> if Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '_' then '-' else Char
c) (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$
      String
s
  where
    slugify :: String -> String
slugify (a :: Char
a : r :: String
r)
      | Char -> Bool
isUpper Char
a = String -> String
slugify (Char -> Char
toLower Char
a Char -> String -> String
forall a. a -> [a] -> [a]
: String
r)
    slugify (a :: Char
a : b :: Char
b : r :: String
r)
      | Char -> Bool
isUpper Char
b = Char
a Char -> String -> String
forall a. a -> [a] -> [a]
: '-' Char -> String -> String
forall a. a -> [a] -> [a]
: String -> String
slugify (Char -> Char
toLower Char
b Char -> String -> String
forall a. a -> [a] -> [a]
: String
r)
      | Bool
otherwise = Char
a Char -> String -> String
forall a. a -> [a] -> [a]
: String -> String
slugify (Char
b Char -> String -> String
forall a. a -> [a] -> [a]
: String
r)
    slugify x :: String
x = String
x

isAllowedChar :: Char -> Bool
isAllowedChar :: Char -> Bool
isAllowedChar c :: Char
c = (Char -> Bool
isAscii Char
c Bool -> Bool -> Bool
&& Char -> Bool
isAlphaNum Char
c) Bool -> Bool -> Bool
|| (Char
c Char -> String -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` "-_")