@@ -31,6 +31,8 @@ module Data.Yaml
3131 , encodeFile
3232 , decode
3333 , decodeFile
34+ -- ** Better error information
35+ , decodeEither
3436 ) where
3537
3638import qualified Text.Libyaml as Y
@@ -231,16 +233,23 @@ parseM a front = do
231233decode :: FromJSON a
232234 => ByteString
233235 -> Maybe a
234−decode bs = unsafePerformIO $ fmap (either (const Nothing) id) $ decodeHelper (Y.decode bs)
236+decode bs = unsafePerformIO
237+ $ fmap (either (const Nothing) (either (const Nothing) Just))
238+ $ decodeHelper (Y.decode bs)
235239
236240decodeFile :: FromJSON a
237241 => FilePath
238242 -> IO (Maybe a)
239−decodeFile fp = decodeHelper (Y.decodeFile fp) >>= either throwIO return
243+decodeFile fp = decodeHelper (Y.decodeFile fp) >>= either throwIO (return . either (const Nothing) id)
244+
245+decodeEither :: FromJSON a => ByteString -> Either String a
246+decodeEither bs = unsafePerformIO
247+ $ fmap (either (Left . show) id)
248+ $ decodeHelper (Y.decode bs)
240249
241250decodeHelper :: FromJSON a
242251 => C.Source Parse Y.Event
243− -> IO (Either ParseException (Maybe a))
252+ -> IO (Either ParseException (Either String a))
244253decodeHelper src = do
245254 x <- try $ C.runResourceT $ flip evalStateT Map.empty $ src C.$$ parse
246255 case x of
@@ -248,7 +257,7 @@ decodeHelper src = do
248257 | Just pe <- fromException e -> return $ Left pe
249258 | Just ye <- fromException e -> return $ Left $ InvalidYaml $ Just $ show (ye :: YamlException)
250259 | otherwise -> throwIO e
251− Right y -> return $ Right $ parseMaybe parseJSON y
260+ Right y -> return $ Right $ parseEither parseJSON y
252261
253262array :: [Value] -> Value
254263array = Array . V.fromList