-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Syntax-preserving CSV manipulation -- -- -- svfactor is a library for parsing, manipulating, and printing CSV and -- similar formats (such as PSV, TSV, and many more). -- -- svfactor retains all syntactic information including newlines, and -- provides lenses, prisms, and traversals to query and manipulate this -- structure. This should make it useful for writing custom CSV -- transformations and sanitisation tools. For example, one could easily -- use it to rewrite all CRLF newlines to LF. It also extends RFC4180 by -- allowing optional spacing surrounding fields. -- -- svfactor's parser is exposed so you can use it independently and -- printing is similarly standalone. -- -- Please note that there are known performance problems with -- svfactor. -- -- Examples: -- -- @package svfactor @version 0.1 module Data.Svfactor.Structure.Headedness -- | Does the Sv have a Header or not? A header is a row -- at the beginning of a file which contains the string names of each of -- the columns. -- -- If a header is present, it must not be decoded with the rest of the -- data. data Headedness Unheaded :: Headedness Headed :: Headedness -- | Classy lens for Headedness class HasHeadedness c headedness :: HasHeadedness c => Lens' c Headedness instance GHC.Show.Show Data.Svfactor.Structure.Headedness.Headedness instance GHC.Classes.Ord Data.Svfactor.Structure.Headedness.Headedness instance GHC.Classes.Eq Data.Svfactor.Structure.Headedness.Headedness instance Data.Svfactor.Structure.Headedness.HasHeadedness Data.Svfactor.Structure.Headedness.Headedness -- | Quote characters can be escaped in CSV documents by using two quote -- characters instead of one. sv's parser will unescape these sequences -- as it parses them, so it wraps them in the newtype Unescaped -- -- Encoding requires you to provide an Escaper, which is a -- function to escape strings on the way out. module Data.Svfactor.Text.Escape -- | Wrapper for text that is known to be in an unescaped form newtype Unescaped a Unescaped :: a -> Unescaped a [getRawUnescaped] :: Unescaped a -> a -- | A function that, given a char, escapes all occurrences of that char. -- -- This version allows the escaping to be type-changing. For example, -- escaping a single char can result in a string with two characters. type Escaper s t = Char -> Unescaped s -> t -- | A function that, given a char, escapes all occurrences of that char. type Escaper' a = Char -> Unescaped a -> a -- | Replaces all occurrences of the given character with two occurrences -- of that character, non-recursively, in the given String. -- --
--   >>> escapeString ''' "hello 'string'"
--   "hello ''string''"
--   
escapeString :: Escaper' String -- | Replaces all occurrences of the given character with two occurrences -- of that character in the given Text -- --
--   {- LANGUAGE OverloadedStrings -}
--   
--   >>> escapeText ''' "hello text"
--   "hello 'text'"
--   
escapeText :: Escaper' Text -- | Replaces all occurrences of the given character with two occurrences -- of that character in the given ByteString, which is assumed to be -- UTF-8 compatible. -- --
--   {- LANGUAGE OverloadedStrings -}
--   >>> escapeUtf8 ''' "hello bytestring"
--   "hello 'bytestring'"
--   
escapeUtf8 :: Escaper' ByteString -- | Replaces all occurrences of the given character with two occurrences -- of that character in the given lazy ByteString, which is assumed to be -- UTF-8 compatible. -- --
--   {- LANGUAGE OverloadedStrings -}
--   
--   >>> escapeUtf8Lazy ''' "hello 'lazy bytestring'"
--   "hello ''lazy bytestring''"
--   
escapeUtf8Lazy :: Escaper' ByteString -- | Escape a character, which must return a string. -- --
--   >>> escapeChar ''' '''
--   "''"
--   
-- --
--   >>> escapeChar ''' 'z'
--   "z"
--   
escapeChar :: Escaper Char String instance GHC.Generics.Generic (Data.Svfactor.Text.Escape.Unescaped a) instance Data.Traversable.Traversable Data.Svfactor.Text.Escape.Unescaped instance Data.Foldable.Foldable Data.Svfactor.Text.Escape.Unescaped instance GHC.Base.Functor Data.Svfactor.Text.Escape.Unescaped instance GHC.Base.Monoid a => GHC.Base.Monoid (Data.Svfactor.Text.Escape.Unescaped a) instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Data.Svfactor.Text.Escape.Unescaped a) instance GHC.Show.Show a => GHC.Show.Show (Data.Svfactor.Text.Escape.Unescaped a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Svfactor.Text.Escape.Unescaped a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Svfactor.Text.Escape.Unescaped a) instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Svfactor.Text.Escape.Unescaped a) module Data.Svfactor.Print.Options -- | Options to configure the printing process data PrintOptions a PrintOptions :: a -> Builder -> Escaper' a -> PrintOptions a -- | How do I convert these values into ByteString Builders? This -- depends not only on type, but on character encoding. Default: -- utf8PrintOptions [_build] :: PrintOptions a -> a -> Builder -- | How do I escape quotes which appear in this value? Default: -- escapeUtf8 [_escape] :: PrintOptions a -> Escaper' a -- | Classy optics for PrintOptions class HasPrintOptions c a | c -> a printOptions :: HasPrintOptions c a => Lens' c (PrintOptions a) build :: HasPrintOptions c a => Lens' c (a -> Builder) escape :: HasPrintOptions c a => Lens' c (Escaper' a) -- | Print options for Svs containing UTF-8 bytestrings defaultPrintOptions :: PrintOptions ByteString -- | Print options for Svs containing UTF-8 bytestrings utf8PrintOptions :: PrintOptions ByteString -- | Print options for Svs containing UTF-8 lazy bytestrings utf8LazyPrintOptions :: PrintOptions ByteString -- | Print options for Svs containing Text textPrintOptions :: PrintOptions Text -- | Print options for Svs containing Strings stringPrintOptions :: PrintOptions String instance Data.Svfactor.Print.Options.HasPrintOptions (Data.Svfactor.Print.Options.PrintOptions a) a -- | A sum type for line endings module Data.Svfactor.Text.Newline -- | Newline is a sum type for line endings data Newline -- |
--   "\r"
--   
CR :: Newline -- |
--   "\n"
--   
LF :: Newline -- |
--   "\rn"
--   
CRLF :: Newline -- | AsNewline is a classy prism for Newline class AsNewline r _Newline :: AsNewline r => Prism' r Newline _CR :: AsNewline r => Prism' r () _LF :: AsNewline r => Prism' r () _CRLF :: AsNewline r => Prism' r () -- | Convert a Newline to a String. Since this uses -- IsString, it works for other data types, like Text or -- ByteString. newlineToString :: IsString s => Newline -> s -- | Try to parse text into a Newline parseNewline :: Text -> Maybe Newline instance GHC.Show.Show Data.Svfactor.Text.Newline.Newline instance GHC.Classes.Ord Data.Svfactor.Text.Newline.Newline instance GHC.Classes.Eq Data.Svfactor.Text.Newline.Newline instance Data.Svfactor.Text.Newline.AsNewline Data.Svfactor.Text.Newline.Newline instance Data.Svfactor.Text.Newline.AsNewline Data.Text.Internal.Text instance Control.DeepSeq.NFData Data.Svfactor.Text.Newline.Newline -- | A sum type for quote characters module Data.Svfactor.Text.Quote -- | A sum type for quote characters. Either single or double quotes. data Quote SingleQuote :: Quote DoubleQuote :: Quote -- | Classy prisms for Quote class AsQuote r _Quote :: AsQuote r => Prism' r Quote _SingleQuote :: AsQuote r => Prism' r () _DoubleQuote :: AsQuote r => Prism' r () -- | Convert a Quote to the Char it represents. quoteChar :: Prism' Char Quote -- | Convert a Quote to a String. Since this uses -- IsString, it works for other data types, like Text or -- ByteString. quoteToString :: IsString a => Quote -> a instance GHC.Show.Show Data.Svfactor.Text.Quote.Quote instance GHC.Classes.Ord Data.Svfactor.Text.Quote.Quote instance GHC.Classes.Eq Data.Svfactor.Text.Quote.Quote instance Data.Svfactor.Text.Quote.AsQuote Data.Svfactor.Text.Quote.Quote instance Data.Svfactor.Text.Quote.AsQuote GHC.Types.Char instance Control.DeepSeq.NFData Data.Svfactor.Text.Quote.Quote -- | A sum type for space characters module Data.Svfactor.Text.Separator -- | By what are your values separated? The answer is often comma, -- but not always. -- -- A Separator is just a Char. It could be a sum type -- instead, since it will usually be comma or pipe, but our preference -- has been to be open here so that you can use whatever you'd like. -- There are test cases, for example, ensuring that you're free to use -- null-byte separated values if you so desire. type Separator = Char -- | Classy lens for Separator class HasSeparator c separator :: HasSeparator c => Lens' c Separator -- | The venerable comma separator. Used for CSV documents. comma :: Separator -- | The pipe separator. Used for PSV documents. pipe :: Separator -- | Tab is a separator too - why not? tab :: Separator instance Data.Svfactor.Text.Separator.HasSeparator GHC.Types.Char -- | A sum type for space characters module Data.Svfactor.Text.Space -- | HorizontalSpace is a subset of Char. To move back and -- forth betwen it and Char, String, or Text, use -- _HorizontalSpace data HorizontalSpace Space :: HorizontalSpace Tab :: HorizontalSpace -- | Classy prisms for HorizontalSpaces class AsHorizontalSpace r _HorizontalSpace :: AsHorizontalSpace r => Prism' r HorizontalSpace _Space :: AsHorizontalSpace r => Prism' r () _Tab :: AsHorizontalSpace r => Prism' r () -- | Helpful alias for lists of Spaces type Spaces = Vector HorizontalSpace -- | One space single :: Spaces -- | As many spaces as you'd like manySpaces :: Int -> Spaces -- | One tab tab :: Spaces -- | Turn a Space into a Char. To go the other way, see -- charToSpace spaceToChar :: HorizontalSpace -> Char -- | Try to turn a Char into a Space. To go the other way, see -- spaceToChar charToSpace :: Char -> Maybe HorizontalSpace -- | Parse Text into Spaces, or turn spaces into Text spacesText :: Prism' Text Spaces -- | Parse String into Spaces, or convert Spaces into -- String spacesString :: Prism' String Spaces -- | Spaced is a value with zero or many horizontal spaces around it -- on both sides. data Spaced a Spaced :: Spaces -> Spaces -> a -> Spaced a [_before] :: Spaced a -> Spaces [_after] :: Spaced a -> Spaces [_value] :: Spaced a -> a -- | Classy lenses for Spaced class HasSpaced s t a b | s -> a, t -> b, s b -> t, t a -> s spaced :: HasSpaced s t a b => Lens s t (Spaced a) (Spaced b) after :: (HasSpaced s t a b, (s ~ t)) => Lens s t Spaces Spaces before :: (HasSpaced s t a b, (s ~ t)) => Lens s t Spaces Spaces spacedValue :: HasSpaced s t a b => Lens s t a b after :: (HasSpaced s t a b, s ~ t, a ~ b) => Lens s t Spaces Spaces before :: (HasSpaced s t a b, s ~ t, a ~ b) => Lens s t Spaces Spaces spacedValue :: (HasSpaced s t a b, s ~ t, a ~ b) => Lens s t a b -- | betwixt is just the constructor for Spaced with a -- different argument order, which is sometimes useful. betwixt :: Spaces -> a -> Spaces -> Spaced a -- | uniform puts the same spacing both before and after something. uniform :: Spaces -> a -> Spaced a -- | Places its argument in a Spaced with no spaces. unspaced :: a -> Spaced a -- | Remove spaces from the argument removeSpaces :: Spaced a -> Spaced a instance GHC.Generics.Generic (Data.Svfactor.Text.Space.Spaced a) instance GHC.Show.Show a => GHC.Show.Show (Data.Svfactor.Text.Space.Spaced a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Svfactor.Text.Space.Spaced a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Svfactor.Text.Space.Spaced a) instance GHC.Show.Show Data.Svfactor.Text.Space.HorizontalSpace instance GHC.Classes.Ord Data.Svfactor.Text.Space.HorizontalSpace instance GHC.Classes.Eq Data.Svfactor.Text.Space.HorizontalSpace instance Data.Svfactor.Text.Space.HasSpaced (Data.Svfactor.Text.Space.Spaced a) (Data.Svfactor.Text.Space.Spaced b) a b instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Svfactor.Text.Space.Spaced a) instance GHC.Base.Functor Data.Svfactor.Text.Space.Spaced instance GHC.Base.Applicative Data.Svfactor.Text.Space.Spaced instance Data.Foldable.Foldable Data.Svfactor.Text.Space.Spaced instance Data.Traversable.Traversable Data.Svfactor.Text.Space.Spaced instance Data.Svfactor.Text.Space.AsHorizontalSpace Data.Svfactor.Text.Space.HorizontalSpace instance Data.Svfactor.Text.Space.AsHorizontalSpace GHC.Types.Char instance Control.DeepSeq.NFData Data.Svfactor.Text.Space.HorizontalSpace module Data.Svfactor.Syntax.Field -- | A Field is a single cell from a CSV document. -- -- Its value is either Quoted, which indicates the type of quote -- surrounding the value, or it is Unquoted, containing only the -- value. data Field s Unquoted :: s -> Field s Quoted :: Quote -> (Unescaped s) -> Field s -- | Fields are often surrounded by spaces type SpacedField a = Spaced (Field a) -- | Spaced is a value with zero or many horizontal spaces around it -- on both sides. data Spaced a Spaced :: Spaces -> Spaces -> a -> Spaced a -- | Classy Traversal for things containing Fields class HasFields c d s t | c -> s, d -> t, c t -> d, d s -> c fields :: HasFields c d s t => Traversal c d (Field s) (Field t) -- | Classy prisms for Field class (HasFields s s a a) => AsField s a | s -> a _Field :: AsField s a => Prism' s (Field a) _Unquoted :: AsField s a => Prism' s a _Quoted :: AsField s a => Prism' s (Quote, Unescaped a) -- | Build a quoted field with a normal string unescapedField :: Quote -> s -> Field s -- | The catamorphism for Field' foldField :: (s -> b) -> (Quote -> Unescaped s -> b) -> Field s -> b -- | Lens into the contents of a Field, regardless of whether it's quoted -- or unquoted fieldContents :: Lens (Field s) (Field t) s t instance GHC.Generics.Generic (Data.Svfactor.Syntax.Field.Field s) instance GHC.Show.Show s => GHC.Show.Show (Data.Svfactor.Syntax.Field.Field s) instance GHC.Classes.Ord s => GHC.Classes.Ord (Data.Svfactor.Syntax.Field.Field s) instance GHC.Classes.Eq s => GHC.Classes.Eq (Data.Svfactor.Syntax.Field.Field s) instance Data.Svfactor.Syntax.Field.AsField (Data.Svfactor.Syntax.Field.Field a) a instance Data.Svfactor.Syntax.Field.HasFields (Data.Svfactor.Syntax.Field.Field s) (Data.Svfactor.Syntax.Field.Field t) s t instance Control.DeepSeq.NFData s => Control.DeepSeq.NFData (Data.Svfactor.Syntax.Field.Field s) instance GHC.Base.Functor Data.Svfactor.Syntax.Field.Field instance Data.Foldable.Foldable Data.Svfactor.Syntax.Field.Field instance Data.Traversable.Traversable Data.Svfactor.Syntax.Field.Field module Data.Svfactor.Vector.NonEmpty -- | A non-empty value of Vector data NonEmptyVector a NonEmptyVector :: a -> (Vector a) -> NonEmptyVector a -- | Convert a NonEmpty list to a NonEmptyVector fromNel :: NonEmpty a -> NonEmptyVector a -- | Convert a NonEmptyVector to a NonEmpty list toNel :: NonEmptyVector a -> NonEmpty a -- | Convert a NonEmptyVector back to a Vector toVector :: NonEmptyVector a -> Vector a -- | Get or set the head of a NonEmptyVector headNev :: Lens' (NonEmptyVector a) a -- | Get or set the head of a NonEmptyVector tailNev :: Lens' (NonEmptyVector a) (Vector a) instance GHC.Generics.Generic (Data.Svfactor.Vector.NonEmpty.NonEmptyVector a) instance GHC.Show.Show a => GHC.Show.Show (Data.Svfactor.Vector.NonEmpty.NonEmptyVector a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Svfactor.Vector.NonEmpty.NonEmptyVector a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Svfactor.Vector.NonEmpty.NonEmptyVector a) instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Svfactor.Vector.NonEmpty.NonEmptyVector a) instance GHC.Base.Functor Data.Svfactor.Vector.NonEmpty.NonEmptyVector instance Data.Functor.Bind.Class.Apply Data.Svfactor.Vector.NonEmpty.NonEmptyVector instance GHC.Base.Applicative Data.Svfactor.Vector.NonEmpty.NonEmptyVector instance Data.Foldable.Foldable Data.Svfactor.Vector.NonEmpty.NonEmptyVector instance Data.Semigroup.Foldable.Class.Foldable1 Data.Svfactor.Vector.NonEmpty.NonEmptyVector instance Data.Traversable.Traversable Data.Svfactor.Vector.NonEmpty.NonEmptyVector instance Data.Semigroup.Traversable.Class.Traversable1 Data.Svfactor.Vector.NonEmpty.NonEmptyVector instance GHC.Base.Semigroup (Data.Svfactor.Vector.NonEmpty.NonEmptyVector a) -- | This module contains datatypes for Records. A record is a "line" or -- "row" of a CSV document module Data.Svfactor.Syntax.Record -- | A Record is a non-empty collection of Fields, implicitly -- separated by a separator (often a comma). newtype Record s Record :: NonEmptyVector (Spaced (Field s)) -> Record s [_fields] :: Record s -> NonEmptyVector (Spaced (Field s)) -- | Classy lenses for Record class HasRecord s t a b | s -> a, t -> b record :: HasRecord s t a b => Lens s t (Record a) (Record b) spacedFields :: HasRecord s t a b => Lens s t (NonEmptyVector (Spaced (Field a))) (NonEmptyVector (Spaced (Field b))) -- | A Record is isomorphic to a NonEmpty list of -- SpacedFields recordSpacedFieldsIso :: Iso (Record s) (Record a) (NonEmptyVector (Spaced (Field s))) (NonEmptyVector (Spaced (Field a))) -- | Build an empty record. -- -- According to RFC 4180, a record must have at least one field. But a -- field can be the empty string. So this is the closest we can get to an -- empty record. -- -- Note that this does not make Record a Monoid. It is not -- a lawful unit for the Semigroup operation. emptyRecord :: Monoid s => Record s -- | Build a Record with just one Field singleField :: Field s -> Record s -- | Build a Record given a NonEmpty list of its fields recordNel :: NonEmpty (SpacedField s) -> Record s -- | A collection of records, separated by newlines. data Records s EmptyRecords :: Records s Records :: (Record s) -> (Vector (Newline, Record s)) -> Records s -- | Classy lenses for Records class HasRecords c s | c -> s records :: HasRecords c s => Lens' c (Records s) traverseRecords :: HasRecords c s => Traversal' c (Record s) traverseNewlines :: HasRecords c s => Traversal' c Newline -- | Prism for an empty Records _EmptyRecords :: Prism' (Records s) () -- | Prism for a non-empty Records _NonEmptyRecords :: Prism (Records s) (Records t) (Record s, Vector (Newline, Record s)) (Record t, Vector (Newline, Record t)) -- | Convenience constructor for Records. -- -- This puts the same newline between all the records. mkRecords :: Newline -> NonEmpty (Record s) -> Records s -- | A record collection conaining one record singleRecord :: Record s -> Records s -- | Collect the list of Records from anything that -- HasRecords recordList :: HasRecords c s => c -> [Record s] instance GHC.Generics.Generic (Data.Svfactor.Syntax.Record.Records s) instance GHC.Show.Show s => GHC.Show.Show (Data.Svfactor.Syntax.Record.Records s) instance GHC.Classes.Ord s => GHC.Classes.Ord (Data.Svfactor.Syntax.Record.Records s) instance GHC.Classes.Eq s => GHC.Classes.Eq (Data.Svfactor.Syntax.Record.Records s) instance GHC.Generics.Generic (Data.Svfactor.Syntax.Record.Record s) instance GHC.Base.Semigroup (Data.Svfactor.Syntax.Record.Record s) instance GHC.Show.Show s => GHC.Show.Show (Data.Svfactor.Syntax.Record.Record s) instance GHC.Classes.Ord s => GHC.Classes.Ord (Data.Svfactor.Syntax.Record.Record s) instance GHC.Classes.Eq s => GHC.Classes.Eq (Data.Svfactor.Syntax.Record.Record s) instance Data.Svfactor.Syntax.Record.HasRecords (Data.Svfactor.Syntax.Record.Records s) s instance Control.DeepSeq.NFData s => Control.DeepSeq.NFData (Data.Svfactor.Syntax.Record.Records s) instance GHC.Base.Functor Data.Svfactor.Syntax.Record.Records instance Data.Foldable.Foldable Data.Svfactor.Syntax.Record.Records instance Data.Traversable.Traversable Data.Svfactor.Syntax.Record.Records instance Data.Svfactor.Syntax.Record.HasRecord (Data.Svfactor.Syntax.Record.Record a) (Data.Svfactor.Syntax.Record.Record b) a b instance Data.Svfactor.Syntax.Field.HasFields (Data.Svfactor.Syntax.Record.Record a) (Data.Svfactor.Syntax.Record.Record b) a b instance Control.DeepSeq.NFData s => Control.DeepSeq.NFData (Data.Svfactor.Syntax.Record.Record s) instance GHC.Base.Functor Data.Svfactor.Syntax.Record.Record instance Data.Foldable.Foldable Data.Svfactor.Syntax.Record.Record instance Data.Traversable.Traversable Data.Svfactor.Syntax.Record.Record -- | This file defines a datatype for a complete Sv document. The datatype -- preserves information such as whitespace so that the original text can -- be recovered. -- -- You can program against it using the provided functions and optics. -- For an example of this see Requote.hs module Data.Svfactor.Syntax.Sv -- | Sv is a whitespace-preserving data type for separated values. -- Often the separator is a comma, but this type does not make that -- assumption so that it can be used for pipe- or tab-separated values as -- well. data Sv s Sv :: Separator -> Maybe (Header s) -> Records s -> [Newline] -> Sv s [_separatorSv] :: Sv s -> Separator [_maybeHeader] :: Sv s -> Maybe (Header s) [_records] :: Sv s -> Records s [_finalNewlines] :: Sv s -> [Newline] -- | Classy lenses for Sv class (HasRecords c s, HasSeparator c) => HasSv c s | c -> s sv :: HasSv c s => Lens' c (Sv s) maybeHeader :: HasSv c s => Lens' c (Maybe (Header s)) traverseHeader :: HasSv c s => Traversal' c (Header s) finalNewlines :: HasSv c s => Lens' c [Newline] -- | Classy lenses for Records class HasRecords c s | c -> s records :: HasRecords c s => Lens' c (Records s) traverseRecords :: HasRecords c s => Traversal' c (Record s) traverseNewlines :: HasRecords c s => Traversal' c Newline -- | Convenience constructor for Sv mkSv :: Separator -> Maybe (Header s) -> [Newline] -> Records s -> Sv s -- | An empty Sv emptySv :: Separator -> Sv s -- | Collect the list of Records from anything that -- HasRecords recordList :: HasRecords c s => c -> [Record s] -- | A Header is present in many CSV documents, usually listing the -- names of the columns. We keep this separate from the regular records. data Header s Header :: Record s -> Newline -> Header s -- | Classy lenses for Header class HasHeader s t a b | s -> a, t -> b, s b -> t, t a -> s header :: HasHeader s t a b => Lens s t (Header a) (Header b) headerNewline :: (HasHeader s t a b, (s ~ t)) => Lens s t Newline Newline headerRecord :: HasHeader s t a b => Lens s t (Record a) (Record b) headerNewline :: (HasHeader s t a b, (a ~ b)) => Lens s t Newline Newline -- | Used to build Svs that don't have a header noHeader :: Maybe (Header s) -- | Convenience constructor for Header, usually when you're -- building Svs mkHeader :: Record s -> Newline -> Maybe (Header s) -- | Does the Sv have a Header or not? A header is a row -- at the beginning of a file which contains the string names of each of -- the columns. -- -- If a header is present, it must not be decoded with the rest of the -- data. data Headedness Unheaded :: Headedness Headed :: Headedness -- | Classy lens for Headedness class HasHeadedness c headedness :: HasHeadedness c => Lens' c Headedness -- | Determine the Headedness of an Sv getHeadedness :: Sv s -> Headedness -- | By what are your values separated? The answer is often comma, -- but not always. -- -- A Separator is just a Char. It could be a sum type -- instead, since it will usually be comma or pipe, but our preference -- has been to be open here so that you can use whatever you'd like. -- There are test cases, for example, ensuring that you're free to use -- null-byte separated values if you so desire. type Separator = Char -- | Classy lens for Separator class HasSeparator c separator :: HasSeparator c => Lens' c Separator -- | The venerable comma separator. Used for CSV documents. comma :: Separator -- | The pipe separator. Used for PSV documents. pipe :: Separator -- | Tab is a separator too - why not? tab :: Separator instance GHC.Generics.Generic (Data.Svfactor.Syntax.Sv.Sv s) instance GHC.Show.Show s => GHC.Show.Show (Data.Svfactor.Syntax.Sv.Sv s) instance GHC.Classes.Ord s => GHC.Classes.Ord (Data.Svfactor.Syntax.Sv.Sv s) instance GHC.Classes.Eq s => GHC.Classes.Eq (Data.Svfactor.Syntax.Sv.Sv s) instance GHC.Generics.Generic (Data.Svfactor.Syntax.Sv.Header s) instance Data.Traversable.Traversable Data.Svfactor.Syntax.Sv.Header instance Data.Foldable.Foldable Data.Svfactor.Syntax.Sv.Header instance GHC.Base.Functor Data.Svfactor.Syntax.Sv.Header instance GHC.Show.Show s => GHC.Show.Show (Data.Svfactor.Syntax.Sv.Header s) instance GHC.Classes.Ord s => GHC.Classes.Ord (Data.Svfactor.Syntax.Sv.Header s) instance GHC.Classes.Eq s => GHC.Classes.Eq (Data.Svfactor.Syntax.Sv.Header s) instance Data.Svfactor.Syntax.Sv.HasHeader (Data.Svfactor.Syntax.Sv.Header a) (Data.Svfactor.Syntax.Sv.Header b) a b instance Data.Svfactor.Syntax.Record.HasRecord (Data.Svfactor.Syntax.Sv.Header a) (Data.Svfactor.Syntax.Sv.Header b) a b instance Data.Svfactor.Syntax.Field.HasFields (Data.Svfactor.Syntax.Sv.Header a) (Data.Svfactor.Syntax.Sv.Header b) a b instance Data.Svfactor.Syntax.Sv.HasSv (Data.Svfactor.Syntax.Sv.Sv s) s instance Control.DeepSeq.NFData s => Control.DeepSeq.NFData (Data.Svfactor.Syntax.Sv.Sv s) instance Data.Svfactor.Syntax.Record.HasRecords (Data.Svfactor.Syntax.Sv.Sv s) s instance GHC.Base.Functor Data.Svfactor.Syntax.Sv.Sv instance Data.Foldable.Foldable Data.Svfactor.Syntax.Sv.Sv instance Data.Traversable.Traversable Data.Svfactor.Syntax.Sv.Sv instance Data.Svfactor.Text.Separator.HasSeparator (Data.Svfactor.Syntax.Sv.Sv s) instance Control.DeepSeq.NFData s => Control.DeepSeq.NFData (Data.Svfactor.Syntax.Sv.Header s) -- | Configuration to tell the parser what your file looks like. module Data.Svfactor.Parse.Options -- | An ParseOptions informs the parser how to parse your file. The -- type parameter will be some sort of string; often ByteString. -- -- A default is provided as defaultParseOptions, seen below. data ParseOptions s ParseOptions :: Separator -> Headedness -> Bool -> String -> s -> ParseOptions s -- | Which separator does the file use? Usually this is comma, but -- it can also be pipe, or any other Char -- (Separator = Char) [_parseSeparator] :: ParseOptions s -> Separator -- | Whether there is a header row with column names or not. [_headedness] :: ParseOptions s -> Headedness -- | If a blank line is encountered, should the parse finish, or treat it -- as an empty row and continue? [_endOnBlankLine] :: ParseOptions s -> Bool -- | How should I turn a String into this type? This is a detail used by -- the parser. [_encodeString] :: ParseOptions s -> String -> s -- | Classy lenses for ParseOptions class (HasSeparator s, HasHeadedness s) => HasParseOptions s t a b | s -> a, t -> b, s b -> t, t a -> s parseOptions :: HasParseOptions s t a b => Lens s t (ParseOptions a) (ParseOptions b) encodeString :: HasParseOptions s t a b => Lens s t (String -> a) (String -> b) endOnBlankLine :: (HasParseOptions s t a b, s ~ t) => Lens s t Bool Bool endOnBlankLine :: (HasParseOptions s t a b, s ~ t, a ~ b) => Lens s t Bool Bool -- | Classy lens for Separator class HasSeparator c separator :: HasSeparator c => Lens' c Separator -- | Classy lens for Headedness class HasHeadedness c headedness :: HasHeadedness c => Lens' c Headedness -- | defaultParseOptions is used to parse a CSV file featuring a -- header row, using Trifecta as the parsing library. It uses UTF-8 -- ByteStrings defaultParseOptions :: ParseOptions ByteString -- | The default is that a header is present. defaultHeadedness :: Headedness -- | The default separator. Alias for comma. defaultSeparator :: Separator instance Data.Svfactor.Parse.Options.HasParseOptions (Data.Svfactor.Parse.Options.ParseOptions a) (Data.Svfactor.Parse.Options.ParseOptions b) a b instance GHC.Base.Functor Data.Svfactor.Parse.Options.ParseOptions instance Data.Svfactor.Text.Separator.HasSeparator (Data.Svfactor.Parse.Options.ParseOptions s) instance Data.Svfactor.Structure.Headedness.HasHeadedness (Data.Svfactor.Parse.Options.ParseOptions s) module Data.Svfactor.Syntax -- | This module is considered an implementation detail. As the -- Internal module name suggests, this module is exempt from the -- PVP, so depend on it at your own risk! These functions exist to be -- called by Data.Svfactor.Print. module Data.Svfactor.Print.Internal -- | Convert a Newline to a ByteString Builder printNewline :: Newline -> Builder -- | Convert a Field to a ByteString Builder printField :: PrintOptions s -> Field s -> Builder -- | Convert a SpacedField to a ByteString Builder printSpaced :: PrintOptions s -> SpacedField s -> Builder -- | Convert a Record to a ByteString Builder printRecord :: PrintOptions s -> Separator -> Record s -> Builder -- | Convert Records to a ByteString Builder. printRecords :: PrintOptions s -> Separator -> Records s -> Builder -- | Convert Header to a ByteString Builder. printHeader :: PrintOptions s -> Separator -> Header s -> Builder -- | Printing is the process of turning an Sv into a textual -- representation, such as a ByteString. -- -- If you want to turn your data type into a textual representation, you -- should look instead at Data.Svfactor.Encode module Data.Svfactor.Print -- | Print an Sv to a ByteString value. printSv :: Sv ByteString -> ByteString -- | Print an Sv to a lazy ByteString value. printSvLazy :: Sv ByteString -> ByteString -- | Converts the given Sv into a strict ByteString printSv' :: PrintOptions s -> Sv s -> ByteString -- | Converts the given Sv into a lazy ByteString printSvLazy' :: PrintOptions s -> Sv s -> ByteString -- | Print an Sv containing Text to a ByteString printSvText :: Sv Text -> ByteString -- | Print an Sv containing Text to a ByteString printSvTextLazy :: Sv Text -> ByteString -- | Writes an sv to a file. This goes directly from a Builder, so -- it is more efficient than calling printSv or printSvLazy -- and writing the result to a file. writeSvToFile :: FilePath -> Sv ByteString -> IO () -- | Writes an sv to a file handle. This goes directly from a -- Builder, so it is more efficient than calling printSv or -- printSvLazy and writing the result to the handle. writeSvToHandle :: Handle -> Sv ByteString -> IO () -- | Writes an sv to a file. This goes directly from a Builder, so -- it is more efficient than calling printSv or printSvLazy -- and writing the result to a file. -- -- This version is polymorphic, but as a penalty you have to tell me how -- to get a Bytestring Builder. writeSvToFile' :: PrintOptions s -> FilePath -> Sv s -> IO () -- | Writes an sv to a file handle. This goes directly from a -- Builder, so it is more efficient than calling printSv or -- printSvLazy and writing the result to the handle. -- -- This version is polymorphic, but as a penalty you have to tell me how -- to get a Bytestring Builder. writeSvToHandle' :: PrintOptions s -> Handle -> Sv s -> IO () -- | This module contains internal implementation details of svfactor's -- parser. As the Internal name suggests, this file is exempt from the -- PVP. Depend on this module at your own risk! module Data.Svfactor.Parse.Internal -- | Parse an Sv separatedValues :: CharParsing m => ParseOptions s -> m (Sv s) -- | Maybe parse the header row of a CSV file, depending on the given -- Headedness header :: CharParsing m => ParseOptions s -> m (Maybe (Header s)) -- | Parse a field, be it quoted or unquoted field :: CharParsing m => Separator -> (String -> s) -> m (Field s) -- | Parse a field surrounded by single quotes singleQuotedField :: CharParsing m => (String -> s) -> m (Field s) -- | Parse a field surrounded by double quotes doubleQuotedField :: CharParsing m => (String -> s) -> m (Field s) -- | Parse a field that is not surrounded by quotes unquotedField :: CharParsing m => Separator -> (String -> s) -> m (Field s) -- | Combinator to parse some data surrounded by spaces spaced :: CharParsing m => Separator -> m a -> m (Spaced a) -- | Parse a field with its surrounding spacing spacedField :: CharParsing m => Separator -> (String -> s) -> m (Spaced (Field s)) -- | Parse an entire record, or "row" record :: CharParsing m => ParseOptions s -> m (Record s) -- | Parse many records, or "rows" records :: CharParsing m => ParseOptions s -> m (Records s) -- | Parse zero or many newlines ending :: CharParsing m => ParseOptions s -> m [Newline] module Data.Svfactor.Parse -- | Parse a ByteString as an Sv. -- -- This version uses Trifecta, hence it assumes its input is UTF-8 -- encoded. parseSv :: ParseOptions ByteString -> ByteString -> Either ByteString (Sv ByteString) -- | Parse some text as an Sv. -- -- This version lets you choose which parsing library to use by providing -- an SvParser. Common selections are trifecta and -- attoparsecByteString. parseSv' :: SvParser s -> ParseOptions s -> s -> Either s (Sv s) -- | Load a file and parse it as an Sv. -- -- This version uses Trifecta, hence it assumes its input is UTF-8 -- encoded. parseSvFromFile :: MonadIO m => ParseOptions ByteString -> FilePath -> m (Either ByteString (Sv ByteString)) -- | Load a file and parse it as an Sv. -- -- This version lets you choose which parsing library to use by providing -- an SvParser. Common selections are trifecta and -- attoparsecByteString. parseSvFromFile' :: MonadIO m => SvParser s -> ParseOptions s -> FilePath -> m (Either s (Sv s)) -- | Parse an Sv separatedValues :: CharParsing m => ParseOptions s -> m (Sv s) -- | Which parsing library should be used to parse the document? -- -- The parser is written in terms of the parsers library, -- meaning it can be instantiated to several different parsing libraries. -- By default, we use trifecta, because Text.Trifectas -- error messages are so helpful. attoparsecByteString is faster -- though, if your input is ASCII and you care a lot about speed. -- -- It is worth noting that Trifecta assumes UTF-8 encoding of the input -- data. UTF-8 is backwards-compatible with 7-bit ASCII, so this will -- work for many documents. However, not all documents are ASCII or -- UTF-8. For example, our species.csv test file is Windows-1252, -- which is a non-ISO extension of latin1 8-bit ASCII. For documents -- encoded as Windows-1252, Trifecta's assumption is invalid and parse -- errors result. Attoparsec works fine for this character -- encoding, but it wouldn't work well on a UTF-8 encoded document -- including non-ASCII characters. data SvParser s SvParser :: ParseOptions s -> s -> Either String (Sv s) -> ParseOptions s -> FilePath -> IO (Either String (Sv s)) -> SvParser s [runSvParser] :: SvParser s -> ParseOptions s -> s -> Either String (Sv s) [runSvParserFromFile] :: SvParser s -> ParseOptions s -> FilePath -> IO (Either String (Sv s)) -- | An SvParser that uses Text.Trifecta. Trifecta assumes -- its input is UTF-8, and provides helpful clang-style error messages. trifecta :: SvParser ByteString -- | Helper to convert Text.Trifecta Result to Either. trifectaResultToEither :: Result a -> Either String a -- | An SvParser that uses Data.Attoparsec.ByteString. This -- is the fastest provided SvParser, but it has poorer error -- messages. attoparsecByteString :: SvParser ByteString -- | An SvParser that uses Data.Attoparsec.Text. This is -- helpful if your input is in the form of Text. attoparsecText :: SvParser Text module Data.Svfactor