git.iko.soy/typeable/dom-parser
on master help sign in
Upd: improve docs, split module `Common`
467a733Aleksey Uimanov
dom-parser.cabal+2−1
@@ -57,8 +57,9 @@ library
57 , xml-conduit
57 , xml-conduit
58 , xml-lens
58 , xml-lens
59 exposed-modules: Text.XML.DOM.Parser
59 exposed-modules: Text.XML.DOM.Parser
60+ , Text.XML.DOM.Parser.Buildable
60 , Text.XML.DOM.Parser.Combinators
61 , Text.XML.DOM.Parser.Combinators
61− , Text.XML.DOM.Parser.Common
62+ , Text.XML.DOM.Parser.Content
62 , Text.XML.DOM.Parser.FromAttribute
63 , Text.XML.DOM.Parser.FromAttribute
63 , Text.XML.DOM.Parser.FromDom
64 , Text.XML.DOM.Parser.FromDom
64 , Text.XML.DOM.Parser.Types
65 , Text.XML.DOM.Parser.Types
src/Text/XML/DOM/Parser.hs+5−3
@@ -1,13 +1,15 @@
1module Text.XML.DOM.Parser
1module Text.XML.DOM.Parser
2− ( module Text.XML.DOM.Parser.Combinators
2+ ( module Text.XML.DOM.Parser.Buildable
3+ , module Text.XML.DOM.Parser.Combinators
3− , module Text.XML.DOM.Parser.Common
4+ , module Text.XML.DOM.Parser.Content
4 , module Text.XML.DOM.Parser.FromAttribute
5 , module Text.XML.DOM.Parser.FromAttribute
5 , module Text.XML.DOM.Parser.FromDom
6 , module Text.XML.DOM.Parser.FromDom
6 , module Text.XML.DOM.Parser.Types
7 , module Text.XML.DOM.Parser.Types
7 ) where
8 ) where
8
9
10+import Text.XML.DOM.Parser.Buildable
9import Text.XML.DOM.Parser.Combinators
11import Text.XML.DOM.Parser.Combinators
10−import Text.XML.DOM.Parser.Common
12+import Text.XML.DOM.Parser.Content
11import Text.XML.DOM.Parser.FromAttribute
13import Text.XML.DOM.Parser.FromAttribute
12import Text.XML.DOM.Parser.FromDom
14import Text.XML.DOM.Parser.FromDom
13import Text.XML.DOM.Parser.Types
15import Text.XML.DOM.Parser.Types
src/Text/XML/DOM/Parser/Buildable.hsnew file+26
@@ -0,0 +1,26 @@
1+module Text.XML.DOM.Parser.Buildable
2+ ( Buildable(..)
3+ ) where
4+
5+import Data.Functor.Identity
6+import Data.List.NonEmpty as NE
7+import Data.Maybe
8+
9+-- | Class of traversable functors which may be constructed from list
10+class Traversable f => Buildable f where
11+ -- | If method return Nothing this means we can not build
12+ -- traversable from given list. In this case 'inFilteredTrav' should
13+ -- fail traversing.
14+ build :: [a] -> Maybe (f a)
15+
16+instance Buildable Identity where
17+ build = fmap Identity . listToMaybe
18+
19+instance Buildable [] where
20+ build = Just
21+
22+instance Buildable Maybe where
23+ build = Just . listToMaybe
24+
25+instance Buildable NonEmpty where
26+ build = NE.nonEmpty
src/Text/XML/DOM/Parser/Combinators.hs+3−3
@@ -2,7 +2,7 @@ module Text.XML.DOM.Parser.Combinators
2 ( -- * Generic combinators to traverse descendants
2 ( -- * Generic combinators to traverse descendants
3 traverseElems
3 traverseElems
4 , inFilteredTrav
4 , inFilteredTrav
5− -- * Using 'DomTraversable'
5+ -- * Using 'Buildable'
6 , inElemTrav
6 , inElemTrav
7 , inElem
7 , inElem
8 , inElemAll
8 , inElemAll
@@ -26,7 +26,7 @@ import Data.Monoid
26import Data.Text as T
26import Data.Text as T
27import Data.Traversable
27import Data.Traversable
28import Text.XML
28import Text.XML
29−import Text.XML.DOM.Parser.Common
29+import Text.XML.DOM.Parser.Buildable
30import Text.XML.DOM.Parser.Types
30import Text.XML.DOM.Parser.Types
31import Text.XML.Lens
31import Text.XML.Lens
32
32
@@ -57,7 +57,7 @@ inFilteredTrav
57 :: (Monad m, Foldable g, Buildable f)
57 :: (Monad m, Foldable g, Buildable f)
58 => ([Element] -> (DomPath, [Element]))
58 => ([Element] -> (DomPath, [Element]))
59 -- ^ Function returning some filtered elements with path suffixes which will
59 -- ^ Function returning some filtered elements with path suffixes which will
60− -- be appended to parser's state
60+ -- be appended to parser's state. The argument is a list of current elements.
61 -> DomParserT Identity m a
61 -> DomParserT Identity m a
62 -> DomParserT g m (f a)
62 -> DomParserT g m (f a)
63inFilteredTrav deeper = traverseElems trav
63inFilteredTrav deeper = traverseElems trav
src/Text/XML/DOM/Parser/Common.hs → src/Text/XML/DOM/Parser/Content.hsrenamed+9−29
@@ -1,8 +1,6 @@
1−module Text.XML.DOM.Parser.Common
1+module Text.XML.DOM.Parser.Content
2− ( -- * Buildable
3− Buildable(..)
4− -- * Content readers
2+ ( -- * Content readers
5− , readBool
3+ readBool
6 , readChar
4 , readChar
7 -- ** Reader constructors
5 -- ** Reader constructors
8 , maybeReadContent
6 , maybeReadContent
@@ -24,9 +22,7 @@ import Control.Lens
24import Control.Monad
22import Control.Monad
25import Control.Monad.Except
23import Control.Monad.Except
26import Data.List as L
24import Data.List as L
27−import Data.List.NonEmpty as NE
28import Data.Map.Strict as M
25import Data.Map.Strict as M
29−import Data.Maybe
30import Data.Monoid
26import Data.Monoid
31import Data.Text as T
27import Data.Text as T
32import Data.Typeable
28import Data.Typeable
@@ -34,25 +30,6 @@ import Text.Read
34import Text.XML.DOM.Parser.Types
30import Text.XML.DOM.Parser.Types
35import Text.XML.Lens
31import Text.XML.Lens
36
32
37−-- | Class of traversable functors which may be constructed from list. Or may
38−-- not.
39−class Traversable f => Buildable f where
40− -- | If method return Nothing this means we can not build
41− -- traversable from given list. In this case 'inFilteredTrav' should
42− -- fail traversing.
43− build :: [a] -> Maybe (f a)
44−
45−instance Buildable Identity where
46− build = fmap Identity . listToMaybe
47−
48−instance Buildable [] where
49− build = Just
50−
51−instance Buildable Maybe where
52− build = Just . listToMaybe
53−
54−instance Buildable NonEmpty where
55− build = NE.nonEmpty
56
33
57-- | @since 1.0.0
34-- | @since 1.0.0
58readBool :: Text -> Either Text Bool
35readBool :: Text -> Either Text Bool
@@ -76,7 +53,8 @@ readChar t = case T.unpack $ T.strip t of
76 _ -> Left "Should have exactly one non-blank character"
53 _ -> Left "Should have exactly one non-blank character"
77
54
78-- | If reader returns 'Nothing' then resulting function returns 'Left
55-- | If reader returns 'Nothing' then resulting function returns 'Left
79−-- "error message"'
56+-- "error message"'. 'Typeable' is used for generating usefull error
57+-- message.
80--
58--
81-- @since 1.0.0
59-- @since 1.0.0
82maybeReadContent
60maybeReadContent
@@ -94,7 +72,8 @@ maybeReadContent f t = maybe (Left msg) Right $ f t
94
72
95
73
96-- | Tries to read given text to value using 'Read'. Useful to use
74-- | Tries to read given text to value using 'Read'. Useful to use
97−-- with 'parseContent' and 'parseAttribute'
75+-- with 'parseContent' and 'parseAttribute'. Content is stripped
76+-- before reading.
98readContent
77readContent
99 :: (Read a, Typeable a)
78 :: (Read a, Typeable a)
100 => Text
79 => Text
@@ -186,7 +165,8 @@ parseAttribute attrName parser =
186 Nothing -> throwParserError $ PEAttributeNotFound attrName
165 Nothing -> throwParserError $ PEAttributeNotFound attrName
187 Just a -> return a
166 Just a -> return a
188
167
189−-- | Parses attribute with given name.
168+-- | Parses attribute with given name. Returns Nothing if attribute is
169+-- not found.
190--
170--
191-- @since 1.0.0
171-- @since 1.0.0
192parseAttributeMaybe
172parseAttributeMaybe
src/Text/XML/DOM/Parser/FromAttribute.hs+4−1
@@ -21,8 +21,11 @@ import Data.Scientific
21import Data.Text as T
21import Data.Text as T
22import Data.Typeable
22import Data.Typeable
23import Data.Void
23import Data.Void
24−import Text.XML.DOM.Parser.Common
24+import Text.XML.DOM.Parser.Content
25
25
26+-- | Class of types which can be get from attribute value. Method
27+-- 'fromAttribute' is a convenient default parameter for
28+-- 'parseAttribute'
26class FromAttribute a where
29class FromAttribute a where
27 fromAttribute
30 fromAttribute
28 :: Text
31 :: Text
src/Text/XML/DOM/Parser/FromDom.hs+1−1
@@ -27,7 +27,7 @@ import Data.Text as T hiding (empty)
27import Data.Typeable
27import Data.Typeable
28import Data.Void
28import Data.Void
29import Text.XML
29import Text.XML
30−import Text.XML.DOM.Parser.Common
30+import Text.XML.DOM.Parser.Content
31import Text.XML.DOM.Parser.Types
31import Text.XML.DOM.Parser.Types
32import TypeFun.Data.List hiding (Union)
32import TypeFun.Data.List hiding (Union)
33
33
src/Text/XML/DOM/Parser/Types.hs+8−1
@@ -57,18 +57,24 @@ instance IsString NameMatcher where
57instance Show NameMatcher where
57instance Show NameMatcher where
58 show = T.unpack . _nmShow
58 show = T.unpack . _nmShow
59
59
60+-- | Makes matcher which matches only local part of name igoring
61+-- namespace and prefix. Local name matching is case sensitive.
60matchLocalName :: Text -> NameMatcher
62matchLocalName :: Text -> NameMatcher
61matchLocalName tname = NameMatcher
63matchLocalName tname = NameMatcher
62 { _nmMatch = \n -> nameLocalName n == tname
64 { _nmMatch = \n -> nameLocalName n == tname
63 , _nmShow = tname
65 , _nmShow = tname
64 }
66 }
65
67
68+-- | Makes matcher which matches only local part of name igoring
69+-- namespace and prefix. Local name matching is case insensitive. This
70+-- is the most common case.
66matchCILocalName :: Text -> NameMatcher
71matchCILocalName :: Text -> NameMatcher
67matchCILocalName tname = NameMatcher
72matchCILocalName tname = NameMatcher
68 { _nmMatch = \n -> CI.mk (nameLocalName n) == CI.mk tname
73 { _nmMatch = \n -> CI.mk (nameLocalName n) == CI.mk tname
69 , _nmShow = tname
74 , _nmShow = tname
70 }
75 }
71
76
77+-- | Makes matcher which match name by 'Eq' with given
72matchName :: Name -> NameMatcher
78matchName :: Name -> NameMatcher
73matchName n = NameMatcher
79matchName n = NameMatcher
74 { _nmMatch = (== n)
80 { _nmMatch = (== n)
@@ -87,12 +93,13 @@ data ParserError
87 -- | Tag not found which should be.
93 -- | Tag not found which should be.
88 = PENotFound
94 = PENotFound
89 { _pePath :: DomPath
95 { _pePath :: DomPath
96+ -- ^ Path of element error occured in
90 }
97 }
91
98
92 -- | Tag contents has wrong format, (could not read text to value)
99 -- | Tag contents has wrong format, (could not read text to value)
93 | PEWrongFormat
100 | PEWrongFormat
94 { _peDetails :: Text
101 { _peDetails :: Text
95− , _pePath :: DomPath -- ^ path of element
102+ , _pePath :: DomPath
96 }
103 }
97
104
98 -- | Could not parse attribute
105 -- | Could not parse attribute