{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeFamilies #-}
module Data.XML.Parser.High.NameParser
( NameParser(..)
, anyName
, anyNameExcept
) where
import Control.Applicative
import Control.Arrow
import Control.Monad.Compat
import Control.Monad.Fail.Compat
import Data.String
import Data.XML.Parser.Low
import Prelude.Compat
newtype NameParser a = NameParser { runNameParser :: QName -> Either String a }
deriving instance Functor NameParser
deriving via (WrappedArrow (Kleisli (Either String)) QName) instance Applicative NameParser
deriving via (WrappedArrow (Kleisli (Either String)) QName) instance Alternative NameParser
instance (a ~ ()) => IsString (NameParser a) where
fromString s = anyName >>= \(QName _ name) ->
when (fromString s /= name) $ fail $ "Expected tag named " <> show s <> ", instead got: " <> show name
instance Monad NameParser where
(NameParser f) >>= g = NameParser $ \name -> do
a <- f name
let NameParser g' = g a
g' name
instance MonadFail NameParser where
fail message = NameParser $ const $ Left message
anyName :: NameParser QName
anyName = NameParser Right
anyNameExcept :: QName -> NameParser QName
anyNameExcept name = NameParser $ \name' -> if name == name'
then Left $ "Expected any tag name except " <> show name
else Right name'