module Text.XML.DOM.Parser.FromDom
  ( -- * FromDom
    FromDom(..)
  , proxyFromDom
    -- * Explicit methods for convenience
  , elementFromDom
  , textFromDom
  , stringFromDom
  , charFromDom
  , intFromDom
  , integerFromDom
  , doubleFromDom
  , fixedFromDom
  , boolFromDom
  , unitFromDom
  , voidFromDom
  , scientificFromDom
  ) where

import Control.Applicative
import Control.Lens
import Data.Fixed
import Data.Scientific
import Data.Text as T hiding (empty)
import Data.Typeable
import Data.Void
import Text.XML
import Text.XML.DOM.Parser.Content
import Text.XML.DOM.Parser.Types

proxyFromDom
  :: forall proxy m a
   . (FromDom a, Monad m)
  => proxy a
  -> DomParserT Identity m a
proxyFromDom :: forall (proxy :: * -> *) (m :: * -> *) a.
(FromDom a, Monad m) =>
proxy a -> DomParserT Identity m a
proxyFromDom proxy a
_ = DomParserT Identity m a
forall a (m :: * -> *).
(FromDom a, Monad m) =>
DomParserT Identity m a
forall (m :: * -> *). Monad m => DomParserT Identity m a
fromDom

-- | Class of types which can be parsed from single XML element. The
-- method 'fromDom' is convenient default to use with 'inElem'
class FromDom a where
  fromDom :: (Monad m) => DomParserT Identity m a

instance FromDom () where
  fromDom :: forall (m :: * -> *). Monad m => DomParserT Identity m ()
fromDom = DomParserT Identity m ()
forall (m :: * -> *). Monad m => DomParserT Identity m ()
unitFromDom

-- | Always successfully parses any DOM to @()@
unitFromDom :: (Monad m) => DomParserT Identity m  ()
unitFromDom :: forall (m :: * -> *). Monad m => DomParserT Identity m ()
unitFromDom = () -> ReaderT (ParserData Identity) (ExceptT ParserErrors m) ()
forall a.
a -> ReaderT (ParserData Identity) (ExceptT ParserErrors m) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

instance FromDom Void where
  fromDom :: forall (m :: * -> *). Monad m => DomParserT Identity m Void
fromDom = DomParserT Identity m Void
forall (m :: * -> *). Monad m => DomParserT Identity m Void
voidFromDom

-- | Never parses successfully. It is just 'empty'
voidFromDom :: (Monad m) => DomParserT Identity m  Void
voidFromDom :: forall (m :: * -> *). Monad m => DomParserT Identity m Void
voidFromDom = ReaderT (ParserData Identity) (ExceptT ParserErrors m) Void
forall a. ReaderT (ParserData Identity) (ExceptT ParserErrors m) a
forall (f :: * -> *) a. Alternative f => f a
empty

instance FromDom Text where
  fromDom :: forall (m :: * -> *). Monad m => DomParserT Identity m Text
fromDom = DomParserT Identity m Text
forall (m :: * -> *). Monad m => DomParserT Identity m Text
textFromDom

textFromDom :: (Monad m) => DomParserT Identity m Text
textFromDom :: forall (m :: * -> *). Monad m => DomParserT Identity m Text
textFromDom = (Text -> Either Text Text) -> DomParserT Identity m Text
forall (m :: * -> *) a.
Monad m =>
(Text -> Either Text a) -> DomParserT Identity m a
parseContent Text -> Either Text Text
forall a b. b -> Either a b
Right

instance FromDom String where
  fromDom :: forall (m :: * -> *). Monad m => DomParserT Identity m String
fromDom = DomParserT Identity m String
forall (m :: * -> *). Monad m => DomParserT Identity m String
stringFromDom

stringFromDom :: (Monad m) => DomParserT Identity m String
stringFromDom :: forall (m :: * -> *). Monad m => DomParserT Identity m String
stringFromDom = (Text -> Either Text String) -> DomParserT Identity m String
forall (m :: * -> *) a.
Monad m =>
(Text -> Either Text a) -> DomParserT Identity m a
parseContent ((Text -> Either Text String) -> DomParserT Identity m String)
-> (Text -> Either Text String) -> DomParserT Identity m String
forall a b. (a -> b) -> a -> b
$ String -> Either Text String
forall a b. b -> Either a b
Right (String -> Either Text String)
-> (Text -> String) -> Text -> Either Text String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack

instance FromDom Char where
  fromDom :: forall (m :: * -> *). Monad m => DomParserT Identity m Char
fromDom = DomParserT Identity m Char
forall (m :: * -> *). Monad m => DomParserT Identity m Char
charFromDom

charFromDom :: (Monad m) => DomParserT Identity m Char
charFromDom :: forall (m :: * -> *). Monad m => DomParserT Identity m Char
charFromDom = (Text -> Either Text Char) -> DomParserT Identity m Char
forall (m :: * -> *) a.
Monad m =>
(Text -> Either Text a) -> DomParserT Identity m a
parseContent Text -> Either Text Char
readChar

instance FromDom Int where
  fromDom :: forall (m :: * -> *). Monad m => DomParserT Identity m Int
fromDom = DomParserT Identity m Int
forall (m :: * -> *). Monad m => DomParserT Identity m Int
intFromDom

intFromDom :: (Monad m) => DomParserT Identity m Int
intFromDom :: forall (m :: * -> *). Monad m => DomParserT Identity m Int
intFromDom = (Text -> Either Text Int) -> DomParserT Identity m Int
forall (m :: * -> *) a.
Monad m =>
(Text -> Either Text a) -> DomParserT Identity m a
parseContent Text -> Either Text Int
forall a. (Read a, Typeable a) => Text -> Either Text a
readContent

instance FromDom Integer where
  fromDom :: forall (m :: * -> *). Monad m => DomParserT Identity m Integer
fromDom = DomParserT Identity m Integer
forall (m :: * -> *). Monad m => DomParserT Identity m Integer
integerFromDom

integerFromDom :: (Monad m) => DomParserT Identity m Integer
integerFromDom :: forall (m :: * -> *). Monad m => DomParserT Identity m Integer
integerFromDom = (Text -> Either Text Integer) -> DomParserT Identity m Integer
forall (m :: * -> *) a.
Monad m =>
(Text -> Either Text a) -> DomParserT Identity m a
parseContent Text -> Either Text Integer
forall a. (Read a, Typeable a) => Text -> Either Text a
readContent

instance FromDom Double where
  fromDom :: forall (m :: * -> *). Monad m => DomParserT Identity m Double
fromDom = DomParserT Identity m Double
forall (m :: * -> *). Monad m => DomParserT Identity m Double
doubleFromDom

doubleFromDom :: (Monad m) => DomParserT Identity m Double
doubleFromDom :: forall (m :: * -> *). Monad m => DomParserT Identity m Double
doubleFromDom = (Text -> Either Text Double) -> DomParserT Identity m Double
forall (m :: * -> *) a.
Monad m =>
(Text -> Either Text a) -> DomParserT Identity m a
parseContent Text -> Either Text Double
forall a. (Read a, Typeable a) => Text -> Either Text a
readContent

instance (HasResolution a, Typeable a) => FromDom (Fixed a) where
  fromDom :: forall (m :: * -> *). Monad m => DomParserT Identity m (Fixed a)
fromDom = DomParserT Identity m (Fixed a)
forall (m :: * -> *) a.
(Monad m, Typeable a, HasResolution a) =>
DomParserT Identity m (Fixed a)
fixedFromDom

fixedFromDom
  :: (Monad m, Typeable a, HasResolution a)
  => DomParserT Identity m (Fixed a)
fixedFromDom :: forall (m :: * -> *) a.
(Monad m, Typeable a, HasResolution a) =>
DomParserT Identity m (Fixed a)
fixedFromDom = (Text -> Either Text (Fixed a)) -> DomParserT Identity m (Fixed a)
forall (m :: * -> *) a.
Monad m =>
(Text -> Either Text a) -> DomParserT Identity m a
parseContent Text -> Either Text (Fixed a)
forall a. (Read a, Typeable a) => Text -> Either Text a
readContent

instance FromDom Scientific where
  fromDom :: forall (m :: * -> *). Monad m => DomParserT Identity m Scientific
fromDom = DomParserT Identity m Scientific
forall (m :: * -> *). Monad m => DomParserT Identity m Scientific
scientificFromDom

scientificFromDom :: Monad m => DomParserT Identity m Scientific
scientificFromDom :: forall (m :: * -> *). Monad m => DomParserT Identity m Scientific
scientificFromDom = (Text -> Either Text Scientific)
-> DomParserT Identity m Scientific
forall (m :: * -> *) a.
Monad m =>
(Text -> Either Text a) -> DomParserT Identity m a
parseContent Text -> Either Text Scientific
forall a. (Read a, Typeable a) => Text -> Either Text a
readContent

instance FromDom Bool where
  fromDom :: forall (m :: * -> *). Monad m => DomParserT Identity m Bool
fromDom = DomParserT Identity m Bool
forall (m :: * -> *). Monad m => DomParserT Identity m Bool
boolFromDom

-- | Expects content to be y, yes, t, true or 1 for True Values n, no,
-- f, false or 0 for False. Case is not significant, blank characters
-- are striped.
boolFromDom :: (Monad m) => DomParserT Identity m Bool
boolFromDom :: forall (m :: * -> *). Monad m => DomParserT Identity m Bool
boolFromDom = (Text -> Either Text Bool) -> DomParserT Identity m Bool
forall (m :: * -> *) a.
Monad m =>
(Text -> Either Text a) -> DomParserT Identity m a
parseContent Text -> Either Text Bool
readBool

instance FromDom Element where
  fromDom :: forall (m :: * -> *). Monad m => DomParserT Identity m Element
fromDom = DomParserT Identity m Element
forall (m :: * -> *). Monad m => DomParserT Identity m Element
elementFromDom

elementFromDom :: (Monad m) => DomParserT Identity m Element
elementFromDom :: forall (m :: * -> *). Monad m => DomParserT Identity m Element
elementFromDom = Getting Element (ParserData Identity) Element
-> ReaderT (ParserData Identity) (ExceptT ParserErrors m) Element
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view (Getting Element (ParserData Identity) Element
 -> ReaderT (ParserData Identity) (ExceptT ParserErrors m) Element)
-> Getting Element (ParserData Identity) Element
-> ReaderT (ParserData Identity) (ExceptT ParserErrors m) Element
forall a b. (a -> b) -> a -> b
$ (Identity Element -> Const Element (Identity Element))
-> ParserData Identity -> Const Element (ParserData Identity)
forall (f1 :: * -> *) (f2 :: * -> *) (f3 :: * -> *).
Functor f3 =>
(f1 Element -> f3 (f2 Element))
-> ParserData f1 -> f3 (ParserData f2)
pdElements ((Identity Element -> Const Element (Identity Element))
 -> ParserData Identity -> Const Element (ParserData Identity))
-> ((Element -> Const Element Element)
    -> Identity Element -> Const Element (Identity Element))
-> Getting Element (ParserData Identity) Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Identity Element -> Element)
-> (Element -> Const Element Element)
-> Identity Element
-> Const Element (Identity Element)
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to Identity Element -> Element
forall a. Identity a -> a
runIdentity