@@ -114,6 +114,7 @@ module Data.THGen.XML
118 -- Re-exports
119 -- Re-exports
@@ -133,12 +134,12 @@ import Data.THGen.Enum
133import qualified Data.Text as T
134import qualified Data.Text as T
134import GHC.Generics (Generic)
135import GHC.Generics (Generic)
135import qualified Language.Haskell.TH as TH
136import qualified Language.Haskell.TH as TH
136−import qualified Language.Haskell.TH.Syntax as TH
137−import Prelude hiding ((+), (*))
137+import Prelude hiding ((+), (*), (^))
138import qualified Text.XML as X
138import qualified Text.XML as X
139−import Text.XML.DOM.Parser
139+import Text.XML.DOM.Parser hiding (parseContent)
140import Text.XML.ParentAttributes
140import Text.XML.ParentAttributes
141import qualified Text.XML.Writer as XW
141import qualified Text.XML.Writer as XW
142+import Text.XML.DOM.Parser.Internal.Content
144data XmlFieldPlural
145data XmlFieldPlural
@@ -157,13 +158,18 @@ data IsoXmlDescPreField = IsoXmlDescPreField String TH.TypeQ
158data IsoXmlDescPreAttribute = IsoXmlDescPreAttribute String TH.TypeQ
159data IsoXmlDescPreAttribute = IsoXmlDescPreAttribute String TH.TypeQ
161+data IsoXmlDescPreContent = IsoXmlDescPreContent String TH.TypeQ
160data IsoXmlDescField = IsoXmlDescField XmlFieldPlural String TH.TypeQ
163data IsoXmlDescField = IsoXmlDescField XmlFieldPlural String TH.TypeQ
162data IsoXmlDescAttribute = IsoXmlDescAttribute XmlAttributePlural String TH.TypeQ
165data IsoXmlDescAttribute = IsoXmlDescAttribute XmlAttributePlural String TH.TypeQ
167+data IsoXmlDescContent = IsoXmlDescContent String TH.TypeQ
164data IsoXmlDescRecordPart
169data IsoXmlDescRecordPart
165 = IsoXmlDescRecordField IsoXmlDescField
170 = IsoXmlDescRecordField IsoXmlDescField
166 | IsoXmlDescRecordAttribute IsoXmlDescAttribute
171 | IsoXmlDescRecordAttribute IsoXmlDescAttribute
172+ | IsoXmlDescRecordContent IsoXmlDescContent
168newtype IsoXmlDescRecord = IsoXmlDescRecord [IsoXmlDescRecordPart]
174newtype IsoXmlDescRecord = IsoXmlDescRecord [IsoXmlDescRecordPart]
@@ -199,6 +205,14 @@ appendAttribute plural xrec (IsoXmlDescPreAttribute name ty) =
199 let xattribute = IsoXmlDescRecordAttribute $ IsoXmlDescAttribute plural name ty
205 let xattribute = IsoXmlDescRecordAttribute $ IsoXmlDescAttribute plural name ty
200 in over _IsoXmlDescRecord (xattribute:) xrec
206 in over _IsoXmlDescRecord (xattribute:) xrec
210+ -> IsoXmlDescPreContent
212+appendContent xrec (IsoXmlDescPreContent name ty) =
213+ let xcontent = IsoXmlDescRecordContent $ IsoXmlDescContent name ty
214+ in over _IsoXmlDescRecord (xcontent:) xrec
202(!), (?), (*), (+) :: IsoXmlDescRecord -> IsoXmlDescPreField -> IsoXmlDescRecord
216(!), (?), (*), (+) :: IsoXmlDescRecord -> IsoXmlDescPreField -> IsoXmlDescRecord
203(!) = appendField XmlFieldPluralMandatory
217(!) = appendField XmlFieldPluralMandatory
204(?) = appendField XmlFieldPluralOptional
218(?) = appendField XmlFieldPluralOptional
@@ -209,12 +223,16 @@ appendAttribute plural xrec (IsoXmlDescPreAttribute name ty) =
209(!%) = appendAttribute XmlAttributePluralMandatory
223(!%) = appendAttribute XmlAttributePluralMandatory
210(?%) = appendAttribute XmlAttributePluralOptional
224(?%) = appendAttribute XmlAttributePluralOptional
226+(^) :: IsoXmlDescRecord -> IsoXmlDescPreContent -> IsoXmlDescRecord
212infixl 2 !
229infixl 2 !
213infixl 2 ?
230infixl 2 ?
214infixl 2 *
231infixl 2 *
215infixl 2 +
232infixl 2 +
216infixl 2 !%
233infixl 2 !%
217infixl 2 ?%
234infixl 2 ?%
219appendEnumCon :: IsoXmlDescEnum -> IsoXmlDescEnumCon -> IsoXmlDescEnum
237appendEnumCon :: IsoXmlDescEnum -> IsoXmlDescEnumCon -> IsoXmlDescEnum
220appendEnumCon xenum xenumcon =
238appendEnumCon xenum xenumcon =
@@ -257,11 +275,19 @@ instance IsString IsoXmlDescPreField where
257instance IsString (TH.TypeQ -> IsoXmlDescPreAttribute) where
275instance IsString (TH.TypeQ -> IsoXmlDescPreAttribute) where
258 fromString = IsoXmlDescPreAttribute
276 fromString = IsoXmlDescPreAttribute
278+instance IsString (TH.TypeQ -> IsoXmlDescPreContent) where
279+ fromString = IsoXmlDescPreContent
260instance IsString IsoXmlDescPreAttribute where
281instance IsString IsoXmlDescPreAttribute where
261 fromString name = IsoXmlDescPreAttribute name ty
282 fromString name = IsoXmlDescPreAttribute name ty
263 ty = (TH.conT . TH.mkName) ("Xml" ++ over _head C.toUpper name)
284 ty = (TH.conT . TH.mkName) ("Xml" ++ over _head C.toUpper name)
286+instance IsString IsoXmlDescPreContent where
287+ fromString name = IsoXmlDescPreContent name ty
289+ ty = (TH.conT . TH.mkName) ("Xml" ++ over _head C.toUpper name)
265instance s ~ String => IsString (s -> PrefixName) where
291instance s ~ String => IsString (s -> PrefixName) where
266 fromString = PrefixName
292 fromString = PrefixName
@@ -349,6 +375,14 @@ isoXmlGenerateDatatype (PrefixName strName' strPrefix') descRecordParts = do
349 in if isNewtype
375 in if isNewtype
350 then varStrictType fName (nonStrictType fType)
376 then varStrictType fName (nonStrictType fType)
351 else varStrictType fName (strictType fType)
377 else varStrictType fName (strictType fType)
378+ IsoXmlDescRecordContent descContent ->
380+ IsoXmlDescContent contentStrName contentType = descContent
381+ fName = TH.mkName (fieldName contentStrName)
384+ then varStrictType fName (nonStrictType fType)
385+ else varStrictType fName (strictType fType)
352 if isNewtype
386 if isNewtype
353 -- generate a newtype instead to do less allocations later
387 -- generate a newtype instead to do less allocations later
354 then newtypeD name (TH.recC name fields) [''Eq, ''Show, ''Generic]
388 then newtypeD name (TH.recC name fields) [''Eq, ''Show, ''Generic]
@@ -384,6 +418,7 @@ isoXmlGenerateDatatype (PrefixName strName' strPrefix') descRecordParts = do
384 XmlAttributePluralOptional -> [e|parseAttributeMaybe|]
418 XmlAttributePluralOptional -> [e|parseAttributeMaybe|]
386 [e|$attributeParse $exprAttributeStrName fromAttribute|]
420 [e|$attributeParse $exprAttributeStrName fromAttribute|]
421+ IsoXmlDescRecordContent _ -> [e|parseContent fromAttribute|]
387 fromDomExpr = foldl (\e fe -> [e| $e <*> $fe |]) exprHeader exprRecordParts
422 fromDomExpr = foldl (\e fe -> [e| $e <*> $fe |]) exprHeader exprRecordParts
388 TH.instanceD
423 TH.instanceD
389 (return [])
424 (return [])
@@ -395,21 +430,27 @@ isoXmlGenerateDatatype (PrefixName strName' strPrefix') descRecordParts = do
396 exprFields = do
431 exprFields = do
397 descRecordPart <- descRecordParts
432 descRecordPart <- descRecordParts
398− IsoXmlDescField fieldPlural rawName _ <-
399− maybeToList $ case descRecordPart of
433+ case descRecordPart of
400− IsoXmlDescRecordField descField -> Just descField
434+ IsoXmlDescRecordField (IsoXmlDescField fieldPlural rawName _) -> do
403− fieldStrName = xmlLocalName rawName
436+ fieldStrName = xmlLocalName rawName
404− fName = TH.mkName (fieldName fieldStrName)
437+ fName = TH.mkName (fieldName fieldStrName)
405− exprFieldStrName = TH.litE (TH.stringL rawName)
438+ exprFieldStrName = TH.litE (TH.stringL rawName)
406− exprForField = case fieldPlural of
439+ exprForField = case fieldPlural of
407− XmlFieldPluralMandatory -> [e|id|]
440+ XmlFieldPluralMandatory -> [e|id|]
408− _ -> [e|traverse|]
441+ _ -> [e|traverse|]
409− exprFieldValue = [e|$(TH.varE fName) $(TH.varE objName)|]
442+ exprFieldValue = [e|$(TH.varE fName) $(TH.varE objName)|]
410− exprFieldRender =
443+ exprFieldRender =
411− [e|(\a -> XW.elementA $exprFieldStrName (toXmlParentAttributes a) a)|]
445+ XW.elementA $exprFieldStrName (toXmlParentAttributes a) a)|]
412− return [e|$exprForField $exprFieldRender $exprFieldValue|]
446+ return [e|$exprForField $exprFieldRender $exprFieldValue|]
447+ IsoXmlDescRecordContent (IsoXmlDescContent rawName _) -> do
449+ fieldStrName = xmlLocalName rawName
450+ fName = TH.mkName (fieldName fieldStrName)
451+ exprFieldValue = [e|$(TH.varE fName) $(TH.varE objName)|]
452+ return [e|XW.content . toXmlAttribute $ $exprFieldValue|]
413 toXmlExpr
454 toXmlExpr
414 = TH.lamE [if null exprFields then TH.wildP else TH.varP objName]
455 = TH.lamE [if null exprFields then TH.wildP else TH.varP objName]
415 $ foldr (\fe e -> [e|$fe *> $e|]) [e|return ()|] exprFields
456 $ foldr (\fe e -> [e|$fe *> $e|]) [e|return ()|] exprFields