/*!
`csv-core` provides a fast CSV reader and writer for use in a `no_std` context.

This crate will never use the standard library. `no_std` support is therefore
enabled by default.

If you're looking for more ergonomic CSV parsing routines, please use the
[`csv`](https://docs.rs/csv) crate.

# Overview

This crate has two primary APIs. The `Reader` API provides a CSV parser, and
the `Writer` API provides a CSV writer.

# Example: reading CSV

This example shows how to count the number of fields and records in CSV data.

```
use csv_core::{Reader, ReadFieldResult};

let data = "
foo,bar,baz
a,b,c
xxx,yyy,zzz
";

let mut rdr = Reader::new();
let mut bytes = data.as_bytes();
let mut count_fields = 0;
let mut count_records = 0;
loop {
    // We skip handling the output since we don't need it for counting.
    let (result, nin, _) = rdr.read_field(bytes, &mut [0; 1024]);
    bytes = &bytes[nin..];
    match result {
        ReadFieldResult::InputEmpty => {},
        ReadFieldResult::OutputFull => panic!("field too large"),
        ReadFieldResult::Field { record_end } => {
            count_fields += 1;
            if record_end {
                count_records += 1;
            }
        }
        ReadFieldResult::End => break,
    }
}
assert_eq!(3, count_records);
assert_eq!(9, count_fields);
```

# Example: writing CSV

This example shows how to use the `Writer` API to write valid CSV data. Proper
quoting is handled automatically.

```
use csv_core::Writer;

// This is where we'll write out CSV data.
let mut out = &mut [0; 1024];
// The number of bytes we've written to `out`.
let mut nout = 0;
// Create a CSV writer with a default configuration.
let mut wtr = Writer::new();

// Write a single field. Note that we ignore the `WriteResult` and the number
// of input bytes consumed since we're doing this by hand.
let (_, _, n) = wtr.field(&b"foo"[..], &mut out[nout..]);
nout += n;

// Write a delimiter and then another field that requires quotes.
let (_, n) = wtr.delimiter(&mut out[nout..]);
nout += n;
let (_, _, n) = wtr.field(&b"bar,baz"[..], &mut out[nout..]);
nout += n;
let (_, n) = wtr.terminator(&mut out[nout..]);
nout += n;

// Now write another record.
let (_, _, n) = wtr.field(&b"a \"b\" c"[..], &mut out[nout..]);
nout += n;
let (_, n) = wtr.delimiter(&mut out[nout..]);
nout += n;
let (_, _, n) = wtr.field(&b"quux"[..], &mut out[nout..]);
nout += n;

// We must always call finish once done writing.
// This ensures that any closing quotes are written.
let (_, n) = wtr.finish(&mut out[nout..]);
nout += n;

assert_eq!(&out[..nout], &b"\
foo,\"bar,baz\"
\"a \"\"b\"\" c\",quux"[..]);
```
*/

#![deny(missing_docs)]
#![no_std]

#[cfg(test)]
extern crate arrayvec;
extern crate memchr;

pub use reader::{
    Reader, ReaderBuilder,
    ReadFieldResult, ReadFieldNoCopyResult,
    ReadRecordResult, ReadRecordNoCopyResult,
};
pub use writer::{Writer, WriterBuilder, WriteResult, is_non_numeric, quote};

mod reader;
mod writer;

/// A record terminator.
///
/// Use this to specify the record terminator while parsing CSV. The default is
/// CRLF, which treats `\r`, `\n` or `\r\n` as a single record terminator.
#[derive(Clone, Copy, Debug)]
pub enum Terminator {
    /// Parses `\r`, `\n` or `\r\n` as a single record terminator.
    CRLF,
    /// Parses the byte given as a record terminator.
    Any(u8),
    /// Hints that destructuring should not be exhaustive.
    ///
    /// This enum may grow additional variants, so this makes sure clients
    /// don't count on exhaustive matching. (Otherwise, adding a new variant
    /// could break existing code.)
    #[doc(hidden)]
    __Nonexhaustive,
}

impl Terminator {
    /// Checks whether the terminator is set to CRLF.
    fn is_crlf(&self) -> bool {
        match *self {
            Terminator::CRLF => true,
            Terminator::Any(_) => false,
            _ => unreachable!(),
        }
    }

    fn equals(&self, other: u8) -> bool {
        match *self {
            Terminator::CRLF => other == b'\r' || other == b'\n',
            Terminator::Any(b) => other == b,
            _ => unreachable!(),
        }
    }
}

impl Default for Terminator {
    fn default() -> Terminator {
        Terminator::CRLF
    }
}

/// The quoting style to use when writing CSV data.
#[derive(Clone, Copy, Debug)]
pub enum QuoteStyle {
    /// This puts quotes around every field. Always.
    Always,
    /// This puts quotes around fields only when necessary.
    ///
    /// They are necessary when fields contain a quote, delimiter or record
    /// terminator. Quotes are also necessary when writing an empty record
    /// (which is indistinguishable from a record with one empty field).
    ///
    /// This is the default.
    Necessary,
    /// This puts quotes around all fields that are non-numeric. Namely, when
    /// writing a field that does not parse as a valid float or integer, then
    /// quotes will be used even if they aren't strictly necessary.
    NonNumeric,
    /// This *never* writes quotes, even if it would produce invalid CSV data.
    Never,
    /// Hints that destructuring should not be exhaustive.
    ///
    /// This enum may grow additional variants, so this makes sure clients
    /// don't count on exhaustive matching. (Otherwise, adding a new variant
    /// could break existing code.)
    #[doc(hidden)]
    __Nonexhaustive,
}

impl Default for QuoteStyle {
    fn default() -> QuoteStyle {
        QuoteStyle::Necessary
    }
}
