{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE StandaloneDeriving #-}
module Data.XML.Parser.High.AttrParser
( AttrParser(..)
, anyAttr
, noAttr
, attrValue
, hasAttr
) where
import Control.Applicative
import Control.Arrow
import Control.Monad.Compat
import Control.Monad.Fail.Compat
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Text (Text)
import qualified Data.Text as Text
import Data.XML.Parser.Low.Name
import Prelude.Compat
newtype AttrParser a = AttrParser { runAttrParser :: Map QName Text -> Either String a }
deriving instance Functor AttrParser
deriving via (WrappedArrow (Kleisli (Either String)) (Map QName Text)) instance Applicative AttrParser
deriving via (WrappedArrow (Kleisli (Either String)) (Map QName Text)) instance Alternative AttrParser
instance Monad AttrParser where
(AttrParser f) >>= g = AttrParser $ \attributes -> do
a <- f attributes
let AttrParser g' = g a
g' attributes
instance MonadFail AttrParser where
fail message = AttrParser $ const $ Left message
anyAttr :: AttrParser ()
anyAttr = pure ()
noAttr :: AttrParser ()
noAttr = AttrParser $ \attributes -> if null attributes then Right () else Left $ "Expected no attribute, instead got: " <> show attributes
attrValue :: QName -> AttrParser Text
attrValue name = AttrParser $ maybe (Left $ "Missing attribute named " <> show name) Right . Map.lookup name
hasAttr :: QName -> Text -> AttrParser ()
hasAttr name value = attrValue name >>= \value' -> if value == value' then pure () else fail $ "Expected attribute value " <> Text.unpack value <> ", instead got: " <> Text.unpack value'