{-# 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 forall a. Maybe a
Nothing 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 = forall a b. (a, b) -> a
fst

strContent :: Element -> Text
strContent :: Element -> Text
strContent = [Text] -> Text
T.concat 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 [] forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 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 = 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 = forall a. (a -> Bool) -> [a] -> [a]
filter ((Name
n forall a. Eq a => a -> a -> Bool
==) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Element -> Name
elementName) forall a b. (a -> b) -> a -> b
$ Element -> [Element]
elementChildren Element
el

findChild :: Name -> Element -> Maybe Element
findChild :: Name -> Element -> Maybe Element
findChild = (forall a. [a] -> Maybe a
headMay forall b c a. (b -> c) -> (a -> b) -> a -> c
.) 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 forall a. Eq a => a -> a -> Bool
== Element -> Name
elementName Element
e = [Element
e]
  | Bool
otherwise = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Name -> Element -> [Element]
findElements Name
n) forall a b. (a -> b) -> a -> b
$ Element -> [Element]
elementChildren Element
e

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