{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE ScopedTypeVariables #-} module DSV.FileStrictCsvRead ( readCsvFileStrictWithZippedHeader , readCsvFileStrictWithoutHeader , readCsvFileStrictIgnoringHeader ) where import DSV.ByteString import DSV.CommonDelimiters import DSV.FileStrictRead import DSV.IO import DSV.ParseStop import DSV.Prelude import DSV.Vector {- | Often, the first line of a CSV file is a row that gives the name of each column in the file. If present, this row is called the /header/. === Example CSV file: > Date,Vendor,Price,Product > 2019-03-24,Acme Co,$599.89,Dehydrated boulders > 2019-04-18,Acme Co,$24.95,Earthquake pills Result: > ( ParseComplete, > [ [ ("Date", "2019-03-24"), > ("Vendor", "Acme Co"), > ("Price", "$599.89"), > ("Product", "Dehydrated boulders") ], > [ ("Date", "2019-04-18"), > ("Vendor", "Acme Co"), > ("Price", "$24.95"), > ("Product", "Earthquake pills") ] ] ) === Example with a malformed file CSV file: > Date,Vendor,Price,Product > 2019-03-24,Acme Co,$599.89,Dehydrated boulders > 2019-03-29,Store Mart,"$"8.14,Coffee beans > 2019-04-18,Acme Co,$24.95,Earthquake pills Notice the quotation marks around the dollar sign on the third line. Result: > ( ParseIncomplete, > [ [ ("Date", "2019-03-24"), > ("Vendor", "Acme Co"), > ("Price", "$599.89"), > ("Product", "Dehydrated boulders") ] ) The result includes the first row of data because it appears /before/ the malformed line. All data that comes /after/ the erroneous quotation is discarded, even though the final line does contain correctly formatted data. -} readCsvFileStrictWithZippedHeader :: forall m . MonadIO m => FilePath -- ^ The path of a CSV file to read -> m (ParseStop, (Vector (Vector (ByteString, ByteString)))) readCsvFileStrictWithZippedHeader :: FilePath -> m (ParseStop, Vector (Vector (ByteString, ByteString))) readCsvFileStrictWithZippedHeader FilePath fp = Delimiter -> FilePath -> m (ParseStop, Vector (Vector (ByteString, ByteString))) forall (m :: * -> *). MonadIO m => Delimiter -> FilePath -> m (ParseStop, Vector (Vector (ByteString, ByteString))) readDsvFileStrictWithZippedHeader Delimiter comma FilePath fp {- | Not every CSV file has a header row. Use this function to read a CSV file that does /not/ have a header. === Example CSV file: > 2019-03-24,Acme Co,$599.89,Dehydrated boulders > 2019-04-18,Acme Co,$24.95,Earthquake pills Result: > ( ParseComplete, > [ ["2019-03-24", "Acme Co", "$599.89", "Dehydrated boulders"], > ["2019-04-18", "Acme Co", "$24.95", "Earthquake pills"] ] ) === Example with a malformed file CSV file: > 2019-03-24,Acme Co,$599.89,Dehydrated boulders > 2019-03-29,Store Mart,"$"8.14,Coffee beans > 2019-04-18,Acme Co,$24.95,Earthquake pills Result: > ( ParseIncomplete, > [ ["2019-03-24", "Acme Co", "$599.89", "Dehydrated boulders"] ] ) -} readCsvFileStrictWithoutHeader :: forall m . MonadIO m => FilePath -- ^ The path of a CSV file to read -> m (ParseStop, (Vector (Vector ByteString))) readCsvFileStrictWithoutHeader :: FilePath -> m (ParseStop, Vector (Vector ByteString)) readCsvFileStrictWithoutHeader FilePath fp = Delimiter -> FilePath -> m (ParseStop, Vector (Vector ByteString)) forall (m :: * -> *). MonadIO m => Delimiter -> FilePath -> m (ParseStop, Vector (Vector ByteString)) readDsvFileStrictWithoutHeader Delimiter comma FilePath fp {- | Sometimes a CSV file has a header but you don't care about it. In that case, you can use this function to /ignore/ the header line and read only the rows containing data. === Example CSV file: > Date,Vendor,Price,Product > 2019-03-24,Acme Co,$599.89,Dehydrated boulders > 2019-04-18,Acme Co,$24.95,Earthquake pills Result: > ( ParseComplete, > [ ["2019-03-24", "Acme Co", "$599.89", "Dehydrated boulders"], > ["2019-04-18", "Acme Co", "$24.95", "Earthquake pills"] ] ) -} readCsvFileStrictIgnoringHeader :: forall m . MonadIO m => FilePath -- ^ The path of a CSV file to read -> m (ParseStop, (Vector (Vector ByteString))) readCsvFileStrictIgnoringHeader :: FilePath -> m (ParseStop, Vector (Vector ByteString)) readCsvFileStrictIgnoringHeader FilePath fp = Delimiter -> FilePath -> m (ParseStop, Vector (Vector ByteString)) forall (m :: * -> *). MonadIO m => Delimiter -> FilePath -> m (ParseStop, Vector (Vector ByteString)) readDsvFileStrictIgnoringHeader Delimiter comma FilePath fp