{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE DeriveTraversable #-}
-- | Conversions between several common identifier casing conventions:
--
-- - @PascalCase@ - no spacing between words, first letter in word is
-- uppercase, all others are lowercase.
-- - @camelCase@ - like @PascalCase@, but the very first letter is lowercase.
-- - @kebab-case@ - everything lowercase, dash delimits words.
-- - @snake_Case@ - underscores delimit words, case is unrestricted.
-- - @quiet_snake_case@ - underscores delimit words, everything lowercase.
-- - @SCREAMING_SNAKE_CASE@ - underscores delimit words, everything uppercase.
module Text.Casing
(
-- * Types
Identifier (..)
-- * Parsing
, fromHumps
, fromKebab
, fromSnake
, fromWords
, fromAny
-- * Generating
, toCamel
, toPascal
, toSnake
, toQuietSnake
, toScreamingSnake
, toKebab
, toWords
-- * Shorthand functions
, pascal
, camel
, snake
, quietSnake
, screamingSnake
, kebab
, wordify
-- * Miscellaneous
, dropPrefix
)
where

import Data.Char
import Data.List (intersperse)
import Data.List.Split (wordsBy)
import Control.Applicative

-- | An opaque type that represents a parsed identifier.
newtype Identifier a = Identifier { Identifier a -> [a]
unIdentifier :: [a] }
    deriving (Applicative Identifier
a -> Identifier a
Applicative Identifier
-> (forall a b.
    Identifier a -> (a -> Identifier b) -> Identifier b)
-> (forall a b. Identifier a -> Identifier b -> Identifier b)
-> (forall a. a -> Identifier a)
-> Monad Identifier
Identifier a -> (a -> Identifier b) -> Identifier b
Identifier a -> Identifier b -> Identifier b
forall a. a -> Identifier a
forall a b. Identifier a -> Identifier b -> Identifier b
forall a b. Identifier a -> (a -> Identifier b) -> Identifier b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> Identifier a
$creturn :: forall a. a -> Identifier a
>> :: Identifier a -> Identifier b -> Identifier b
$c>> :: forall a b. Identifier a -> Identifier b -> Identifier b
>>= :: Identifier a -> (a -> Identifier b) -> Identifier b
$c>>= :: forall a b. Identifier a -> (a -> Identifier b) -> Identifier b
$cp1Monad :: Applicative Identifier
Monad, a -> Identifier b -> Identifier a
(a -> b) -> Identifier a -> Identifier b
(forall a b. (a -> b) -> Identifier a -> Identifier b)
-> (forall a b. a -> Identifier b -> Identifier a)
-> Functor Identifier
forall a b. a -> Identifier b -> Identifier a
forall a b. (a -> b) -> Identifier a -> Identifier b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Identifier b -> Identifier a
$c<$ :: forall a b. a -> Identifier b -> Identifier a
fmap :: (a -> b) -> Identifier a -> Identifier b
$cfmap :: forall a b. (a -> b) -> Identifier a -> Identifier b
Functor, Functor Identifier
a -> Identifier a
Functor Identifier
-> (forall a. a -> Identifier a)
-> (forall a b.
    Identifier (a -> b) -> Identifier a -> Identifier b)
-> (forall a b c.
    (a -> b -> c) -> Identifier a -> Identifier b -> Identifier c)
-> (forall a b. Identifier a -> Identifier b -> Identifier b)
-> (forall a b. Identifier a -> Identifier b -> Identifier a)
-> Applicative Identifier
Identifier a -> Identifier b -> Identifier b
Identifier a -> Identifier b -> Identifier a
Identifier (a -> b) -> Identifier a -> Identifier b
(a -> b -> c) -> Identifier a -> Identifier b -> Identifier c
forall a. a -> Identifier a
forall a b. Identifier a -> Identifier b -> Identifier a
forall a b. Identifier a -> Identifier b -> Identifier b
forall a b. Identifier (a -> b) -> Identifier a -> Identifier b
forall a b c.
(a -> b -> c) -> Identifier a -> Identifier b -> Identifier c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: Identifier a -> Identifier b -> Identifier a
$c<* :: forall a b. Identifier a -> Identifier b -> Identifier a
*> :: Identifier a -> Identifier b -> Identifier b
$c*> :: forall a b. Identifier a -> Identifier b -> Identifier b
liftA2 :: (a -> b -> c) -> Identifier a -> Identifier b -> Identifier c
$cliftA2 :: forall a b c.
(a -> b -> c) -> Identifier a -> Identifier b -> Identifier c
<*> :: Identifier (a -> b) -> Identifier a -> Identifier b
$c<*> :: forall a b. Identifier (a -> b) -> Identifier a -> Identifier b
pure :: a -> Identifier a
$cpure :: forall a. a -> Identifier a
$cp1Applicative :: Functor Identifier
Applicative, Int -> Identifier a -> ShowS
[Identifier a] -> ShowS
Identifier a -> String
(Int -> Identifier a -> ShowS)
-> (Identifier a -> String)
-> ([Identifier a] -> ShowS)
-> Show (Identifier a)
forall a. Show a => Int -> Identifier a -> ShowS
forall a. Show a => [Identifier a] -> ShowS
forall a. Show a => Identifier a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Identifier a] -> ShowS
$cshowList :: forall a. Show a => [Identifier a] -> ShowS
show :: Identifier a -> String
$cshow :: forall a. Show a => Identifier a -> String
showsPrec :: Int -> Identifier a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Identifier a -> ShowS
Show, a -> Identifier a -> Bool
Identifier m -> m
Identifier a -> [a]
Identifier a -> Bool
Identifier a -> Int
Identifier a -> a
Identifier a -> a
Identifier a -> a
Identifier a -> a
(a -> m) -> Identifier a -> m
(a -> m) -> Identifier a -> m
(a -> b -> b) -> b -> Identifier a -> b
(a -> b -> b) -> b -> Identifier a -> b
(b -> a -> b) -> b -> Identifier a -> b
(b -> a -> b) -> b -> Identifier a -> b
(a -> a -> a) -> Identifier a -> a
(a -> a -> a) -> Identifier a -> a
(forall m. Monoid m => Identifier m -> m)
-> (forall m a. Monoid m => (a -> m) -> Identifier a -> m)
-> (forall m a. Monoid m => (a -> m) -> Identifier a -> m)
-> (forall a b. (a -> b -> b) -> b -> Identifier a -> b)
-> (forall a b. (a -> b -> b) -> b -> Identifier a -> b)
-> (forall b a. (b -> a -> b) -> b -> Identifier a -> b)
-> (forall b a. (b -> a -> b) -> b -> Identifier a -> b)
-> (forall a. (a -> a -> a) -> Identifier a -> a)
-> (forall a. (a -> a -> a) -> Identifier a -> a)
-> (forall a. Identifier a -> [a])
-> (forall a. Identifier a -> Bool)
-> (forall a. Identifier a -> Int)
-> (forall a. Eq a => a -> Identifier a -> Bool)
-> (forall a. Ord a => Identifier a -> a)
-> (forall a. Ord a => Identifier a -> a)
-> (forall a. Num a => Identifier a -> a)
-> (forall a. Num a => Identifier a -> a)
-> Foldable Identifier
forall a. Eq a => a -> Identifier a -> Bool
forall a. Num a => Identifier a -> a
forall a. Ord a => Identifier a -> a
forall m. Monoid m => Identifier m -> m
forall a. Identifier a -> Bool
forall a. Identifier a -> Int
forall a. Identifier a -> [a]
forall a. (a -> a -> a) -> Identifier a -> a
forall m a. Monoid m => (a -> m) -> Identifier a -> m
forall b a. (b -> a -> b) -> b -> Identifier a -> b
forall a b. (a -> b -> b) -> b -> Identifier a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: Identifier a -> a
$cproduct :: forall a. Num a => Identifier a -> a
sum :: Identifier a -> a
$csum :: forall a. Num a => Identifier a -> a
minimum :: Identifier a -> a
$cminimum :: forall a. Ord a => Identifier a -> a
maximum :: Identifier a -> a
$cmaximum :: forall a. Ord a => Identifier a -> a
elem :: a -> Identifier a -> Bool
$celem :: forall a. Eq a => a -> Identifier a -> Bool
length :: Identifier a -> Int
$clength :: forall a. Identifier a -> Int
null :: Identifier a -> Bool
$cnull :: forall a. Identifier a -> Bool
toList :: Identifier a -> [a]
$ctoList :: forall a. Identifier a -> [a]
foldl1 :: (a -> a -> a) -> Identifier a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Identifier a -> a
foldr1 :: (a -> a -> a) -> Identifier a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> Identifier a -> a
foldl' :: (b -> a -> b) -> b -> Identifier a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Identifier a -> b
foldl :: (b -> a -> b) -> b -> Identifier a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Identifier a -> b
foldr' :: (a -> b -> b) -> b -> Identifier a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Identifier a -> b
foldr :: (a -> b -> b) -> b -> Identifier a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> Identifier a -> b
foldMap' :: (a -> m) -> Identifier a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Identifier a -> m
foldMap :: (a -> m) -> Identifier a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Identifier a -> m
fold :: Identifier m -> m
$cfold :: forall m. Monoid m => Identifier m -> m
Foldable, Functor Identifier
Foldable Identifier
Functor Identifier
-> Foldable Identifier
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> Identifier a -> f (Identifier b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Identifier (f a) -> f (Identifier a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Identifier a -> m (Identifier b))
-> (forall (m :: * -> *) a.
    Monad m =>
    Identifier (m a) -> m (Identifier a))
-> Traversable Identifier
(a -> f b) -> Identifier a -> f (Identifier b)
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a.
Monad m =>
Identifier (m a) -> m (Identifier a)
forall (f :: * -> *) a.
Applicative f =>
Identifier (f a) -> f (Identifier a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Identifier a -> m (Identifier b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Identifier a -> f (Identifier b)
sequence :: Identifier (m a) -> m (Identifier a)
$csequence :: forall (m :: * -> *) a.
Monad m =>
Identifier (m a) -> m (Identifier a)
mapM :: (a -> m b) -> Identifier a -> m (Identifier b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Identifier a -> m (Identifier b)
sequenceA :: Identifier (f a) -> f (Identifier a)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
Identifier (f a) -> f (Identifier a)
traverse :: (a -> f b) -> Identifier a -> f (Identifier b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Identifier a -> f (Identifier b)
$cp2Traversable :: Foldable Identifier
$cp1Traversable :: Functor Identifier
Traversable, Identifier a -> Identifier a -> Bool
(Identifier a -> Identifier a -> Bool)
-> (Identifier a -> Identifier a -> Bool) -> Eq (Identifier a)
forall a. Eq a => Identifier a -> Identifier a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Identifier a -> Identifier a -> Bool
$c/= :: forall a. Eq a => Identifier a -> Identifier a -> Bool
== :: Identifier a -> Identifier a -> Bool
$c== :: forall a. Eq a => Identifier a -> Identifier a -> Bool
Eq)

wordCase :: String -> String
wordCase :: ShowS
wordCase String
"" = String
""
wordCase (Char
x:String
xs) = Char -> Char
toUpper Char
x Char -> ShowS
forall a. a -> [a] -> [a]
: (Char -> Char) -> ShowS
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower String
xs

-- | Convert from "humped" casing (@camelCase@ or @PascalCase@)
fromHumps :: String -> Identifier String
fromHumps :: String -> Identifier String
fromHumps = [String] -> Identifier String
forall a. [a] -> Identifier a
Identifier ([String] -> Identifier String)
-> (String -> [String]) -> String -> Identifier String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
go
    where
        go :: String -> [String]
go String
"" = [String
""]
        go (Char
x:[]) = [Char
xChar -> ShowS
forall a. a -> [a] -> [a]
:[]]
        go xxs :: String
xxs@(Char
x:String
xs)
          | Char -> Bool
isUpper Char
x =
              let lhs :: String
lhs = (Char -> Bool) -> ShowS
forall a. (a -> Bool) -> [a] -> [a]
takeWhile Char -> Bool
isUpper String
xxs
                  rhs :: String
rhs = (Char -> Bool) -> ShowS
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
isUpper String
xxs
              in
              if String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
rhs then
                [String
lhs]
              else
                let curLen :: Int
curLen = String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
lhs Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
                    cur :: String
cur = Int -> ShowS
forall a. Int -> [a] -> [a]
take Int
curLen String
lhs
                    rec :: [String]
rec = String -> [String]
go String
rhs
                    nxt :: String
nxt = Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
curLen String
lhs String -> ShowS
forall a. [a] -> [a] -> [a]
++ [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (Int -> [String] -> [String]
forall a. Int -> [a] -> [a]
take Int
1 [String]
rec)
                    rem :: [String]
rem = Int -> [String] -> [String]
forall a. Int -> [a] -> [a]
drop Int
1 [String]
rec
                    curL :: [String]
curL = if String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
cur then [] else [String
cur]
                    nxtL :: [String]
nxtL = if String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
nxt then [] else [String
nxt]
                in [String]
curL [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
nxtL [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
rem

          | Bool
otherwise =
              let cur :: String
cur = (Char -> Bool) -> ShowS
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isUpper) String
xxs
                  rem :: String
rem = (Char -> Bool) -> ShowS
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isUpper) String
xxs
              in
              if String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
rem then
                [String
cur]
              else
                String
curString -> [String] -> [String]
forall a. a -> [a] -> [a]
:String -> [String]
go String
rem

fromWords :: String -> Identifier String
fromWords :: String -> Identifier String
fromWords = [String] -> Identifier String
forall a. [a] -> Identifier a
Identifier ([String] -> Identifier String)
-> (String -> [String]) -> String -> Identifier String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
words

-- | Convert from @kebab-cased-identifiers@
fromKebab :: String -> Identifier String
fromKebab :: String -> Identifier String
fromKebab = [String] -> Identifier String
forall a. [a] -> Identifier a
Identifier ([String] -> Identifier String)
-> (String -> [String]) -> String -> Identifier String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> String -> [String]
forall a. (a -> Bool) -> [a] -> [[a]]
wordsBy (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'-')

-- | Convert from @snake_cased@ (either flavor)
fromSnake :: String -> Identifier String
fromSnake :: String -> Identifier String
fromSnake = [String] -> Identifier String
forall a. [a] -> Identifier a
Identifier ([String] -> Identifier String)
-> (String -> [String]) -> String -> Identifier String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> String -> [String]
forall a. (a -> Bool) -> [a] -> [[a]]
wordsBy (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'_')

-- | Convert from anything, including mixed casing.
fromAny :: String -> Identifier String
fromAny :: String -> Identifier String
fromAny String
str = String -> Identifier String
fromHumps String
str Identifier String
-> (String -> Identifier String) -> Identifier String
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> Identifier String
fromKebab Identifier String
-> (String -> Identifier String) -> Identifier String
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> Identifier String
fromSnake Identifier String
-> (String -> Identifier String) -> Identifier String
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> Identifier String
fromWords

-- | To @PascalCase@
toPascal :: Identifier String -> String
toPascal :: Identifier String -> String
toPascal = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([String] -> String)
-> (Identifier String -> [String]) -> Identifier String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ShowS
wordCase ([String] -> [String])
-> (Identifier String -> [String]) -> Identifier String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Identifier String -> [String]
forall a. Identifier a -> [a]
unIdentifier

-- | To @camelCase@
toCamel :: Identifier String -> String
toCamel :: Identifier String -> String
toCamel (Identifier []) = String
""
toCamel (Identifier (String
x:[String]
xs)) = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ (Char -> Char) -> ShowS
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower String
xString -> [String] -> [String]
forall a. a -> [a] -> [a]
:ShowS -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ShowS
wordCase [String]
xs

-- | To @kebab-case@
toKebab :: Identifier String -> String
toKebab :: Identifier String -> String
toKebab = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([String] -> String)
-> (Identifier String -> [String]) -> Identifier String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String] -> [String]
forall a. a -> [a] -> [a]
intersperse String
"-" ([String] -> [String])
-> (Identifier String -> [String]) -> Identifier String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ((Char -> Char) -> ShowS
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower) ([String] -> [String])
-> (Identifier String -> [String]) -> Identifier String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Identifier String -> [String]
forall a. Identifier a -> [a]
unIdentifier

-- | To @snake_Case@
toSnake :: Identifier String -> String
toSnake :: Identifier String -> String
toSnake = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([String] -> String)
-> (Identifier String -> [String]) -> Identifier String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String] -> [String]
forall a. a -> [a] -> [a]
intersperse String
"_" ([String] -> [String])
-> (Identifier String -> [String]) -> Identifier String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Identifier String -> [String]
forall a. Identifier a -> [a]
unIdentifier

-- | To @quiet_snake_case@
toQuietSnake :: Identifier String -> String
toQuietSnake :: Identifier String -> String
toQuietSnake = (Char -> Char) -> ShowS
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower ShowS
-> (Identifier String -> String) -> Identifier String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Identifier String -> String
toSnake

-- | To @SCREAMING_SNAKE_CASE@
toScreamingSnake :: Identifier String -> String
toScreamingSnake :: Identifier String -> String
toScreamingSnake = (Char -> Char) -> ShowS
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toUpper ShowS
-> (Identifier String -> String) -> Identifier String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Identifier String -> String
toSnake

-- | To @word Case@
toWords :: Identifier String -> String
toWords :: Identifier String -> String
toWords = [String] -> String
unwords ([String] -> String)
-> (Identifier String -> [String]) -> Identifier String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Identifier String -> [String]
forall a. Identifier a -> [a]
unIdentifier

-- | Directly convert to @PascalCase@ through 'fromAny'
pascal :: String -> String
pascal :: ShowS
pascal = Identifier String -> String
toPascal (Identifier String -> String)
-> (String -> Identifier String) -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Identifier String
fromAny

-- | Directly convert to @camelCase@ through 'fromAny'
camel :: String -> String
camel :: ShowS
camel = Identifier String -> String
toCamel (Identifier String -> String)
-> (String -> Identifier String) -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Identifier String
fromAny

-- | Directly convert to @snake_Case@ through 'fromAny'
snake :: String -> String
snake :: ShowS
snake = Identifier String -> String
toSnake (Identifier String -> String)
-> (String -> Identifier String) -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Identifier String
fromAny

-- | Directly convert to @quiet_snake_case@ through 'fromAny'
quietSnake :: String -> String
quietSnake :: ShowS
quietSnake = Identifier String -> String
toQuietSnake (Identifier String -> String)
-> (String -> Identifier String) -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Identifier String
fromAny

-- | Directly convert to @SCREAMING_SNAKE_CASE@ through 'fromAny'
screamingSnake :: String -> String
screamingSnake :: ShowS
screamingSnake = Identifier String -> String
toScreamingSnake (Identifier String -> String)
-> (String -> Identifier String) -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Identifier String
fromAny

-- | Directly convert to @kebab-case@ through 'fromAny'
kebab :: String -> String
kebab :: ShowS
kebab = Identifier String -> String
toKebab (Identifier String -> String)
-> (String -> Identifier String) -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Identifier String
fromAny

-- | Directly convert to @word Case@ through 'fromAny'
wordify :: String -> String
wordify :: ShowS
wordify = Identifier String -> String
toWords (Identifier String -> String)
-> (String -> Identifier String) -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Identifier String
fromAny

-- | Drop the first word from a parsed identifier. Typical usage is between
-- parsing and writing, e.g.: @toKebab . dropPrefix . fromAny $ "strHelloWorld" == "hello-world"@
dropPrefix :: Identifier String -> Identifier String
dropPrefix :: Identifier String -> Identifier String
dropPrefix = [String] -> Identifier String
forall a. [a] -> Identifier a
Identifier ([String] -> Identifier String)
-> (Identifier String -> [String])
-> Identifier String
-> Identifier String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [String] -> [String]
forall a. Int -> [a] -> [a]
drop Int
1 ([String] -> [String])
-> (Identifier String -> [String]) -> Identifier String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Identifier String -> [String]
forall a. Identifier a -> [a]
unIdentifier