    {-# LANGUAGE FlexibleInstances #-}

    -- | Compatibility interface between `xml` and `xml-types`.
    module Data.XML.Compat where

    import Prelude.Compat

    import Data.Text (Text)
    import qualified Data.Text as T
    import Data.XML.Types

    import Safe

    type Attr = (Name, [Content])

    mkAttr :: Text -> Text -> Attr
    mkAttr :: Text -> Text -> Attr
    mkAttr Text
    k = Name -> Text -> Attr
    mkNAttr (Text -> Maybe Text -> Maybe Text -> Name
    Name Text
    k Maybe Text
    forall a. Maybe a
    Nothing Maybe Text
    forall a. Maybe a
    Nothing)

    mkNAttr :: Name -> Text -> Attr
    mkNAttr :: Name -> Text -> Attr
    mkNAttr Name
    k Text
    v = (Name
    k, [Text -> Content
    ContentText Text
    v])

    attrKey :: Attr -> Name
    attrKey :: Attr -> Name
    attrKey = Attr -> Name
    forall a b. (a, b) -> a
    fst

    strContent :: Element -> Text
    strContent :: Element -> Text
    strContent = [Text] -> Text
    T.concat ([Text] -> Text) -> (Element -> [Text]) -> Element -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Element -> [Text]
    elementText

    class ToNode t where
      unode :: Name -> t -> Element

    instance ToNode [Attr] where
      unode :: Name -> [Attr] -> Element
    unode Name
    n [Attr]
    as = Name -> [Attr] -> [Node] -> Element
    Element Name
    n [Attr]
    as []

    instance ToNode [Element] where
      unode :: Name -> [Element] -> Element
    unode Name
    n = Name -> [Attr] -> [Node] -> Element
    Element Name
    n [] ([Node] -> Element)
    -> ([Element] -> [Node]) -> [Element] -> Element
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Element -> Node) -> [Element] -> [Node]
    forall a b. (a -> b) -> [a] -> [b]
    map Element -> Node
    NodeElement

    instance ToNode ([Attr], Text) where
      unode :: Name -> ([Attr], Text) -> Element
    unode Name
    n ([Attr]
    as, Text
    t) = Name -> [Attr] -> [Node] -> Element
    Element Name
    n [Attr]
    as [Content -> Node
    NodeContent (Content -> Node) -> Content -> Node
    forall a b. (a -> b) -> a -> b
    $ Text -> Content
    ContentText Text
    t]

    instance ToNode Text where
      unode :: Name -> Text -> Element
    unode Name
    n Text
    t = Name -> ([Attr], Text) -> Element
    forall t. ToNode t => Name -> t -> Element
    unode Name
    n ([] :: [Attr], Text
    t)

    findChildren :: Name -> Element -> [Element]
    findChildren :: Name -> Element -> [Element]
    findChildren Name
    n Element
    el = (Element -> Bool) -> [Element] -> [Element]
    forall a. (a -> Bool) -> [a] -> [a]
    filter ((Name
    n Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    ==) (Name -> Bool) -> (Element -> Name) -> Element -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Element -> Name
    elementName) ([Element] -> [Element]) -> [Element] -> [Element]
    forall a b. (a -> b) -> a -> b
    $ Element -> [Element]
    elementChildren Element
    el

    findChild :: Name -> Element -> Maybe Element
    findChild :: Name -> Element -> Maybe Element
    findChild = ([Element] -> Maybe Element
    forall a. [a] -> Maybe a
    headMay ([Element] -> Maybe Element)
    -> (Element -> [Element]) -> Element -> Maybe Element
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .) ((Element -> [Element]) -> Element -> Maybe Element)
    -> (Name -> Element -> [Element])
    -> Name
    -> Element
    -> Maybe Element
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Name -> Element -> [Element]
    findChildren

    findElements :: Name -> Element -> [Element]
    findElements :: Name -> Element -> [Element]
    findElements Name
    n Element
    e
      | Name
    n Name -> Name -> Bool
    forall a. Eq a => a -> a -> Bool
    == Element -> Name
    elementName Element
    e = [Element
    e]
      | Bool
    otherwise = (Element -> [Element]) -> [Element] -> [Element]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap (Name -> Element -> [Element]
    findElements Name
    n) ([Element] -> [Element]) -> [Element] -> [Element]
    forall a b. (a -> b) -> a -> b
    $ Element -> [Element]
    elementChildren Element
    e

    findElement :: Name -> Element -> Maybe Element
    findElement :: Name -> Element -> Maybe Element
    findElement = ([Element] -> Maybe Element
    forall a. [a] -> Maybe a
    headMay ([Element] -> Maybe Element)
    -> (Element -> [Element]) -> Element -> Maybe Element
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .) ((Element -> [Element]) -> Element -> Maybe Element)
    -> (Name -> Element -> [Element])
    -> Name
    -> Element
    -> Maybe Element
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Name -> Element -> [Element]
    findElements