{-# LANGUAGE MagicHash #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ViewPatterns #-}
module Data.Text.Manipulate.Internal.Types where
import Control.Monad
import qualified Data.Char as Char
import Data.Text.Lazy.Builder (Builder, singleton)
import GHC.Base
isWordBoundary :: Char -> Bool
isWordBoundary :: Char -> Bool
isWordBoundary Char
c = Char -> Bool
Char.isUpper Char
c Bool -> Bool -> Bool
|| Char -> Bool
isBoundary Char
c
isBoundary :: Char -> Bool
isBoundary :: Char -> Bool
isBoundary = Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
Char.isAlphaNum
ordinal :: Integral a => a -> Builder
ordinal :: a -> Builder
ordinal (a -> Integer
forall a. Integral a => a -> Integer
toInteger -> Integer
n) = Integer -> Builder
forall a. Integral a => a -> Builder
decimal Integer
n Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
suf
where
suf :: Builder
suf
| Integer
x Integer -> [Integer] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Integer
11 .. Integer
13] = Builder
"th"
| Integer
y Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
1 = Builder
"st"
| Integer
y Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
2 = Builder
"nd"
| Integer
y Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
3 = Builder
"rd"
| Bool
otherwise = Builder
"th"
((Integer -> Integer -> Integer) -> Integer -> Integer -> Integer
forall a b c. (a -> b -> c) -> b -> a -> c
flip Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
mod Integer
100 -> Integer
x, (Integer -> Integer -> Integer) -> Integer -> Integer -> Integer
forall a b c. (a -> b -> c) -> b -> a -> c
flip Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
mod Integer
10 -> Integer
y) = (Integer -> Integer -> (Integer, Integer))
-> Integer -> (Integer, Integer)
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (,) (Integer -> Integer
forall a. Num a => a -> a
abs Integer
n)
{-# NOINLINE [0] ordinal #-}
decimal :: Integral a => a -> Builder
{-# SPECIALIZE decimal :: Int -> Builder #-}
decimal :: a -> Builder
decimal a
i
| a
i a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
0 = Char -> Builder
singleton Char
'-' Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> a -> Builder
forall a. Integral a => a -> Builder
go (- a
i)
| Bool
otherwise = a -> Builder
forall a. Integral a => a -> Builder
go a
i
where
go :: a -> Builder
go a
n
| a
n a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
10 = a -> Builder
forall a. Integral a => a -> Builder
digit a
n
| Bool
otherwise = a -> Builder
go (a
n a -> a -> a
forall a. Integral a => a -> a -> a
`quot` a
10) Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> a -> Builder
forall a. Integral a => a -> Builder
digit (a
n a -> a -> a
forall a. Integral a => a -> a -> a
`rem` a
10)
{-# NOINLINE [0] decimal #-}
digit :: Integral a => a -> Builder
digit :: a -> Builder
digit a
n = Char -> Builder
singleton (Char -> Builder) -> Char -> Builder
forall a b. (a -> b) -> a -> b
$! Int -> Char
i2d (a -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
n)
{-# INLINE digit #-}
i2d :: Int -> Char
i2d :: Int -> Char
i2d (I# Int#
i#) = Char# -> Char
C# (Int# -> Char#
chr# (Char# -> Int#
ord# Char#
'0'# Int# -> Int# -> Int#
+# Int#
i#))
{-# INLINE i2d #-}