Permalink
Browse files

Have decode return Either instead of Maybe

  • Loading branch information...
1 parent c7b4136 commit 4bbee6f3f371e04ebedcc04cbadf837b18eacfd1 @tibbe committed Jun 27, 2012
Showing with 25 additions and 30 deletions.
  1. +15 −14 Data/Ceason.hs
  2. +4 −0 Data/Ceason/Encode.hs
  3. +6 −16 Data/Ceason/Parser/Internal.hs
View
@@ -55,33 +55,34 @@ import Data.Ceason.Types
-- $typeconversion
--
--- There are two ways to convert between CSV records and data types:
--- index based and name based.
+-- There are two ways to convert CSV records to and from and
+-- user-defined data types: index-based conversion and name-based
+-- conversion.
-- $indexbased
--
--- Index-based conversion lets you convert CSV records to data types
--- by referring to a field's position (its index) in the file. The
--- first column in a CSV file is given index 0, the second index 1,
--- and so on.
+-- Index-based conversion lets you convert CSV records to and from
+-- user-defined data types by referring to a field's position (its
+-- index) in the record. The first column in a CSV file is given index
+-- 0, the second index 1, and so on.
-- $namebased
--
--- Name-based conversion lets you convert CSV records to data types by
--- referring to a field's name. The names of the fields are defined
--- by the first line in the file, also known as the header.
--- Name-based conversion is more robust to changes in the file
--- structure e.g. to reording or addition of columns, but can be a bit
--- slower.
+-- Name-based conversion lets you convert CSV records to and from
+-- user-defined data types by referring to a field's name. The names
+-- of the fields are defined by the first line in the file, also known
+-- as the header. Name-based conversion is more robust to changes in
+-- the file structure e.g. to reording or addition of columns, but can
+-- be a bit slower.
-- | Efficiently deserialize CSV records from a lazy
-- 'L.ByteString'. If this fails due to incomplete or invalid input,
-- 'Nothing' is returned.
-decode :: FromRecord a => L.ByteString -> Maybe (Vector a)
+decode :: FromRecord a => L.ByteString -> Either String (Vector a)
decode = decodeWith csv (parse . traverse parseRecord)
decodeWithHeader :: FromNamedRecord a => L.ByteString
-> Either String (Header, Vector a)
decodeWithHeader =
- decodeWithEither csvWithHeader
+ decodeWith csvWithHeader
(\ (hdr, vs) -> (,) <$> pure hdr <*> (parse $ traverse parseNamedRecord vs))
View
@@ -31,6 +31,10 @@ encode = toLazyByteString
. V.toList . toRecord)
. V.toList
+-- TODO: Implement
+encodeWithHeader :: ToNamedRecord a => V.Vector a -> L.ByteString
+encodeWithHeader = undefined
+
unlines :: [Builder] -> Builder
unlines [] = mempty
unlines (b:bs) = b <> fromString "\r\n" <> unlines bs
@@ -5,7 +5,6 @@ module Data.Ceason.Parser.Internal
, record
, field
, decodeWith
- , decodeWithEither
) where
import Blaze.ByteString.Builder (fromByteString, toByteString)
@@ -33,7 +32,6 @@ csv = do
endOfInput
return (V.fromList (removeBlankLines vals))
--- TODO: Rename headers to header everywhere.
csvWithHeader :: AL.Parser (Header, V.Vector NamedRecord)
csvWithHeader = do
hdr <- header
@@ -117,20 +115,12 @@ unescape = toByteString <$> go mempty where
doubleQuote :: Word8
doubleQuote = 34
-decodeWith :: AL.Parser a -> (a -> Result b) -> L.ByteString -> Maybe b
+decodeWith :: AL.Parser a -> (a -> Result b) -> L.ByteString -> Either String b
decodeWith p to s =
case AL.parse p s of
- AL.Done _ v -> case to v of
- Success a -> Just a
- _ -> Nothing
- _ -> Nothing
-{-# INLINE decodeWith #-}
-
-decodeWithEither :: AL.Parser a -> (a -> Result b) -> L.ByteString -> Either String b
-decodeWithEither p to s =
- case AL.parse p s of
- AL.Done _ v -> case to v of
+ AL.Done _ v -> case to v of
Success a -> Right a
- Error msg -> Left msg
- AL.Fail s _ msg -> Left $ msg ++ " at: " ++ BL8.unpack s
-{-# INLINE decodeWithEither #-}
+ Error msg -> Left $ "conversion error: " ++ msg
+ AL.Fail s _ msg -> Left $ "parse error (" ++ msg ++ ") at \"" ++
+ show (BL8.unpack s) ++ "\""
+{-# INLINE decodeWith #-}

0 comments on commit 4bbee6f

Please sign in to comment.