@@ -1,6 +1,7 @@
1{-# LANGUAGE FlexibleInstances #-}
1{-# LANGUAGE FlexibleInstances #-}
2{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE MultiParamTypeClasses #-}
3{-# LANGUAGE MultiParamTypeClasses #-}
4---------------------------------------------------------
5---------------------------------------------------------
6-- Module : Text.Yaml
7-- Module : Text.Yaml
@@ -21,84 +22,97 @@ module Text.Yaml
21 , encodeFile
22 , encodeFile
23 , decodeFile
24 , decodeFile
24 , testSuite
26 , testSuite
27import Prelude hiding (readList)
30import Prelude hiding (readList)
28import Text.Libyaml
31import Text.Libyaml
29import qualified Data.ByteString as B
32import qualified Data.ByteString as B
30−import Data.ByteString.Class
33+import qualified Data.ByteString.Lazy as BL
31import Data.Object
34import Data.Object
32−import Data.Object.Raw
35+import Data.Object.Text
33import System.IO.Unsafe
36import System.IO.Unsafe
34−import Control.Arrow (first, (***))
37+import Control.Arrow (first)
35−import Control.Monad (replicateM, liftM)
38+import Control.Monad (liftM, join)
36import Control.Monad.Trans
39import Control.Monad.Trans
37import Control.Monad.Attempt
40import Control.Monad.Attempt
41+import Data.Convertible
43+import Data.Text.Lazy (Text)
44+import qualified Data.Text.Lazy as LT
45+import qualified Data.Text.Lazy.Encoding as LTE
39import Test.Framework (testGroup, Test)
48import Test.Framework (testGroup, Test)
40import Test.Framework.Providers.HUnit
49import Test.Framework.Providers.HUnit
41import Test.Framework.Providers.QuickCheck (testProperty)
50import Test.Framework.Providers.QuickCheck (testProperty)
42import Test.HUnit hiding (Test, path)
51import Test.HUnit hiding (Test, path)
43import Test.QuickCheck
52import Test.QuickCheck
45−import Control.Exception
55+encode :: (ConvertSuccess B.ByteString a, ToObject o Text Text) => o -> a
47−encode :: (StrictByteString bs, ToObject o Raw Raw) => o -> bs
48encode = unsafePerformIO . encode'
56encode = unsafePerformIO . encode'
50−decode :: (StrictByteString bs, FromObject o Raw Raw, MonadFailure SomeException m)
58+decode :: (ConvertSuccess a B.ByteString,
51− => bs
59+ MonadFailure YamlException m)
53−decode bs = unsafePerformIO $ do
62+decode = unsafePerformIO . decode'
54− a <- runAttemptT $ decode' bs -- FIXME
56− Success s -> return $ return s
57− Failure e -> return $ failure e
59−encodeFile :: ToObject o Raw Raw => FilePath -> o -> IO ()
64+encodeFile :: ToObject o Text Text => FilePath -> o -> IO ()
60−encodeFile path o = encode' o >>= B.writeFile path
65+encodeFile path o = encode' o >>= ltWriteFile path
62−decodeFile :: (FromObject o Raw Raw, MonadFailure SomeException m, MonadIO m)
63− => FilePath
67+ltWriteFile :: FilePath -> Text -> IO ()
64− -> m o
68+ltWriteFile fp = BL.writeFile fp . LTE.encodeUtf8
65−decodeFile path = liftIO (B.readFile path) >>= decode'
67−encode' :: (StrictByteString bs, ToObject o Raw Raw) => o -> IO bs
70+decodeFile :: (MonadFailure YamlException m,
75+ contents <- liftIO (ltReadFile path)
76+ join $ liftIO $ decode' contents
78+ltReadFile :: FilePath -> IO Text
79+ltReadFile = fmap LTE.decodeUtf8 . BL.readFile
81+encode' :: (ConvertSuccess B.ByteString a,
82+ ToObject o Text Text)
68encode' o =
85encode' o =
69 let events = objectToEvents $ toObject o
86 let events = objectToEvents $ toObject o
70 result = withEmitter $ flip emitEvents events
87 result = withEmitter $ flip emitEvents events
71− in fromStrictByteString `fmap` joinAttempt result
88+ in convertSuccess `fmap` joinAttempt result
73−decode' :: (StrictByteString bs, FromObject o Raw Raw, MonadIO m,
90+decode' :: (ConvertSuccess a B.ByteString,
74− MonadFailure SomeException m)
91+ MonadFailure YamlException m
77decode' bs = do
95decode' bs = do
78− events <- liftIO $ withParser (toStrictByteString bs) parserParse
96+ events <- withParser (convertSuccess bs) parserParse
79− attempt failure' (myFA . fromObject . eventsToRawObject) events
97+ return $ liftM eventsToTextObject events
81− myFA = attempt failure' return
82− failure' :: (MonadFailure SomeException m, Exception e) => e -> m a
83− failure' = failure . SomeException
85−objectToEvents :: RawObject -> [Event]
99+objectToEvents :: TextObject -> [Event]
86objectToEvents y = concat
100objectToEvents y = concat
87 [ [EventStreamStart, EventDocumentStart]
101 [ [EventStreamStart, EventDocumentStart]
88 , writeSingle y
102 , writeSingle y
89 , [EventDocumentEnd, EventStreamEnd]] where
103 , [EventDocumentEnd, EventStreamEnd]] where
90− writeSingle :: RawObject -> [Event]
104+ writeSingle :: TextObject -> [Event]
91− writeSingle (Scalar (Raw bs)) = [EventScalar $ toStrictByteString bs]
105+ writeSingle (Scalar text) = [EventScalar $ convertSuccess text]
92 writeSingle (Sequence ys) =
106 writeSingle (Sequence ys) =
93 (EventSequenceStart : concatMap writeSingle ys)
107 (EventSequenceStart : concatMap writeSingle ys)
94 ++ [EventSequenceEnd]
108 ++ [EventSequenceEnd]
95 writeSingle (Mapping pairs) =
109 writeSingle (Mapping pairs) =
96 EventMappingStart : concatMap writePair pairs ++ [EventMappingEnd]
110 EventMappingStart : concatMap writePair pairs ++ [EventMappingEnd]
97− writePair :: (Raw, RawObject) -> [Event]
111+ writePair :: (Text, TextObject) -> [Event]
98− writePair (Raw k, v) = EventScalar (fromLazyByteString k) : writeSingle v
112+ writePair (k, v) = EventScalar (convertSuccess k) : writeSingle v
100−eventsToRawObject :: [Event] -> RawObject
114+eventsToTextObject :: [Event] -> TextObject
101−eventsToRawObject = fst . readSingle . dropWhile isIgnored where
115+eventsToTextObject = fst . readSingle . dropWhile isIgnored where
102 isIgnored EventAlias = False
116 isIgnored EventAlias = False
103 isIgnored (EventScalar _) = False
117 isIgnored (EventScalar _) = False
104 isIgnored EventSequenceStart = False
118 isIgnored EventSequenceStart = False
@@ -106,37 +120,40 @@ eventsToRawObject = fst . readSingle . dropWhile isIgnored where
106 isIgnored EventMappingStart = False
120 isIgnored EventMappingStart = False
107 isIgnored EventMappingEnd = False
121 isIgnored EventMappingEnd = False
108 isIgnored _ = True
122 isIgnored _ = True
109− readSingle :: [Event] -> (RawObject, [Event])
123+ readSingle :: [Event] -> (TextObject, [Event])
110 readSingle [] = error "readSingle: no more events"
124 readSingle [] = error "readSingle: no more events"
111 readSingle (EventScalar bs:rest) =
125 readSingle (EventScalar bs:rest) =
112− (Scalar $ Raw $ toLazyByteString bs, rest)
126+ (Scalar $ convertSuccess bs, rest)
113 readSingle (EventSequenceStart:rest) = readList [] rest
127 readSingle (EventSequenceStart:rest) = readList [] rest
114 readSingle (EventMappingStart:rest) = readMap [] rest
128 readSingle (EventMappingStart:rest) = readMap [] rest
115 readSingle (x:_) = error $ "readSingle: " ++ show x
129 readSingle (x:_) = error $ "readSingle: " ++ show x
116− readList :: [RawObject] -> [Event] -> (RawObject, [Event])
130+ readList :: [TextObject] -> [Event] -> (TextObject, [Event])
117 readList nodes (EventSequenceEnd:rest) =
131 readList nodes (EventSequenceEnd:rest) =
118 (Sequence $ reverse nodes, rest)
132 (Sequence $ reverse nodes, rest)
119 readList nodes events =
133 readList nodes events =
120 let (next, rest) = readSingle events
134 let (next, rest) = readSingle events
121 in readList (next : nodes) rest
135 in readList (next : nodes) rest
122− readMap :: [(B.ByteString, RawObject)]
136+ readMap :: [(B.ByteString, TextObject)]
123 -> [Event]
137 -> [Event]
124− -> (RawObject, [Event])
138+ -> (TextObject, [Event])
125 readMap pairs (EventMappingEnd:rest) =
139 readMap pairs (EventMappingEnd:rest) =
126− (Mapping $ map (first $ Raw . toLazyByteString) $ reverse pairs, rest)
140+ (Mapping $ map (first convertSuccess) $ reverse pairs, rest)
127 readMap pairs (EventScalar bs:events) =
141 readMap pairs (EventScalar bs:events) =
128 let (next, rest) = readSingle events
142 let (next, rest) = readSingle events
129− in readMap ((fromStrictByteString bs, next) : pairs) rest
143+ in readMap ((bs, next) : pairs) rest
130 readMap _ (e:_) = error $ "Unexpected event in readMap: " ++ show e
144 readMap _ (e:_) = error $ "Unexpected event in readMap: " ++ show e
131 readMap _ [] = error "Unexpected empty event list in readMap"
145 readMap _ [] = error "Unexpected empty event list in readMap"
133newtype MyString = MyString String
147newtype MyString = MyString String
134 deriving (Eq, Show)
148 deriving (Eq, Show)
135−instance ToScalar MyString Raw where
149+instance ConvertAttempt MyString Text where
136− toScalar (MyString s) = toScalar s
150+ convertAttempt = return . convertSuccess
151+instance ConvertSuccess MyString Text where
152+ convertSuccess (MyString s) = convertSuccess s
137−instance FromScalar MyString Raw where
153+instance ConvertAttempt Text MyString where
138− fromScalar raw = MyString `liftM` fromScalar raw
154+ convertAttempt raw = MyString `liftM` convertAttempt raw
140propEncodeDecode :: Object MyString MyString -> Bool
157propEncodeDecode :: Object MyString MyString -> Bool
141propEncodeDecode o = fromAttempt (decode (encode o :: B.ByteString))
158propEncodeDecode o = fromAttempt (decode (encode o :: B.ByteString))
142 == Just o
159 == Just o
@@ -174,3 +191,4 @@ instance Arbitrary MyString where
174 size <- arbitrary
191 size <- arbitrary
175 s <- replicateM (size `mod` 5) $ elements ['A'..'Z']
192 s <- replicateM (size `mod` 5) $ elements ['A'..'Z']
176 return $! MyString s
193 return $! MyString s