Skip to content

Commit

Permalink
Export named function equivalents of operators
Browse files Browse the repository at this point in the history
Fixes #24
  • Loading branch information
tibbe committed Nov 21, 2012
1 parent e015485 commit 3a07917
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 5 deletions.
5 changes: 5 additions & 0 deletions Data/Csv.hs
Expand Up @@ -51,6 +51,7 @@ module Data.Csv
, FromRecord(..)
, Parser
, runParser
, index
, (.!)
, ToRecord(..)
, record
Expand All @@ -59,16 +60,20 @@ module Data.Csv
-- ** Name-based record conversion
-- $namebased
, FromNamedRecord(..)
, lookup
, (.:)
, ToNamedRecord(..)
, namedRecord
, namedField
, (.=)

-- ** Field conversion
, FromField(..)
, ToField(..)
) where

import Prelude hiding (lookup)

import Data.Csv.Conversion
import Data.Csv.Encoding
import Data.Csv.Types
Expand Down
34 changes: 29 additions & 5 deletions Data/Csv/Conversion.hs
Expand Up @@ -20,8 +20,11 @@ module Data.Csv.Conversion
, runParser

-- * Accessors
, index
, (.!)
, lookup
, (.:)
, namedField
, (.=)
, record
, namedRecord
Expand All @@ -48,7 +51,7 @@ import qualified Data.Vector as V
import qualified Data.Vector.Unboxed as U
import Data.Word
import GHC.Float (double2Float)
import Prelude hiding (takeWhile)
import Prelude hiding (lookup, takeWhile)

import Data.Csv.Conversion.Internal
import Data.Csv.Types
Expand Down Expand Up @@ -611,22 +614,40 @@ typeError typ s mmsg =
-- | Retrieve the /n/th field in the given record. The result is
-- 'empty' if the value cannot be converted to the desired type.
-- Raises an exception if the index is out of bounds.
--
-- If you're certain that the index is not out of bounds, using
-- @'parseField' (`V.unsafeIndex` v idx)@ is somewhat faster.
index :: FromField a => Record -> Int -> Parser a
index v idx = parseField (v ! idx)
{-# INLINE index #-}

-- | Alias for 'index'.
(.!) :: FromField a => Record -> Int -> Parser a
v .! idx = parseField (v ! idx)
(.!) = index
{-# INLINE (.!) #-}

-- | Retrieve a field in the given record by name. The result is
-- 'empty' if the field is missing or if the value cannot be converted
-- to the desired type.
(.:) :: FromField a => NamedRecord -> B.ByteString -> Parser a
m .: name = maybe (fail err) parseField $ HM.lookup name m
lookup :: FromField a => NamedRecord -> B.ByteString -> Parser a
lookup m name = maybe (fail err) parseField $ HM.lookup name m
where err = "no field named " ++ show (B8.unpack name)
{-# INLINE lookup #-}

-- | Alias for 'lookup'.
(.:) :: FromField a => NamedRecord -> B.ByteString -> Parser a
(.:) = lookup
{-# INLINE (.:) #-}

-- | Construct a pair from a name and a value. For use with
-- 'namedRecord'.
namedField :: ToField a => B.ByteString -> a -> (B.ByteString, B.ByteString)
namedField name val = (name, toField val)
{-# INLINE namedField #-}

-- | Alias for 'namedField'.
(.=) :: ToField a => B.ByteString -> a -> (B.ByteString, B.ByteString)
name .= val = (name, toField val)
(.=) = namedField
{-# INLINE (.=) #-}

-- | Construct a record from a list of 'B.ByteString's. Use 'toField'
Expand Down Expand Up @@ -707,6 +728,9 @@ apP d e = do
-- | Run a 'Parser', returning either @'Left' errMsg@ or @'Right'
-- result@. Forces the value in the 'Left' or 'Right' constructors to
-- weak head normal form.
--
-- You most likely won't need to use this function directly, but it's
-- included for completeness.
runParser :: Parser a -> Either String a
runParser p = unParser p left right
where
Expand Down

0 comments on commit 3a07917

Please sign in to comment.