    module WithCli.Normalize (
      normalize,
      matches,
     ) where

    import           Data.Char

    matches :: String -> String -> Bool
    matches :: String -> String -> Bool
    matches String
    a 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 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
    == Char
    '-') (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 (\ Char
    c -> if Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '_' then Char
    '-' else Char
    c) (String -> String) -> String -> String
    forall a b. (a -> b) -> a -> b
    $
          String
    s
      where
        slugify :: String -> String
    slugify (Char
    a : 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 (Char
    a : Char
    b : String
    r)
          | Char -> Bool
    isUpper Char
    b = Char
    a Char -> String -> String
    forall a. a -> [a] -> [a]
    : Char
    '-' 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 String
    x = String
    x

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