{-# OPTIONS_HADDOCK not-home #-}
module Yamlet.Internal.Parser.Hints
( unexpected
, flowError
, codePointName
, firstTab
, tabMessage
, keyLengthMessage
) where
import Control.Monad
import Data.Char
import Data.List qualified as L
import Data.Maybe
import Data.Text qualified as T
import Data.Text.Array qualified as A
import Data.Word
import Numeric
import Yamlet.Internal.Chars
import Yamlet.Internal.Parser.Monad
import Yamlet.Internal.Parser.Scan
import Yamlet.Internal.Utils
unexpected :: Env -> Int -> (Maybe Int, (Int, String))
unexpected :: Env -> Int -> (Maybe Int, (Int, [Char]))
unexpected Env
input Int
i = (Maybe Int
tabCause, (Int, [Char])
other)
where
tabCause :: Maybe Int
tabCause :: Maybe Int
tabCause = case Int -> Maybe Int -> Maybe Int
indentationTab (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Maybe Int
forall a. Maybe a
Nothing of
Maybe Int
Nothing
| Env -> Int -> Word8
byteAt Env
e Int
i Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
COLON Bool -> Bool -> Bool
&& Int -> Bool
firstColonFrom Int
contentStart ->
Env -> Int -> Int -> Maybe Int
firstTab Env
e Int
lineStart Int
contentStart
Maybe Int
t -> Maybe Int
t
other :: (Int, String)
other :: (Int, [Char])
other
| Just Int
start <- Maybe Int
propertiesLine =
( Int
start
, [Char]
"an anchor or a tag cannot be on a line of its own here, write it after the key or the '-'"
)
| Just (Int, [Char])
r <- Maybe (Int, [Char])
blockMistake = (Int, [Char])
r
| Bool
afterComment =
(Int
i, [Char]
"a comment ends a plain scalar, so this line cannot continue it")
| Just Int
colon <- Env -> Int -> Maybe Int
aliasColon Env
e Int
i = (Int
colon, [Char]
aliasColonMessage)
| Bool
otherwise = (Int
i,) ([Char] -> (Int, [Char])) -> [Char] -> (Int, [Char])
forall a b. (a -> b) -> a -> b
$ case Env -> Int -> Word8
byteAt Env
e Int
i of
Word8
w
| Env -> Int -> Word8
byteBefore Env
e Int
i Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
STAR Bool -> Bool -> Bool
&& Bool -> Bool
not (Word8 -> Bool
isAnchorChar Word8
w) ->
[Char]
"expected an alias name after '*'"
| Env -> Int -> Word8
byteBefore Env
e Int
i Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
AMP Bool -> Bool -> Bool
&& Bool -> Bool
not (Word8 -> Bool
isAnchorChar Word8
w) ->
[Char]
"expected an anchor name after '&'"
| Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0 -> [Char]
"unexpected end of input"
| Bool
indented, Just [Char]
msg <- Maybe [Char]
indentationMistake -> [Char]
msg
| Bool
indented, Just [Char]
msg <- Env -> Bool -> Int -> Maybe [Char]
mistakeIn Env
e Bool
False Int
i -> [Char]
msg
| Bool
indented, Bool -> Bool
not Bool
alignedWithEntry -> [Char]
"unexpected indentation"
| Word8 -> Bool
isBreak Word8
w -> [Char]
"unexpected end of line"
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Env
e.base Bool -> Bool -> Bool
&& Word8 -> Bool
isBreak (Env -> Int -> Word8
byteBefore Env
e Int
i)
, Just [Char]
msg <- Maybe [Char]
indentationMistake ->
[Char]
msg
| Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
COLON Bool -> Bool -> Bool
&& Bool
firstColon Bool -> Bool -> Bool
&& Bool -> Bool
not (Env -> Int -> Int -> Bool
fitsKey Env
e Int
entryStart Int
i) -> [Char]
keyLengthMessage
| Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
COLON Bool -> Bool -> Bool
&& Bool
multiLineKey ->
[Char]
"unexpected ':', a key must be on a single line"
| Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
COLON Bool -> Bool -> Bool
&& Bool
firstColon Bool -> Bool -> Bool
&& Bool
valueColon Bool -> Bool -> Bool
&& Bool
onStartMarkerLine ->
[Char]
"unexpected ':', a mapping cannot start on the line of '---'"
| Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
COLON
Bool -> Bool -> Bool
&& Bool
firstColon
Bool -> Bool -> Bool
&& Bool
valueColon
Bool -> Bool -> Bool
&& Maybe Int -> Bool
forall a. Maybe a -> Bool
isJust (Int -> Maybe Int
lineAbove (Env -> Int -> Int
lineStartAt Env
e Int
i)) ->
[Char]
"unexpected ':', this line continues the scalar from the line above, check the indentation and the line above"
| Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
COLON Bool -> Bool -> Bool
&& Bool
valueColon ->
[Char]
"unexpected ':', quote the value if it contains \": \""
| Bool
itemAfterKey -> [Char]
"unexpected '-', a list cannot start on the line of its key"
| Bool
itemAfterProperty ->
[Char]
"unexpected '-', a list cannot start on the line of its anchor or tag"
| Bool
itemAfterStartMarker ->
[Char]
"unexpected '-', a list cannot start on the line of '---'"
| Just [Char]
msg <- Env -> Bool -> Int -> Maybe [Char]
mistakeIn Env
e Bool
False Int
i -> [Char]
msg
| Just [Char]
node <- Maybe [Char]
endBefore -> Env -> Int -> [Char]
unexpectedChar Env
e Int
i [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" after the end of " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
node
| Bool
otherwise -> Env -> Int -> [Char]
unexpectedChar Env
e Int
i
e :: Env
e :: Env
e = Env -> Env
afterBoms Env
input
endBefore :: Maybe String
endBefore :: Maybe [Char]
endBefore
| Bool -> Bool
not (Word8 -> Bool
isNsChar (Env -> Int -> Word8
byteAt Env
e Int
i)) = Maybe [Char]
forall a. Maybe a
Nothing
| Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
RBRACKET Bool -> Bool -> Bool
|| Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
RBRACE = [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
"a flow collection"
| (Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
DQUOTE Bool -> Bool -> Bool
|| Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
SQUOTE) Bool -> Bool -> Bool
&& Int
j Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
i = [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
"a quoted scalar"
| Bool
otherwise = Maybe [Char]
forall a. Maybe a
Nothing
where
j :: Int
j :: Int
j = Env -> Int -> Int
skipBackWhites Env
e Int
i
b :: Word8
b :: Word8
b = Env -> Int -> Word8
byteBefore Env
e Int
j
afterComment :: Bool
afterComment :: Bool
afterComment =
Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Env -> Int -> Int
skipSpaces Env
e (Env -> Int -> Int
lineStartAt Env
e Int
i)
Bool -> Bool -> Bool
&& Word8 -> Bool
isNsChar (Env -> Int -> Word8
byteAt Env
e Int
i)
Bool -> Bool -> Bool
&& Bool -> Bool
not (Int -> Bool
isListItem Int
i)
Bool -> Bool -> Bool
&& Bool -> Bool
not ((Int -> Bool) -> [Int] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Int -> Bool
isKeyColon [Int
i .. Env -> Int -> Int
lineEndAt Env
e Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1])
Bool -> Bool -> Bool
&& Maybe [Char] -> Bool
forall a. Maybe a -> Bool
isNothing (Env -> Bool -> Int -> Maybe [Char]
mistakeIn Env
e Bool
False Int
i)
Bool -> Bool -> Bool
&& Int -> Bool
commentAbove (Env -> Int -> Int
lineStartAt Env
e Int
i)
Bool -> Bool -> Bool
&& Bool -> (Int -> Bool) -> Maybe Int -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
False Int -> Bool
endsPlain (Int -> Maybe Int
lineAbove (Env -> Int -> Int
lineStartAt Env
e Int
i))
where
endsPlain :: Int -> Bool
endsPlain :: Int -> Bool
endsPlain Int
k =
let end :: Int
end = Env -> Int -> Int
lineContentEnd Env
e Int
k
start :: Int
start = Env -> Int -> Int
wordStart Env
e Int
end
b :: Word8
b = Env -> Int -> Word8
byteBefore Env
e Int
end
w :: Word8
w = Env -> Int -> Word8
byteAt Env
e Int
start
in Int
end Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
k
Bool -> Bool -> Bool
&& Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
SQUOTE
Bool -> Bool -> Bool
&& Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
DQUOTE
Bool -> Bool -> Bool
&& Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
RBRACKET
Bool -> Bool -> Bool
&& Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
RBRACE
Bool -> Bool -> Bool
&& Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
COLON
Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
STAR
Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
AMP
Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
EXCL
Bool -> Bool -> Bool
&& Bool -> Bool
not (Int
end Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
start Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 Bool -> Bool -> Bool
&& (Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
MINUS Bool -> Bool -> Bool
|| Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
QUESTION))
Bool -> Bool -> Bool
&& Bool -> Bool
not (Int -> Bool
endsWithBlockHeader Int
k)
Bool -> Bool -> Bool
&& Bool -> Bool
not (Int -> Bool
inBlockScalar Int
k)
inBlockScalar :: Int -> Bool
inBlockScalar :: Int -> Bool
inBlockScalar Int
k = Int -> Bool
go Int
k
where
go :: Int -> Bool
go :: Int -> Bool
go Int
j = case Int -> Maybe Int
lineAbove (Env -> Int -> Int
lineStartAt Env
e Int
j) of
Maybe Int
Nothing -> Bool
False
Just Int
above
| Int -> Int
columnOf Int
above Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int -> Int
columnOf Int
k -> Int -> Bool
endsWithBlockHeader Int
above
| Bool
otherwise -> Int -> Bool
go Int
above
commentAbove :: Int -> Bool
commentAbove :: Int -> Bool
commentAbove Int
start
| Int
start Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Env
e.base = Bool
False
| Bool
otherwise =
let prev :: Int
prev = Env -> Int -> Int
lineStartAt Env
e (Int
start Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
k :: Int
k = Env -> Int -> Int
skipWhites Env
e (Env -> Int -> Int
skipBoms Env
e Int
prev)
in if Word8 -> Bool
isBreak (Env -> Int -> Word8
byteAt Env
e Int
k) then Int -> Bool
commentAbove Int
prev else Int -> Bool
hasComment Int
k
hasComment :: Int -> Bool
hasComment :: Int -> Bool
hasComment Int
j = case (Int -> Bool) -> [Int] -> Maybe Int
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
L.find Int -> Bool
startsComment [Int
j .. Int
end Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1] of
Just Int
h -> Bool -> Bool
not ((Int -> Bool) -> [Int] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Int -> Bool
closingQuote [Int
h Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 .. Int
end Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1])
Maybe Int
Nothing -> Bool
False
where
end :: Int
end :: Int
end = Env -> Int -> Int
lineEndAt Env
e Int
j
startsComment :: Int -> Bool
startsComment :: Int -> Bool
startsComment Int
k = Env -> Int -> Word8
byteAt Env
e Int
k Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
HASH Bool -> Bool -> Bool
&& (Int
k Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
j Bool -> Bool -> Bool
|| Word8 -> Bool
isWhite (Env -> Int -> Word8
byteBefore Env
e Int
k))
closingQuote :: Int -> Bool
closingQuote :: Int -> Bool
closingQuote Int
k =
let b :: Word8
b = Env -> Int -> Word8
byteAt Env
e Int
k in (Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
SQUOTE Bool -> Bool -> Bool
|| Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
DQUOTE) Bool -> Bool -> Bool
&& Env -> Int -> Bool
canEndFlowNode Env
e (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
propertiesLine :: Maybe Int
propertiesLine :: Maybe Int
propertiesLine =
let start :: Int
start = Env -> Int -> Int
skipSpaces Env
e (Env -> Int -> Int
lineStartAt Env
e Int
i)
in if Int -> Bool
onlyProperties Int
start then Int -> Maybe Int
forall a. a -> Maybe a
Just Int
start else Maybe Int
forall a. Maybe a
Nothing
where
onlyProperties :: Int -> Bool
onlyProperties :: Int -> Bool
onlyProperties Int
j =
let b :: Word8
b = Env -> Int -> Word8
byteAt Env
e Int
j
next :: Int
next = Env -> Int -> Int
skipWhites Env
e (Int -> Int
wordEnd Int
j)
b' :: Word8
b' = Env -> Int -> Word8
byteAt Env
e Int
next
in (Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
AMP Bool -> Bool -> Bool
|| Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
EXCL)
Bool -> Bool -> Bool
&& (Word8
b' Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0 Bool -> Bool -> Bool
|| Word8 -> Bool
isBreak Word8
b' Bool -> Bool -> Bool
|| Word8
b' Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
HASH Bool -> Bool -> Bool
|| Int -> Bool
onlyProperties Int
next)
wordEnd :: Int -> Int
wordEnd :: Int -> Int
wordEnd Int
j = if Word8 -> Bool
isNsChar (Env -> Int -> Word8
byteAt Env
e Int
j) then Int -> Int
wordEnd (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) else Int
j
multiLineKey :: Bool
multiLineKey :: Bool
multiLineKey =
Bool
multiLineCollection
Bool -> Bool -> Bool
|| Bool
firstColon Bool -> Bool -> Bool
&& (Env -> Int -> Word8
byteBefore Env
e Int
i Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
DQUOTE Bool -> Bool -> Bool
|| Env -> Int -> Word8
byteBefore Env
e Int
i Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
SQUOTE)
multiLineCollection :: Bool
multiLineCollection :: Bool
multiLineCollection =
let b :: Word8
b = Env -> Int -> Word8
byteBefore Env
e Int
i
in (Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
RBRACKET Bool -> Bool -> Bool
|| Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
RBRACE) Bool -> Bool -> Bool
&& Int -> Int -> Bool -> Bool
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2) Int
1 Bool
False
where
go :: Int -> Int -> Bool -> Bool
go :: Int -> Int -> Bool -> Bool
go Int
j Int
depth Bool
crossed
| Int
j Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Env
e.base = Bool
False
| Word8
c Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
RBRACKET Bool -> Bool -> Bool
|| Word8
c Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
RBRACE = Int -> Int -> Bool -> Bool
go (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (Int
depth Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Bool
crossed
| Word8
c Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
LBRACKET Bool -> Bool -> Bool
|| Word8
c Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
LBRACE =
if Int
depth Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 then Bool
crossed else Int -> Int -> Bool -> Bool
go (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (Int
depth Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Bool
crossed
| Bool
otherwise = Int -> Int -> Bool -> Bool
go (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Int
depth (Bool
crossed Bool -> Bool -> Bool
|| Word8 -> Bool
isBreak Word8
c)
where
c :: Word8
c :: Word8
c = Env -> Int -> Word8
byteAt Env
e Int
j
onStartMarkerLine :: Bool
onStartMarkerLine :: Bool
onStartMarkerLine = Env -> Int -> Bool
isStartMarker Env
e Int
markerStart
markerStart :: Int
markerStart :: Int
markerStart = Env -> Int -> Int
skipBoms Env
e (Env -> Int -> Int
lineStartAt Env
e Int
i)
entryStart :: Int
entryStart :: Int
entryStart = Int -> Int
skipListItems (Env -> Int -> Int
skipSpaces Env
e (Env -> Int -> Int
lineStartAt Env
e Int
i))
firstColon :: Bool
firstColon :: Bool
firstColon = Int -> Bool
firstColonFrom Int
entryStart
firstColonFrom :: Int -> Bool
firstColonFrom :: Int -> Bool
firstColonFrom Int
start = Int -> Int -> Bool
go Int
start Int
0
where
go :: Int -> Int -> Bool
go :: Int -> Int -> Bool
go Int
j Int
depth
| Int
j Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
i = Bool
True
| Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
LBRACKET Bool -> Bool -> Bool
|| Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
LBRACE = Int -> Int -> Bool
go (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (Int
depth Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
| Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
RBRACKET Bool -> Bool -> Bool
|| Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
RBRACE = Int -> Int -> Bool
go (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 (Int
depth Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1))
| Int
depth Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 Bool -> Bool -> Bool
&& Int -> Bool
isKeyColon Int
j = Bool
False
| Bool
otherwise = Int -> Int -> Bool
go (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int
depth
where
b :: Word8
b :: Word8
b = Env -> Int -> Word8
byteAt Env
e Int
j
itemAfterKey :: Bool
itemAfterKey :: Bool
itemAfterKey = Int -> Bool
isListItem Int
i Bool -> Bool -> Bool
&& Env -> Int -> Word8
byteBefore Env
e (Env -> Int -> Int
skipBackWhites Env
e Int
i) Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
COLON
itemAfterProperty :: Bool
itemAfterProperty :: Bool
itemAfterProperty =
let j :: Int
j = Env -> Int -> Int
skipBackWhites Env
e Int
i
b :: Word8
b = Env -> Int -> Word8
byteAt Env
e (Env -> Int -> Int
wordStart Env
e Int
j)
in Int -> Bool
isListItem Int
i Bool -> Bool -> Bool
&& Int
j Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
i Bool -> Bool -> Bool
&& (Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
AMP Bool -> Bool -> Bool
|| Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
EXCL)
itemAfterStartMarker :: Bool
itemAfterStartMarker :: Bool
itemAfterStartMarker =
Int -> Bool
isListItem Int
i
Bool -> Bool -> Bool
&& Bool
onStartMarkerLine
Bool -> Bool -> Bool
&& Env -> Int -> Int
skipBackWhites Env
e Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
markerStart Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
markerLength
valueColon :: Bool
valueColon :: Bool
valueColon =
Word8 -> Bool
isNsChar (Env -> Int -> Word8
byteBefore Env
e Int
i)
Bool -> Bool -> Bool
&& (let w :: Word8
w = Env -> Int -> Word8
byteAt Env
e (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) in Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0 Bool -> Bool -> Bool
|| Word8 -> Bool
isWhite Word8
w Bool -> Bool -> Bool
|| Word8 -> Bool
isBreak Word8
w)
indented :: Bool
indented :: Bool
indented = Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Env
e.base Bool -> Bool -> Bool
&& Env -> Int -> Word8
byteBefore Env
e Int
i Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
SPACE Bool -> Bool -> Bool
&& Int -> Bool
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
where
go :: Int -> Bool
go :: Int -> Bool
go Int
j
| Int
j Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Env
e.base = Bool
True
| Bool
otherwise = case Env -> Int -> Word8
byteBefore Env
e Int
j of
Word8
SPACE -> Int -> Bool
go (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
Word8
w -> Word8 -> Bool
isBreak Word8
w
alignedWithEntry :: Bool
alignedWithEntry :: Bool
alignedWithEntry = case Int -> Int -> Maybe Int
entryAbove (Int -> Int
columnOf Int
i) (Env -> Int -> Int
lineStartAt Env
e Int
i) of
Just Int
k -> Int -> Bool
isListItem Int
k Bool -> Bool -> Bool
|| (Int -> Bool) -> [Int] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Int -> Bool
isKeyColon [Int
k .. Env -> Int -> Int
lineContentEnd Env
e Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1]
Maybe Int
Nothing -> Bool
False
lineStart :: Int
lineStart :: Int
lineStart = Env -> Int -> Int
lineStartAt Env
e Int
i
contentStart :: Int
contentStart :: Int
contentStart = Int -> Int
go Int
lineStart
where
go :: Int -> Int
go :: Int -> Int
go Int
j =
let k :: Int
k = Env -> Int -> Int
skipWhites Env
e Int
j
in if Int -> Bool
isBlockIndicator Int
k then Int -> Int
go (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) else Int
k
indentationTab :: Int -> Maybe Int -> Maybe Int
indentationTab :: Int -> Maybe Int -> Maybe Int
indentationTab Int
j Maybe Int
tab
| Int
j Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Env
e.base = Maybe Int
tab'
| Int -> Bool
isBlockIndicator Int
j = Int -> Maybe Int -> Maybe Int
indentationTab (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Maybe Int
tab
| Bool
otherwise = case Array -> Int -> Word8
A.unsafeIndex Env
e.array Int
j of
Word8
SPACE -> Int -> Maybe Int -> Maybe Int
indentationTab (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Maybe Int
tab
Word8
TAB -> Int -> Maybe Int -> Maybe Int
indentationTab (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
j)
Word8
w
| Word8 -> Bool
isBreak Word8
w -> Maybe Int
tab'
| Bool
otherwise -> Maybe Int
forall a. Maybe a
Nothing
where
tab' :: Maybe Int
tab' :: Maybe Int
tab' = if Env -> Int -> Word8
byteAt Env
e Int
i Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
TAB then Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
i Maybe Int
tab) else Maybe Int
tab
isBlockIndicator :: Int -> Bool
isBlockIndicator :: Int -> Bool
isBlockIndicator Int
j =
let w :: Word8
w = Env -> Int -> Word8
byteAt Env
e Int
j
in (Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
MINUS Bool -> Bool -> Bool
|| Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
QUESTION Bool -> Bool -> Bool
|| Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
COLON) Bool -> Bool -> Bool
&& Word8 -> Bool
isWhite (Env -> Int -> Word8
byteAt Env
e (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))
blockMistake :: Maybe (Int, String)
blockMistake :: Maybe (Int, [Char])
blockMistake = do
Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ Int
start Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
stop
k <- Int -> Int -> Maybe Int
entryAbove Int
column (Env -> Int -> Int
lineStartAt Env
e Int
stop)
if
| isListItem k && byteAt e start == MINUS && stop == start + 1 ->
Just (stop, "expected a space after '-'")
| not (isListItem k)
&& (w == 0 || isBreak w || stop < i)
&& not (any isKeyColon [afterKey .. stop - 1]) ->
Just $ case (keyEnd, filter tightColon [afterKey .. stop - 1]) of
(Maybe Int
Nothing, [Int]
_) -> (Int
start, [Char]
"unterminated " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
quotedName [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" scalar")
(Just Int
end, [Int]
_) | Int
end Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
stop -> (Int
stop, [Char]
"a key must be on a single line")
(Maybe Int
_, Int
colon : [Int]
_) -> (Int
colon Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1, [Char]
"expected a space after ':'")
(Maybe Int
_, []) -> (Int
stop, [Char]
"expected ':' after the key")
| otherwise -> Nothing
where
stop :: Int
stop :: Int
stop
| Env -> Int -> Word8
byteAt Env
e Int
i Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
HASH Bool -> Bool -> Bool
&& Word8 -> Bool
isWhite (Env -> Int -> Word8
byteBefore Env
e Int
i) = Env -> Int -> Int
skipBackWhites Env
e Int
i
| Bool
otherwise = Int
i
keyEnd :: Maybe Int
keyEnd :: Maybe Int
keyEnd
| Word8
quote Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
DQUOTE Bool -> Bool -> Bool
|| Word8
quote Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
SQUOTE = Int -> Maybe Int
closing (Int
start Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
| Bool
otherwise = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
start
where
closing :: Int -> Maybe Int
closing :: Int -> Maybe Int
closing Int
j
| Int
j Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Env
e.end = Maybe Int
forall a. Maybe a
Nothing
| Word8
quote Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
SQUOTE Bool -> Bool -> Bool
&& Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
SQUOTE Bool -> Bool -> Bool
&& Env -> Int -> Word8
byteAt Env
e (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
SQUOTE =
Int -> Maybe Int
closing (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2)
| Word8
quote Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
DQUOTE Bool -> Bool -> Bool
&& Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
BACKSLASH = Int -> Maybe Int
closing (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2)
| Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
quote = Int -> Maybe Int
forall a. a -> Maybe a
Just (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
| Bool
otherwise = Int -> Maybe Int
closing (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
where
b :: Word8
b :: Word8
b = Env -> Int -> Word8
byteAt Env
e Int
j
afterKey :: Int
afterKey :: Int
afterKey = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
stop Maybe Int
keyEnd
quote :: Word8
quote :: Word8
quote = Env -> Int -> Word8
byteAt Env
e Int
start
quotedName :: String
quotedName :: [Char]
quotedName = if Word8
quote Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
DQUOTE then [Char]
"double-quoted" else [Char]
"single-quoted"
w :: Word8
w :: Word8
w = Env -> Int -> Word8
byteAt Env
e Int
stop
start :: Int
start :: Int
start = Env -> Int -> Int
skipSpaces Env
e (Env -> Int -> Int
lineStartAt Env
e Int
stop)
column :: Int
column :: Int
column = Int
start Int -> Int -> Int
forall a. Num a => a -> a -> a
- Env -> Int -> Int
lineStartAt Env
e Int
stop
tightColon :: Int -> Bool
tightColon :: Int -> Bool
tightColon Int
j = Env -> Int -> Word8
byteAt Env
e Int
j Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
COLON Bool -> Bool -> Bool
&& Word8 -> Bool
startsWord (Env -> Int -> Word8
byteAt Env
e (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))
startsWord :: Word8 -> Bool
startsWord :: Word8 -> Bool
startsWord Word8
b =
(Word8 -> Bool
isAsciiByte Word8
b Bool -> Bool -> Bool
&& Char -> Bool
isAlphaNum (Int -> Char
chr (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b)))
Bool -> Bool -> Bool
|| Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
SQUOTE
Bool -> Bool -> Bool
|| Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
DQUOTE
Bool -> Bool -> Bool
|| Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
LBRACKET
Bool -> Bool -> Bool
|| Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
LBRACE
entryAbove :: Int -> Int -> Maybe Int
entryAbove :: Int -> Int -> Maybe Int
entryAbove Int
column Int
from = do
k <- Int -> Maybe Int
lineAbove Int
from
let indent = Int -> Int
columnOf Int
k
entry = Int -> Int
skipListItems Int
k
if
| indent == column -> Just k
| columnOf entry == column -> Just entry
| indent < column -> Nothing
| otherwise -> entryAbove column (lineStartAt e k)
indentationMistake :: Maybe String
indentationMistake :: Maybe [Char]
indentationMistake = Int -> Maybe [Char]
go (Env -> Int -> Int
lineStartAt Env
e Int
i)
where
column :: Int
column :: Int
column = Int -> Int
columnOf Int
i
go :: Int -> Maybe String
go :: Int -> Maybe [Char]
go Int
start = do
k <- Int -> Maybe Int
lineAbove Int
start
let indent = Int -> Int
columnOf Int
k
if
| indent > column -> go (lineStartAt e k)
| indent < column ->
if endsWithBlockHeader k
then
Just
"unexpected indentation, the line has less indentation than the block scalar above it"
else Nothing
| isListItem k && not (isListItem i) && not (isFlowIndicator (byteAt e i)) ->
Just $
if hasKey i
then "unexpected key among list items"
else "unexpected value among list items"
| not (isListItem k) && isListItem i ->
Just "unexpected list item among mapping entries"
| otherwise -> Nothing
endsWithBlockHeader :: Int -> Bool
endsWithBlockHeader :: Int -> Bool
endsWithBlockHeader Int
k =
let h :: Int
h = Int -> Int
skipIndicators (Env -> Int -> Int
lineContentEnd Env
e Int
k)
in Int
h Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
k
Bool -> Bool -> Bool
&& (let b :: Word8
b = Env -> Int -> Word8
byteAt Env
e (Int
h Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) in Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
PIPE Bool -> Bool -> Bool
|| Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
GREATER)
Bool -> Bool -> Bool
&& (Int
h Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
k Bool -> Bool -> Bool
|| Word8 -> Bool
isWhite (Env -> Int -> Word8
byteAt Env
e (Int
h Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2)))
where
skipIndicators :: Int -> Int
skipIndicators :: Int -> Int
skipIndicators Int
j =
let b :: Word8
b = Env -> Int -> Word8
byteBefore Env
e Int
j
in if Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
MINUS Bool -> Bool -> Bool
|| Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
PLUS Bool -> Bool -> Bool
|| Word8 -> Bool
isDecDigit Word8
b then Int -> Int
skipIndicators (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) else Int
j
lineAbove :: Int -> Maybe Int
lineAbove :: Int -> Maybe Int
lineAbove Int
start = Env -> Int -> Int
skipSpaces Env
e (Int -> Int) -> (Int -> Int) -> Int -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Env -> Int -> Int
skipBoms Env
e (Int -> Int) -> Maybe Int -> Maybe Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Env -> Int -> Maybe Int
contentLineAbove Env
e Int
start
columnOf :: Int -> Int
columnOf :: Int -> Int
columnOf Int
j = Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- Env -> Int -> Int
skipBoms Env
e (Env -> Int -> Int
lineStartAt Env
e Int
j)
skipListItems :: Int -> Int
skipListItems :: Int -> Int
skipListItems Int
j = if Int -> Bool
isListItem Int
j then Int -> Int
skipListItems (Env -> Int -> Int
skipWhites Env
e (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)) else Int
j
isKeyColon :: Int -> Bool
isKeyColon :: Int -> Bool
isKeyColon Int
j =
Env -> Int -> Word8
byteAt Env
e Int
j Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
COLON
Bool -> Bool -> Bool
&& (let b :: Word8
b = Env -> Int -> Word8
byteAt Env
e (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) in Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0 Bool -> Bool -> Bool
|| Word8 -> Bool
isWhite Word8
b Bool -> Bool -> Bool
|| Word8 -> Bool
isBreak Word8
b)
hasKey :: Int -> Bool
hasKey :: Int -> Bool
hasKey Int
j =
(Env -> Int -> Word8
byteAt Env
e Int
j Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
QUESTION Bool -> Bool -> Bool
&& (let b :: Word8
b = Env -> Int -> Word8
byteAt Env
e (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) in Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0 Bool -> Bool -> Bool
|| Word8 -> Bool
isWhite Word8
b Bool -> Bool -> Bool
|| Word8 -> Bool
isBreak Word8
b))
Bool -> Bool -> Bool
|| (Int -> Bool) -> [Int] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Int -> Bool
isKeyColon [Int
j .. Env -> Int -> Int
lineContentEnd Env
e Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1]
isListItem :: Int -> Bool
isListItem :: Int -> Bool
isListItem Int
j =
Env -> Int -> Word8
byteAt Env
e Int
j Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
MINUS
Bool -> Bool -> Bool
&& (let b :: Word8
b = Env -> Int -> Word8
byteAt Env
e (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) in Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0 Bool -> Bool -> Bool
|| Word8 -> Bool
isWhite Word8
b Bool -> Bool -> Bool
|| Word8 -> Bool
isBreak Word8
b)
aliasColon :: Env -> Int -> Maybe Int
aliasColon :: Env -> Int -> Maybe Int
aliasColon Env
e Int
i =
let j :: Int
j = Env -> Int -> Int
skipBackWhites Env
e Int
i
start :: Int
start = Env -> Int -> Int
wordStart Env
e Int
j
in if Int
j Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
start Bool -> Bool -> Bool
&& Env -> Int -> Word8
byteBefore Env
e Int
j Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
COLON Bool -> Bool -> Bool
&& Env -> Int -> Word8
byteAt Env
e Int
start Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
STAR
then Int -> Maybe Int
forall a. a -> Maybe a
Just (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
else Maybe Int
forall a. Maybe a
Nothing
aliasColonMessage :: String
aliasColonMessage :: [Char]
aliasColonMessage =
[Char]
"the name of the alias includes the ':', write a space before ':' if the alias is a key"
flowError :: Env -> Int -> String -> (Int, String)
flowError :: Env -> Int -> [Char] -> (Int, [Char])
flowError Env
e Int
i [Char]
msg = case Env -> Int -> Maybe Int
aliasColon Env
e Int
i of
Just Int
colon -> (Int
colon, [Char]
aliasColonMessage)
Maybe Int
Nothing -> (Int
i, [Char] -> Maybe [Char] -> [Char]
forall a. a -> Maybe a -> a
fromMaybe [Char]
msg (Env -> Bool -> Int -> Maybe [Char]
mistakeIn (Env -> Env
afterBoms Env
e) Bool
True Int
i))
afterBoms :: Env -> Env
afterBoms :: Env -> Env
afterBoms Env
e = Env
e {base = skipBoms e e.base}
mistakeIn :: Env -> Bool -> Int -> Maybe String
mistakeIn :: Env -> Bool -> Int -> Maybe [Char]
mistakeIn Env
e Bool
flow Int
i
| Env -> Int -> Bool
isBom Env
e Int
i = [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
"unexpected byte order mark"
| Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
HASH Bool -> Bool -> Bool
&& Word8 -> Bool
isNsChar (Env -> Int -> Word8
byteBefore Env
e Int
i) =
[Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
"unexpected '#', a comment needs a space before it"
| Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
COMMA
Bool -> Bool -> Bool
&& ( let b :: Word8
b = Env -> Int -> Word8
byteBefore Env
e (Int -> Int
skipBack Int
i)
in Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
COMMA Bool -> Bool -> Bool
|| Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
LBRACKET Bool -> Bool -> Bool
|| Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
LBRACE
) =
[Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
"unexpected ',', a flow collection cannot have an empty entry"
| Bool
flow Bool -> Bool -> Bool
&& (Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
PIPE Bool -> Bool -> Bool
|| Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
GREATER) =
[Char] -> Maybe [Char]
forall a. a -> Maybe a
Just ([Char] -> Maybe [Char]) -> [Char] -> Maybe [Char]
forall a b. (a -> b) -> a -> b
$ Env -> Int -> [Char]
unexpectedChar Env
e Int
i [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
", a block scalar cannot be inside a flow collection"
| Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
STAR Bool -> Bool -> Bool
&& Bool -> Bool
not (Word8 -> Bool
isAnchorChar (Env -> Int -> Word8
byteAt Env
e (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))) =
[Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
"expected an alias name after '*'"
| Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
STAR
Bool -> Bool -> Bool
&& (let b :: Word8
b = Env -> Int -> Word8
byteAt Env
e (Env -> Int -> Int
wordStart Env
e (Env -> Int -> Int
skipBackWhites Env
e Int
i)) in Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
AMP Bool -> Bool -> Bool
|| Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
EXCL) =
[Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
"unexpected '*', an alias cannot have an anchor or a tag"
| Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
AMP Bool -> Bool -> Bool
&& Bool -> Bool
not (Word8 -> Bool
isAnchorChar (Env -> Int -> Word8
byteAt Env
e (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))) =
[Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
"expected an anchor name after '&'"
| Word8 -> Bool
afterQuote Word8
SQUOTE =
[Char] -> Maybe [Char]
forall a. a -> Maybe a
Just ([Char] -> Maybe [Char]) -> [Char] -> Maybe [Char]
forall a b. (a -> b) -> a -> b
$
Env -> Int -> [Char]
unexpectedChar Env
e Int
i
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" after a single-quoted scalar, write '' for a quote inside it"
| Word8 -> Bool
afterQuote Word8
DQUOTE =
[Char] -> Maybe [Char]
forall a. a -> Maybe a
Just ([Char] -> Maybe [Char]) -> [Char] -> Maybe [Char]
forall a b. (a -> b) -> a -> b
$
Env -> Int -> [Char]
unexpectedChar Env
e Int
i
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" after a double-quoted scalar, write \\\" for a quote inside it"
| Bool -> Bool
not Bool
flow Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
PERCENT Bool -> Bool -> Bool
&& Env -> Int -> Bool
isStartOfLine Env
e Int
i Bool -> Bool -> Bool
&& Word8 -> Bool
isNsChar (Env -> Int -> Word8
byteAt Env
e (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)) =
[Char] -> Maybe [Char]
forall a. a -> Maybe a
Just
[Char]
"unexpected '%', a directive needs '...' on a line above it to end the document"
| Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
AT Bool -> Bool -> Bool
|| Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
GRAVE Bool -> Bool -> Bool
|| Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
PERCENT =
[Char] -> Maybe [Char]
forall a. a -> Maybe a
Just ([Char] -> Maybe [Char]) -> [Char] -> Maybe [Char]
forall a b. (a -> b) -> a -> b
$
Env -> Int -> [Char]
unexpectedChar Env
e Int
i [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
", a plain scalar cannot start with it, quote the value"
| Bool
otherwise = Maybe [Char]
forall a. Maybe a
Nothing
where
w :: Word8
w :: Word8
w = Env -> Int -> Word8
byteAt Env
e Int
i
skipBack :: Int -> Int
skipBack :: Int -> Int
skipBack Int
j
| Word8 -> Bool
isWhite (Env -> Int -> Word8
byteBefore Env
e Int
j) Bool -> Bool -> Bool
|| Word8 -> Bool
isBreak (Env -> Int -> Word8
byteBefore Env
e Int
j) = Int -> Int
skipBack (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
| Bool
otherwise = Int
j
afterQuote :: Word8 -> Bool
afterQuote :: Word8 -> Bool
afterQuote Word8
q =
Env -> Int -> Word8
byteBefore Env
e Int
i Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
q
Bool -> Bool -> Bool
&& Word8 -> Bool
isNsChar Word8
w
Bool -> Bool -> Bool
&& Bool -> Bool
not (Word8 -> Bool
isFlowIndicator Word8
w)
Bool -> Bool -> Bool
&& Word8
w Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
COLON
Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
quoteInTag
quoteInTag :: Bool
quoteInTag :: Bool
quoteInTag = Env -> Int -> Word8
byteBefore Env
e (Int -> Int
tagStart Int
i) Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
EXCL
where
tagStart :: Int -> Int
tagStart :: Int -> Int
tagStart Int
j = if Word8 -> Bool
isTagChar (Env -> Int -> Word8
byteBefore Env
e Int
j) then Int -> Int
tagStart (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) else Int
j
lineContentEnd :: Env -> Int -> Int
lineContentEnd :: Env -> Int -> Int
lineContentEnd Env
e = Env -> Int -> Int
skipBackWhites Env
e (Int -> Int) -> (Int -> Int) -> Int -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Int
go
where
go :: Int -> Int
go :: Int -> Int
go Int
j
| Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0 Bool -> Bool -> Bool
|| Word8 -> Bool
isBreak Word8
b = Int
j
| Word8
b Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
HASH Bool -> Bool -> Bool
&& Word8 -> Bool
isWhite (Env -> Int -> Word8
byteBefore Env
e Int
j) = Int
j
| Bool
otherwise = Int -> Int
go (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
where
b :: Word8
b :: Word8
b = Env -> Int -> Word8
byteAt Env
e Int
j
skipBackWhites :: Env -> Int -> Int
skipBackWhites :: Env -> Int -> Int
skipBackWhites Env
e Int
i = if Word8 -> Bool
isWhite (Env -> Int -> Word8
byteBefore Env
e Int
i) then Env -> Int -> Int
skipBackWhites Env
e (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) else Int
i
wordStart :: Env -> Int -> Int
wordStart :: Env -> Int -> Int
wordStart Env
e Int
i = if Word8 -> Bool
isAnchorChar (Env -> Int -> Word8
byteBefore Env
e Int
i) then Env -> Int -> Int
wordStart Env
e (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) else Int
i
unexpectedChar :: Env -> Int -> String
unexpectedChar :: Env -> Int -> [Char]
unexpectedChar Env
e Int
i
| Word8 -> Bool
isAsciiByte Word8
w = [Char]
"unexpected " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Char -> [Char]
forall a. Show a => a -> [Char]
show (Int -> Char
chr (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
w))
| Char -> Bool
isPrint Char
c = [Char]
"unexpected '" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char
c] [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"'"
| Bool
otherwise = [Char]
"unexpected " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Char -> [Char]
codePointName Char
c
where
w :: Word8
w :: Word8
w = Env -> Int -> Word8
byteAt Env
e Int
i
c :: Char
c :: Char
c = HasCallStack => Text -> Char
Text -> Char
T.head (Env -> Int -> Int -> Text
slice Env
e Int
i Env
e.end)
firstTab :: Env -> Int -> Int -> Maybe Int
firstTab :: Env -> Int -> Int -> Maybe Int
firstTab Env
e Int
i Int
j = (Int -> Bool) -> [Int] -> Maybe Int
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
L.find (\Int
k -> Env -> Int -> Word8
byteAt Env
e Int
k Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
TAB) [Int
i .. Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1]
tabMessage :: String
tabMessage :: [Char]
tabMessage = [Char]
"tabs cannot be used for indentation"
keyLengthMessage :: String
keyLengthMessage :: [Char]
keyLengthMessage =
[Char]
"a key can be at most "
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
maxImplicitKeyLength
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" characters long, write a longer key after '? '"
codePointName :: Char -> String
codePointName :: Char -> [Char]
codePointName Char
c =
let hex :: [Char]
hex = (Char -> Char) -> [Char] -> [Char]
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toUpper (Int -> [Char] -> [Char]
forall a. Integral a => a -> [Char] -> [Char]
showHex (Char -> Int
ord Char
c) [Char]
"")
in [Char]
"U+" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> Char -> [Char]
forall a. Int -> a -> [a]
replicate (Int
4 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]
hex) Char
'0' [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
hex