xml-isogen-0.2.0: src/Text/XML/ParentAttributes.hs
module Text.XML.ParentAttributes
( ToXmlParentAttributes(..)
, ToXmlAttribute(..)
, toXmlAttributeIntegral
) where
import Data.Text as T.S
import Data.Text.Lazy as T.L
import Data.Text.Lazy.Builder as T.L
import Data.Text.Lazy.Builder.Int as T.L
import Numeric.Natural
import Text.XML
class ToXmlParentAttributes a where
toXmlParentAttributes :: a -> [(Name, T.S.Text)]
-- | A catch-all instance: by default objects don't have parent attributes.
-- The alternative solution is to write a default implementation in the class,
-- but it has a drawback that it requires numerous (boilerplate) empty
-- instances - one for each type that doesn't have parent attributes (most
-- types). This overlappable instance gets overriden for XML records
-- (described in "Data.THGen.XML") because they can store parent attributes
-- added via the @!%@ and @?%@ operators.
-- For example, `toXmlParentAttributes` applied to a `Text` or `Integer' value
-- returns @[]@ because of this instance. However, an XML record defined as
-- @"Foo" =:= record !% "bar"@ will have its own TH-generated
-- `ToXmlParentAttributes` instance that inspects the value of its @bar@ field
-- and returns it as an attribute.
-- This way the TH-generators can safely apply `toXmlParentAttributes` to any
-- value without worrying about missing instances.
instance {-# OVERLAPPABLE #-} ToXmlParentAttributes a where
toXmlParentAttributes _ = []
class ToXmlAttribute a where
toXmlAttribute :: a -> T.S.Text
instance ToXmlAttribute T.S.Text where
toXmlAttribute = id
toXmlAttributeIntegral :: Integral a => a -> T.S.Text
toXmlAttributeIntegral = T.L.toStrict . T.L.toLazyText . T.L.decimal
instance ToXmlAttribute Int where
toXmlAttribute = toXmlAttributeIntegral
instance ToXmlAttribute Word where
toXmlAttribute = toXmlAttributeIntegral
instance ToXmlAttribute Integer where
toXmlAttribute = toXmlAttributeIntegral
instance ToXmlAttribute Natural where
toXmlAttribute = toXmlAttributeIntegral