{-# LANGUAGE CPP #-}
{-# OPTIONS_HADDOCK not-home #-}
module Yamlet.Internal.Utils
( textStripPrefix
, textIsPrefixOf
, maxImplicitKeyLength
, maxVersion
, minExpansion
, coreTagPrefix
, picoDecimals
, decimalPlaces
, isHighSurrogate
, isLowSurrogate
, fromSurrogates
, isScalarValue
, xEscapeDigits
, uEscapeDigits
, bigUEscapeDigits
, percentDigits
, showText
, strictPair
, strictMap
, firstOfResult
) where
import Data.Char
import Data.Fixed
import Data.Proxy
import Data.Text qualified as T
import Math.NumberTheory.Logarithms
import Numeric
#if !MIN_VERSION_text(2,1,4)
import Data.Text.Internal qualified as T
#endif
textStripPrefix :: T.Text -> T.Text -> Maybe T.Text
#if MIN_VERSION_text(2,1,4)
textStripPrefix :: Text -> Text -> Maybe Text
textStripPrefix = Text -> Text -> Maybe Text
T.stripPrefix
#else
textStripPrefix p@(T.Text _arr _off plen) t@(T.Text arr off len)
| textIsPrefixOf p t = Just $! T.text arr (off + plen) (len - plen)
| otherwise = Nothing
#endif
textIsPrefixOf :: T.Text -> T.Text -> Bool
#if MIN_VERSION_text(2,1,4)
textIsPrefixOf :: Text -> Text -> Bool
textIsPrefixOf = Text -> Text -> Bool
T.isPrefixOf
#else
textIsPrefixOf a@(T.Text _aArr _aOff aLen) b@(T.Text bArr bOff bLen) =
d >= 0 && a == b'
where
d :: Int
d = bLen - aLen
b' :: T.Text
b'
| d == 0 = b
| otherwise = T.Text bArr bOff aLen
#endif
maxImplicitKeyLength :: Int
maxImplicitKeyLength :: Int
maxImplicitKeyLength = Int
1024
maxVersion :: Int
maxVersion :: Int
maxVersion = Int
1000000
minExpansion :: Int
minExpansion :: Int
minExpansion = Int
100000
coreTagPrefix :: T.Text
coreTagPrefix :: Text
coreTagPrefix = Text
"tag:yaml.org,2002:"
picoDecimals :: Int
picoDecimals :: Int
picoDecimals = Integer -> Int
integerLog10 (Proxy E12 -> Integer
forall k (a :: k) (p :: k -> *). HasResolution a => p a -> Integer
forall (p :: * -> *). p E12 -> Integer
resolution (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @E12))
decimalPlaces :: Integer -> Maybe Int
decimalPlaces :: Integer -> Maybe Int
decimalPlaces Integer
n = if Integer
rest Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
1 then Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
twos Int
fives) else Maybe Int
forall a. Maybe a
Nothing
where
twos, fives :: Int
afterTwos, rest :: Integer
(Int
twos, Integer
afterTwos) = Integer -> Integer -> (Int, Integer)
factors Integer
2 Integer
n
(Int
fives, Integer
rest) = Integer -> Integer -> (Int, Integer)
factors Integer
5 Integer
afterTwos
factors :: Integer -> Integer -> (Int, Integer)
factors :: Integer -> Integer -> (Int, Integer)
factors Integer
p = Int -> Integer -> (Int, Integer)
go Int
0
where
go :: Int -> Integer -> (Int, Integer)
go :: Int -> Integer -> (Int, Integer)
go Int
i Integer
x = case Integer
x Integer -> Integer -> (Integer, Integer)
forall a. Integral a => a -> a -> (a, a)
`quotRem` Integer
p of
(Integer
q, Integer
0) | Integer
x Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
/= Integer
0 -> Int -> Integer -> (Int, Integer)
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Integer
q
(Integer, Integer)
_ -> (Int
i, Integer
x)
isHighSurrogate :: Int -> Bool
isHighSurrogate :: Int -> Bool
isHighSurrogate Int
u = Int
u Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0xD800 Bool -> Bool -> Bool
&& Int
u Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0xDBFF
isLowSurrogate :: Int -> Bool
isLowSurrogate :: Int -> Bool
isLowSurrogate Int
u = Int
u Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0xDC00 Bool -> Bool -> Bool
&& Int
u Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0xDFFF
fromSurrogates :: Int -> Int -> Int
fromSurrogates :: Int -> Int -> Int
fromSurrogates Int
hi Int
lo = Int
0x10000 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Int
hi Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
0xD800) Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
0x400 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Int
lo Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
0xDC00)
isScalarValue :: Int -> Bool
isScalarValue :: Int -> Bool
isScalarValue Int
c =
Int
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Char -> Int
ord Char
forall a. Bounded a => a
maxBound Bool -> Bool -> Bool
&& Bool -> Bool
not (Int -> Bool
isHighSurrogate Int
c Bool -> Bool -> Bool
|| Int -> Bool
isLowSurrogate Int
c)
xEscapeDigits, uEscapeDigits, bigUEscapeDigits :: Int
xEscapeDigits :: Int
xEscapeDigits = Int
2
uEscapeDigits :: Int
uEscapeDigits = Int
4
bigUEscapeDigits :: Int
bigUEscapeDigits = Int
8
percentDigits :: Int
percentDigits :: Int
percentDigits = Int
2
showText :: T.Text -> String
showText :: Text -> [Char]
showText Text
t = Char
'"' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: (Char -> [Char]) -> [Char] -> [Char]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Char -> [Char]
escape (Text -> [Char]
T.unpack Text
t) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"\""
where
escape :: Char -> String
escape :: Char -> [Char]
escape Char
c
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'"' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\\' = [Char
'\\', Char
c]
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\n' = [Char]
"\\n"
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\r' = [Char]
"\\r"
| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'\t' = [Char]
"\\t"
| Char -> Bool
isPrint Char
c = [Char
c]
| Char -> Int
ord Char
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
16 Int -> Int -> Int
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
xEscapeDigits = Char -> Int -> [Char]
hex Char
'x' Int
xEscapeDigits
| Char -> Int
ord Char
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
16 Int -> Int -> Int
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
uEscapeDigits = Char -> Int -> [Char]
hex Char
'u' Int
uEscapeDigits
| Bool
otherwise = Char -> Int -> [Char]
hex Char
'U' Int
bigUEscapeDigits
where
hex :: Char -> Int -> String
hex :: Char -> Int -> [Char]
hex Char
p Int
width =
let h :: [Char]
h = Int -> [Char] -> [Char]
forall a. Integral a => a -> [Char] -> [Char]
showHex (Char -> Int
ord Char
c) [Char]
""
in Char
'\\' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: Char
p Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: Int -> Char -> [Char]
forall a. Int -> a -> [a]
replicate (Int
width Int -> Int -> Int
forall a. Num a => a -> a -> a
- [Char] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Char]
h) Char
'0' [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
h
strictPair :: a -> b -> (a, b)
strictPair :: forall a b. a -> b -> (a, b)
strictPair !a
a !b
b = (a
a, b
b)
strictMap :: forall a b. (a -> b) -> [a] -> [b]
strictMap :: forall a b. (a -> b) -> [a] -> [b]
strictMap a -> b
f = [b] -> [a] -> [b]
go []
where
go :: [b] -> [a] -> [b]
go :: [b] -> [a] -> [b]
go [b]
acc = \case
[] -> [b] -> [b]
forall a. [a] -> [a]
reverse [b]
acc
a
x : [a]
xs -> let !y :: b
y = a -> b
f a
x in [b] -> [a] -> [b]
go (b
y b -> [b] -> [b]
forall a. a -> [a] -> [a]
: [b]
acc) [a]
xs
firstOfResult :: Either e (a, b) -> Either e a
firstOfResult :: forall e a b. Either e (a, b) -> Either e a
firstOfResult = \case
Left e
e -> e -> Either e a
forall a b. a -> Either a b
Left e
e
Right (a
a, b
_) -> a -> Either e a
forall a b. b -> Either a b
Right a
a