{-# OPTIONS_GHC -Wno-orphans #-} module YAML (module YAML, module Data.YAML, untagged) where import Data.ByteString (ByteString) import Data.ByteString.Char8 qualified as BS8 import Data.ByteString.Lazy qualified as LazyBS import Data.Text (Text) import Data.Text qualified as Text import Data.YAML import Data.YAML.Event (untagged) import Misc import System.IO qualified as IO str' :: String -> Node () str' = str . Text.pack str :: Text -> Node () str = Scalar () . SStr obj :: Mapping () -> Node () obj = Mapping () untagged (##=) :: (ToYAML b) => Text -> b -> (Node (), Node ()) (##=) = (#=) (#=) :: (ToYAML a, ToYAML b) => a -> b -> (Node (), Node ()) k #= v = (toYAML k, toYAML v) list :: ToYAML a => [a] -> Node () list = Sequence () untagged . map toYAML -- | read a chunk from the beginning of the file between a -- @---@ and a @...@. throw an exception if there isn't one readHeader :: FilePath -> IO (Node Pos) readHeader file = IO.withFile file IO.ReadMode \h -> do ln <- BS8.hGetLine h if (ln /= "---") then fail $ file <> ": no header" else unwrap file . decode1 =<< linesUntil "..." h -- | read all the lines from a handle until the given terminator. return the -- lines read, excluding the terminator linesUntil :: ByteString -> IO.Handle -> IO LazyBS.ByteString linesUntil end h = go [] where go acc = do l <- BS8.hGetLine h if l == end then return $ LazyBS.fromChunks $ reverse acc else go ("\n" : l : acc) instance FromYAML IsoDate where parseYAML = withStr "iso date" parseIsoDate