on master help sign in
YamlObject adds tag and style information
commit6b00934154178d450241f6cb8e523e4f25800794 authorMichael Snoyman <michael@snoyman.com> dateThu 10 Dec 2009, 02:29 (17 years ago) parent2e327be
7 files changed+299−227
Data/Object/Yaml.hs+148 Text/Libyaml.hs+27−38 Text/Yaml.hs+100−187 c/helper.c+17 c/helper.h+4 Test.hs → runtests.hs yaml.cabal+3−2
Data/Object/Yaml.hsnew file+148
@@ -0,0 +1,148 @@
1+{-# LANGUAGE FlexibleInstances #-}
2+{-# LANGUAGE FlexibleContexts #-}
3+{-# LANGUAGE MultiParamTypeClasses #-}
4+{-# LANGUAGE DeriveDataTypeable #-}
5+module Data.Object.Yaml
6+ ( -- * The event stream
7+ Event (..)
8+ , Style (..)
9+ -- * 'YamlObject' definition
10+ , Yaml (..)
11+ , YamlObject
12+ -- * Performing conversions
13+ , eventsToYamlObject
14+ -- * Exceptions
15+ , YamlException (..)
16+ ) where
17+
18+import Data.ByteString (ByteString)
19+import Data.Object
20+import Data.Object.Text
21+import Data.Convertible.Text
22+import Data.Attempt
23+
24+import Data.Typeable (Typeable)
25+import Control.Exception (Exception)
26+
27+data Event =
28+ EventNone
29+ | EventStreamStart
30+ | EventStreamEnd
31+ | EventDocumentStart
32+ | EventDocumentEnd
33+ | EventAlias
34+ | EventScalar ByteString ByteString Style
35+ | EventSequenceStart
36+ | EventSequenceEnd
37+ | EventMappingStart
38+ | EventMappingEnd
39+ deriving (Show, Eq)
40+
41+data Style = Any
42+ | Plain
43+ | SingleQuoted
44+ | DoubleQuoted
45+ | Literal
46+ | Folded
47+ deriving (Show, Eq, Enum, Bounded, Ord)
48+
49+data Yaml = Yaml
50+ { value :: ByteString
51+ , tag :: String
52+ , style :: Style
53+ }
54+instance ConvertSuccess Yaml Event where
55+ convertSuccess (Yaml v t s) = EventScalar v (convertSuccess t) s
56+instance ConvertSuccess Yaml Text where
57+ convertSuccess = convertSuccess . value
58+instance ConvertSuccess Text Yaml where
59+ convertSuccess t = Yaml (convertSuccess t) "" Any
60+
61+type YamlObject = Object Yaml Yaml
62+
63+data YamlException =
64+ YamlParserException
65+ { parserProblem :: String
66+ , parserContext :: String
67+ , parserOffset :: Int
68+ }
69+ | YamlEmitterException { emitterProblem :: String }
70+ | YamlInvalidEventStreamBeginning [Event]
71+ | YamlInvalidEventStreamEnd [Event]
72+ | YamlPrematureEventStreamEnd
73+ | YamlNonScalarKey
74+ | YamlInvalidStartingEvent Event
75+ deriving (Show, Typeable)
76+instance Exception YamlException
77+
78+-- Emit a YamlObject to an event stream
79+instance ConvertSuccess (Object Yaml Yaml) [Event] where
80+ convertSuccess o = EventStreamStart
81+ : EventDocumentStart
82+ : helper o [EventDocumentEnd, EventStreamEnd] where
83+ helper :: YamlObject -> [Event] -> [Event]
84+ helper (Scalar y) rest = convertSuccess y : rest
85+ helper (Sequence ys) rest =
86+ EventSequenceStart
87+ : foldr ($) (EventSequenceEnd : rest) (map helper ys)
88+ helper (Mapping pairs) rest =
89+ EventMappingStart
90+ : foldr ($) (EventMappingEnd : rest) (map helperPairs pairs)
91+ helperPairs :: (Yaml, YamlObject) -> [Event] -> [Event]
92+ helperPairs (k, v) rest = convertSuccess k : helper v rest
93+
94+-- Parse a YamlObject from an event stream
95+eventsToYamlObject :: MonadFailure YamlException m
96+ => [Event]
97+ -> m YamlObject
98+eventsToYamlObject (EventStreamStart:EventDocumentStart:events) = h1 events
99+ where
100+ h1 :: MonadFailure YamlException m => [Event] -> m YamlObject
101+ h1 es = do
102+ (yo, es') <- h2 es
103+ case es' of
104+ [EventDocumentEnd, EventStreamEnd] -> return yo
105+ _ -> failure $ YamlInvalidEventStreamEnd es'
106+ h2 :: MonadFailure YamlException m
107+ => [Event]
108+ -> m (YamlObject, [Event])
109+ h2 [] = failure YamlPrematureEventStreamEnd
110+ h2 (EventScalar v t s:rest) =
111+ return (Scalar $ Yaml v (convertSuccess t) s, rest)
112+ h2 (EventSequenceStart:es) = do
113+ (yos, rest) <- readSeq id es
114+ return (Sequence yos, rest)
115+ h2 (EventMappingStart:es) = do
116+ (ypairs, rest) <- readMap id es
117+ return (Mapping ypairs, rest)
118+ h2 (e:_) = failure $ YamlInvalidStartingEvent e
119+
120+ readSeq :: MonadFailure YamlException m
121+ => ([YamlObject] -> [YamlObject])
122+ -> [Event]
123+ -> m ([YamlObject], [Event])
124+ readSeq _ [] = failure YamlPrematureEventStreamEnd
125+ readSeq f (EventSequenceEnd:rest) = return (f [], rest)
126+ readSeq f es = do
127+ (next, rest) <- h2 es
128+ readSeq (f . ((:) next)) rest
129+
130+ readMap :: MonadFailure YamlException m
131+ => ([(Yaml, YamlObject)] -> [(Yaml, YamlObject)])
132+ -> [Event]
133+ -> m ([(Yaml, YamlObject)], [Event])
134+ readMap _ [] = failure YamlPrematureEventStreamEnd
135+ readMap f (EventMappingEnd:rest) = return (f [], rest)
136+ readMap f es = do
137+ (key, rest) <- h2 es
138+ key' <- case key of
139+ Scalar y -> return y
140+ _ -> failure YamlNonScalarKey
141+ (val, rest') <- h2 rest
142+ readMap (f . ((:) (key', val))) rest'
143+eventsToYamlObject e = failure $ YamlInvalidEventStreamBeginning e
144+
145+instance ConvertSuccess (Object Yaml Yaml) (Object Text Text) where
146+ convertSuccess = mapKeysValues convertSuccess convertSuccess
147+instance ConvertSuccess (Object Text Text) (Object Yaml Yaml) where
148+ convertSuccess = mapKeysValues convertSuccess convertSuccess
Text/Libyaml.hs+27−38
@@ -7,14 +7,12 @@
77{-# INCLUDE <yaml.h> #-}
88{-# INCLUDE <helper.h> #-}
99module Text.Libyaml
10−{-
11− (
12− Event (..)
13− , parserParse
14− , withParser
15− , emitEvents
10+ ( YamlException (..)
1611 , withEmitter
17− )-} where
12+ , emitEvents
13+ , withParser
14+ , parserParse
15+ ) where
1816
1917import qualified Data.ByteString.Internal as B
2018import Control.Monad
@@ -24,14 +22,12 @@ import Foreign.ForeignPtr
2422import Foreign.Marshal.Alloc
2523
2624import Control.Failure
27−import Data.Typeable (Typeable)
28−import Control.Exception (Exception)
2925
3026import Data.Convertible.Text
31−import Data.Text.Lazy (Text)
32−import Data.Object.Text ()
3327import Control.Applicative
3428
29+import Data.Object.Yaml hiding (style, value)
30+
3531data ParserStruct
3632type Parser = Ptr ParserStruct
3733parserSize :: Int
@@ -87,22 +83,12 @@ foreign import ccall "get_parser_error_context"
8783foreign import ccall unsafe "get_parser_error_offset"
8884 c_get_parser_error_offset :: Parser -> IO CULong
8985
90−data YamlException =
91− YamlParserException
92− { parserProblem :: String
93− , parserContext :: String
94− , parserOffset :: Int
95− }
96− | YamlEmitterException { emitterProblem :: String }
97− deriving (Show, Typeable)
98−instance Exception YamlException
99−
10086makeString :: (a -> IO (Ptr CUChar)) -> a -> IO String
10187makeString f a = do
10288 cchar <- castPtr `fmap` f a
10389 len <- fromIntegral `fmap` B.c_strlen cchar
10490 bs <- B.create len $ \dest -> B.memcpy dest (castPtr cchar) (fromIntegral len)
105− return $ (convertSuccess :: Text -> String) $ convertSuccess bs
91+ return $ convertSuccess bs
10692
10793parserParseOne :: MonadFailure YamlException m
10894 => Parser
@@ -122,20 +108,6 @@ parserParseOne parser = withEventRaw $ \er -> do
122108 c_yaml_event_delete er
123109 return event
124110
125−data Event =
126− EventNone
127− | EventStreamStart
128− | EventStreamEnd
129− | EventDocumentStart
130− | EventDocumentEnd
131− | EventAlias
132− | EventScalar B.ByteString
133− | EventSequenceStart
134− | EventSequenceEnd
135− | EventMappingStart
136− | EventMappingEnd
137− deriving (Show)
138−
139111data EventType = YamlNoEvent
140112 | YamlStreamStartEvent
141113 | YamlStreamEndEvent
@@ -158,6 +130,15 @@ foreign import ccall unsafe "get_scalar_value"
158130foreign import ccall unsafe "get_scalar_length"
159131 c_get_scalar_length :: EventRaw -> IO CULong
160132
133+foreign import ccall unsafe "get_scalar_tag"
134+ c_get_scalar_tag :: EventRaw -> IO (Ptr CUChar)
135+
136+foreign import ccall unsafe "get_scalar_tag_len"
137+ c_get_scalar_tag_len :: EventRaw -> IO CULong
138+
139+foreign import ccall unsafe "get_scalar_style"
140+ c_get_scalar_style :: EventRaw -> IO CInt
141+
161142getEvent :: EventRaw -> IO Event
162143getEvent er = do
163144 et <- c_get_event_type er
@@ -171,11 +152,19 @@ getEvent er = do
171152 YamlScalarEvent -> do
172153 yvalue <- c_get_scalar_value er
173154 ylen <- c_get_scalar_length er
155+ ytag <- c_get_scalar_tag er
156+ ytag_len <- c_get_scalar_tag_len er
157+ ystyle <- c_get_scalar_style er
158+ let ytag_len' = fromEnum ytag_len
174159 let yvalue' = castPtr yvalue
160+ let ytag' = castPtr ytag
175161 let ylen' = fromEnum ylen
176162 let ylen'' = toEnum $ fromEnum ylen
177163 bs <- B.create ylen' $ \dest -> B.memcpy dest yvalue' ylen''
178− return $ EventScalar bs
164+ tagbs <- B.create ytag_len'
165+ $ \dest -> B.memcpy dest ytag' (toEnum ytag_len')
166+ let style = toEnum $ fromEnum ystyle
167+ return $ EventScalar bs tagbs style
179168 YamlSequenceStartEvent -> return EventSequenceStart
180169 YamlSequenceEndEvent -> return EventSequenceEnd
181170 YamlMappingStartEvent -> return EventMappingStart
@@ -346,7 +335,7 @@ toEventRaw e f = withEventRaw $ \er -> do
346335 c_simple_document_start er
347336 EventDocumentEnd ->
348337 c_yaml_document_end_event_initialize er 1
349− EventScalar bs -> do
338+ EventScalar bs _tag _style -> do -- FIXME
350339 let (fvalue, offset, len) = B.toForeignPtr bs
351340 withForeignPtr fvalue $ \value -> do
352341 let value' = value `plusPtr` offset
Text/Yaml.hs+100−187
@@ -2,6 +2,7 @@
22{-# LANGUAGE FlexibleContexts #-}
33{-# LANGUAGE MultiParamTypeClasses #-}
44{-# LANGUAGE CPP #-}
5+{-# LANGUAGE PackageImports #-}
56---------------------------------------------------------
67--
78-- Module : Text.Yaml
@@ -20,21 +21,18 @@ module Text.Yaml
2021 (
2122 -- * Exceptions
2223 YamlException (..)
23− ,
24+ -- * Converting to/from 'YamlObject's
25+ , encodeYaml'
26+ , decodeYaml'
27+ , encodeYaml
28+ , decodeYaml
29+ , decodeYamlSuccess
2430 -- * Converting to/from 'TextObject's
25− encodeText
26− , encodeToText
31+ , encodeText'
32+ , decodeText'
33+ , encodeText
2734 , decodeText
28− , decodeFromText
29− , decodeFromTextWrap
30− -- * Convert to/from 'ScalarObejct's
31− , encodeScalar
32− , decodeScalar
33− -- * Files
34− , encodeFile
35− , encodeFileToText
36− , decodeFile
37− , decodeFileFromTextWrap
35+ , decodeTextSuccess
3836#if TEST
3937 , testSuite
4038#endif
@@ -42,20 +40,17 @@ module Text.Yaml
4240
4341import Prelude hiding (readList)
4442import Text.Libyaml
45−import qualified Data.ByteString as B
46−import Data.Object
43+import Data.ByteString (ByteString)
4744import Data.Object.Text
48−import Data.Object.Scalar
4945import System.IO.Unsafe
50−import Control.Arrow (first)
51−import Control.Monad (liftM, join)
52−import Control.Monad.Trans
46+import Control.Monad (join)
5347import Data.Convertible.Text
5448import Data.Attempt
5549
56−import Data.Text.Lazy (Text)
50+import Data.Object.Yaml
5751
5852#if TEST
53+import Data.Object
5954import Test.Framework (testGroup, Test)
6055import Test.Framework.Providers.HUnit
6156import Test.Framework.Providers.QuickCheck (testProperty)
@@ -63,187 +58,101 @@ import Test.HUnit hiding (Test, path)
6358import Test.QuickCheck
6459
6560import Control.Monad (replicateM)
66−import Control.Arrow ((***))
6761import qualified Data.Text.Lazy as LT
6862import qualified Data.ByteString.Lazy as BL
63+import qualified Data.ByteString as B
64+import Data.Attempt
65+import Control.Arrow ((***))
6966#endif
7067
7168-- Low level, non-exported functions
7269encode' :: MonadFailure YamlException m
73− => TextObject
74− -> IO (m B.ByteString)
75−encode' o = do
76− let events = objectToEvents o
77− result <- withEmitter $ flip emitEvents events
78− return $ do
79− result' <- result
80− return result'
70+ => YamlObject
71+ -> IO (m ByteString)
72+encode' = withEmitter . flip emitEvents . convertSuccess
8173
8274decode' :: MonadFailure YamlException m
83− => B.ByteString
84− -> IO (m TextObject)
75+ => ByteString
76+ -> IO (m YamlObject)
8577decode' bs = do
86− events <- withParser (convertSuccess bs) parserParse
87− return $ liftM eventsToTextObject events
88−
89−-- Text API
90−-- FIXME: this *should* be in a MonadFailure
91−
92−-- FIXME: I think the To and From below are backwards. Maybe just say convert?
93−encodeText :: ConvertSuccess B.ByteString a
94− => TextObject
95− -> a
96−encodeText = convertSuccess . unsafePerformIO . join . encode'
97−
98−encodeToText :: (ConvertSuccess B.ByteString a, ToObject x Text Text)
99− => x
100− -> a
101−encodeToText = convertSuccess . unsafePerformIO . join . encode' . toTextObject
102−
103−decodeText :: (ConvertSuccess a B.ByteString,
104− MonadFailure YamlException m)
105− => a
106− -> m TextObject
107−decodeText = unsafePerformIO . decode' . convertSuccess
108−
109−decodeFromText :: (ConvertSuccess a B.ByteString,
110− FromObject x Text Text)
111− => a
112− -> Attempt x
113−decodeFromText a = decodeText a >>= fromObject
114−
115−decodeFromTextWrap :: (ConvertSuccess a B.ByteString,
116− FromObject x Text Text,
117− MonadFailure YamlException m,
118− MonadFailure FromObjectException m
119− )
120− => a
121− -> m x
122−decodeFromTextWrap a = decodeText a >>= fromObjectWrap
123−
124−-- Scalar API
125−-- FIXME: this *should* be in a MonadFailure...
126−encodeScalar :: ConvertSuccess B.ByteString a
127− => ScalarObject
128− -> a
129−encodeScalar = convertSuccess . unsafePerformIO . join . encode' . toTextObject
130−
131−decodeScalar :: (ConvertSuccess a B.ByteString,
132− MonadFailure YamlException m)
133− => a
134− -> m ScalarObject
135−decodeScalar = liftM toScalarObject . unsafePerformIO . decode' . convertSuccess
136−
137−-- File API
138−encodeFile :: (MonadIO m, MonadFailure YamlException m)
139− => FilePath
140− -> TextObject
141− -> m ()
142−encodeFile path o = do
143− content <- liftIO $ encode' o
144− content' <- content
145− liftIO $ B.writeFile path content'
146−
147−encodeFileToText :: (ToObject x Text Text,
148− MonadIO m,
149− MonadFailure YamlException m
150− )
151− => FilePath
152− -> x
153− -> m ()
154−encodeFileToText fp = encodeFile fp . toTextObject
155−
156−decodeFile :: (MonadFailure YamlException m,
157− MonadIO m)
158− => FilePath
159− -> m TextObject
160−decodeFile path = do
161− contents <- liftIO $ B.readFile path
162− join $ liftIO $ decode' contents
163−
164−decodeFileFromTextWrap :: (MonadFailure YamlException m,
165− MonadFailure FromObjectException m,
166− MonadIO m,
167− FromObject x Text Text
168− )
169− => FilePath
170− -> m x
171−decodeFileFromTextWrap path = decodeFile path >>= fromObjectWrap
172−
173−-- The real worker functions
174−objectToEvents :: TextObject -> [Event]
175−objectToEvents y = concat
176− [ [EventStreamStart, EventDocumentStart]
177− , writeSingle y
178− , [EventDocumentEnd, EventStreamEnd]] where
179− writeSingle :: TextObject -> [Event]
180− writeSingle (Scalar text) = [EventScalar $ convertSuccess text]
181− writeSingle (Sequence ys) =
182− (EventSequenceStart : concatMap writeSingle ys)
183− ++ [EventSequenceEnd]
184− writeSingle (Mapping pairs) =
185− EventMappingStart : concatMap writePair pairs ++ [EventMappingEnd]
186− writePair :: (Text, TextObject) -> [Event]
187− writePair (k, v) = EventScalar (convertSuccess k) : writeSingle v
188−
189−eventsToTextObject :: [Event] -> TextObject
190−eventsToTextObject = fst . readSingle . dropWhile isIgnored where
191− isIgnored EventAlias = False
192− isIgnored (EventScalar _) = False
193− isIgnored EventSequenceStart = False
194− isIgnored EventSequenceEnd = False
195− isIgnored EventMappingStart = False
196− isIgnored EventMappingEnd = False
197− isIgnored _ = True
198− readSingle :: [Event] -> (TextObject, [Event])
199− readSingle [] = error "readSingle: no more events"
200− readSingle (EventScalar bs:rest) =
201− (Scalar $ convertSuccess bs, rest)
202− readSingle (EventSequenceStart:rest) = readList [] rest
203− readSingle (EventMappingStart:rest) = readMap [] rest
204− readSingle (x:_) = error $ "readSingle: " ++ show x
205− readList :: [TextObject] -> [Event] -> (TextObject, [Event])
206− readList nodes (EventSequenceEnd:rest) =
207− (Sequence $ reverse nodes, rest)
208− readList nodes events =
209− let (next, rest) = readSingle events
210− in readList (next : nodes) rest
211− readMap :: [(B.ByteString, TextObject)]
212− -> [Event]
213− -> (TextObject, [Event])
214− readMap pairs (EventMappingEnd:rest) =
215− (Mapping $ map (first convertSuccess) $ reverse pairs, rest)
216− readMap pairs (EventScalar bs:events) =
217− let (next, rest) = readSingle events
218− in readMap ((bs, next) : pairs) rest
219− readMap _ (e:_) = error $ "Unexpected event in readMap: " ++ show e
220− readMap _ [] = error "Unexpected empty event list in readMap"
78+ events <- withParser bs parserParse
79+ return $ events >>= eventsToYamlObject
80+
81+-- Convert to YamlObject directly
82+encodeYaml' :: YamlObject -> ByteString
83+encodeYaml' = unsafePerformIO . join . encode'
84+
85+decodeYaml' :: MonadFailure YamlException m => ByteString -> m YamlObject
86+decodeYaml' = unsafePerformIO . decode'
87+
88+-- Convert to YamlObject conversions
89+encodeYaml :: ConvertSuccess x YamlObject => x -> ByteString
90+encodeYaml = encodeYaml' . convertSuccess
91+
92+decodeYaml :: ( ConvertAttempt YamlObject x
93+ , Failure ConversionException m
94+ , MonadFailure YamlException m
95+ )
96+ => ByteString
97+ -> m x
98+decodeYaml b = decodeYaml' b >>= convertAttemptWrap
99+
100+decodeYamlSuccess :: ( ConvertSuccess YamlObject x
101+ , MonadFailure YamlException m
102+ )
103+ => ByteString
104+ -> m x
105+decodeYamlSuccess = fmap convertSuccess . decodeYaml'
106+
107+-- TextObjects
108+encodeText' :: TextObject -> ByteString
109+encodeText' = encodeYaml
110+
111+decodeText' :: MonadFailure YamlException m => ByteString -> m TextObject
112+decodeText' = decodeYamlSuccess
113+
114+-- TextObject conversions
115+encodeText :: ConvertSuccess x TextObject => x -> ByteString
116+encodeText = encodeText' . convertSuccess
117+
118+decodeText :: ( MonadFailure YamlException m
119+ , ConvertAttempt TextObject x
120+ , Failure ConversionException m
121+ )
122+ => ByteString
123+ -> m x
124+decodeText bs = decodeText' bs >>= convertAttemptWrap
125+
126+decodeTextSuccess :: ( MonadFailure YamlException m
127+ , ConvertSuccess TextObject x
128+ )
129+ => ByteString
130+ -> m x
131+decodeTextSuccess = fmap convertSuccess . decodeText'
221132
222133#if TEST
223134newtype MyString = MyString String
224135 deriving (Eq, Show)
225−instance ConvertAttempt MyString Text where
226− convertAttempt = return . convertSuccess
227136instance ConvertSuccess MyString Text where
228137 convertSuccess (MyString s) = convertSuccess s
229−instance ConvertAttempt Text MyString where
230− convertAttempt = return . convertSuccess
231138instance ConvertSuccess Text MyString where
232139 convertSuccess = MyString . convertSuccess
140+instance ConvertSuccess (Object Text Text) (Object MyString MyString) where
141+ convertSuccess = mapKeysValues convertSuccess convertSuccess
142+instance ConvertSuccess (Object MyString MyString) (Object Text Text) where
143+ convertSuccess = mapKeysValues convertSuccess convertSuccess
233144
234145myEquals :: Eq v => Attempt v -> Attempt v -> Bool
235−myEquals (Success v1) (Success v2) = v1 == v2
236−myEquals _ _ = False
146+myEquals a1 a2
147+ | isSuccess a1 && isSuccess a2 = fromSuccess a1 == fromSuccess a2
148+ | otherwise = False
237149
238150propEncodeDecode :: Object MyString MyString -> Bool
239151propEncodeDecode o =
240− fmap h2 (decodeText (encodeText (h1 o) :: B.ByteString))
241− `myEquals` Success o
242− where
243− h1 = mapKeysValues convertSuccess convertSuccess
244− h2 = mapKeysValues convertSuccess convertSuccess
152+ (decodeTextSuccess $ encodeText' $ convertSuccess o)
153+ `myEquals` return o
245154
246−toSBS :: ConvertSuccess a B.ByteString => a -> B.ByteString
155+toSBS :: ConvertSuccess a ByteString => a -> ByteString
247156toSBS = convertSuccess
248157
249158toLBS :: ConvertSuccess a BL.ByteString => a -> BL.ByteString
@@ -258,15 +167,19 @@ caseEmptyStrings = do
258167 ]
259168 let m' = map (toSBS *** toSBS) m
260169 let m'' = map (toLBS *** toLBS) m
261− let test' :: (ToObject x Text Text, FromObject x Text Text, Eq x, Show x)
170+ let test' :: (ConvertSuccess x TextObject,
171+ ConvertSuccess TextObject x,
172+ Eq x,
173+ Show x)
262174 => x
263175 -> Assertion
264− test' x = Just x @=?
265− fa (decodeText (encodeText (toTextObject x) :: String)
266− >>= fromTextObject)
267− test' m
268− test' m'
269− test' m''
176+ test' x = do
177+ let bs = encodeText x
178+ x' <- decodeTextSuccess bs
179+ x' @?= x
180+ test' $ toTextObject m
181+ test' $ toTextObject m'
182+ test' $ toTextObject m''
270183
271184caseLargeObjects :: Assertion
272185caseLargeObjects = do
@@ -274,10 +187,10 @@ caseLargeObjects = do
274187 level2 = toTextObject $ replicate 10000 level3
275188 level1 = toTextObject $ zip (map (: []) ['A'..'Z']) $ repeat level2
276189 decoded :: Maybe TextObject
277− decoded = decodeText $ (encodeText level1 :: Text)
190+ decoded = decodeText $ encodeText level1
278191 assertEqual "encode/decode identity" decoded $ Just level1
279192 putStrLn "encoding the file..."
280− encodeFile "test.yaml" level1
193+ B.writeFile "test.yaml" $ encodeText' level1
281194
282195testSuite :: Test
283196testSuite = testGroup "Text.Yaml"
c/helper.c+17
@@ -90,3 +90,20 @@ unsigned long get_scalar_length(yaml_event_t *e)
9090{
9191 return e->data.scalar.length;
9292}
93+
94+unsigned char * get_scalar_tag(yaml_event_t *e)
95+{
96+ unsigned char *s = e->data.scalar.tag;
97+ if (!s) s = "";
98+ return s;
99+}
100+
101+unsigned long get_scalar_tag_len(yaml_event_t *e)
102+{
103+ return strlen(get_scalar_tag(e));
104+}
105+
106+int get_scalar_style(yaml_event_t *e)
107+{
108+ return e->data.scalar.style;
109+}
c/helper.h+4
@@ -26,4 +26,8 @@ int get_event_type(yaml_event_t *e);
2626unsigned char * get_scalar_value(yaml_event_t *e);
2727unsigned long get_scalar_length(yaml_event_t *e);
2828
29+unsigned char * get_scalar_tag(yaml_event_t *e);
30+unsigned long get_scalar_tag_len(yaml_event_t *e);
31+int get_scalar_style(yaml_event_t *e);
32+
2933#endif /* __HELPER_H__ */
Test.hs → runtests.hsrenamed

The content is the same.

yaml.cabal+3−2
@@ -35,6 +35,7 @@ library
3535 convertible-text >= 0.0.0 && < 0.1,
3636 attempt >= 0.2.0 && < 0.3
3737 exposed-modules: Text.Yaml
38+ Data.Object.Yaml
3839 other-modules: Text.Libyaml
3940 ghc-options: -Wall
4041 c-sources: c/helper.c,
@@ -48,7 +49,7 @@ library
4849 c/writer.c
4950 include-dirs: c
5051
51−executable yamltest
52+executable runtests
5253 if flag(buildtests)
5354 Buildable: True
5455 cpp-options: -DTEST
@@ -70,4 +71,4 @@ executable yamltest
7071 c/scanner.c,
7172 c/writer.c
7273 include-dirs: c
73− main-is: Test.hs
74+ main-is: runtests.hs