///|
/// Represents configuration options for CSV parsing operations.
///
/// Parameters:
///
/// * `delimiter` : Character used to separate fields in the CSV data (typically
/// a comma ',').
/// * `allow_newlines_in_quotes` : Boolean flag indicating whether newline
/// characters are allowed within quoted fields.
/// * `quote_char` : Character used for quoting fields that contain special
/// characters (typically a double quote '"').
/// * `skip_empty_lines` : Boolean flag indicating whether empty lines in the
/// input should be ignored.
/// * `trim_spaces` : Boolean flag indicating whether leading and trailing
/// whitespace should be removed from fields.
///
pub(all) struct CSVOptions {
delimiter : Char
allow_newlines_in_quotes : Bool
quote_char : Char
skip_empty_lines : Bool
trim_spaces : Bool
}
///|
priv trait CSVReader {
read_char(Self) -> Char?
peek_char(Self) -> Char?
is_eof(Self) -> Bool
}
///|
priv struct StringReader {
source : String
mut pos : Int
}
///|
impl CSVReader for StringReader with read_char(self) -> Char? {
if self.pos < self.source.length() {
let ch = Int::unsafe_to_char(self.source.code_unit_at(self.pos).to_int())
self.pos += 1
Some(ch)
} else {
None
}
}
///|
test "StringReader::read_char/normal_case" {
let reader : StringReader = { source: "Hello, World!", pos: 0 }
assert_true(reader.read_char() is Some('H'))
assert_true(reader.read_char() is Some('e'))
assert_true(reader.read_char() is Some('l'))
}
///|
test "StringReader::read_char/empty_string" {
let reader : StringReader = { source: "", pos: 0 }
assert_true(reader.read_char() is None)
}
///|
test "StringReader::read_char/past_end_of_string" {
let reader : StringReader = { source: "Hello", pos: 5 } // 'pos' is set to the length of the string
assert_true(reader.read_char() is None)
}
///|
impl CSVReader for StringReader with peek_char(self) -> Char? {
if self.pos < self.source.length() {
Some(Int::unsafe_to_char(self.source.code_unit_at(self.pos).to_int()))
} else {
None
}
}
///|
test "StringReader::peek_char/normal_case" {
let reader : StringReader = { source: "Hello, World!", pos: 0 }
assert_true(reader.peek_char() is Some('H'))
reader.pos = 7
assert_true(reader.peek_char() is Some('W'))
}
///|
test "StringReader::peek_char/empty_string" {
let reader : StringReader = { source: "", pos: 0 }
assert_true(reader.peek_char() is None)
}
///|
test "StringReader::peek_char/at_end_of_string" {
let reader : StringReader = { source: "Hello", pos: 5 } // 'pos' is set to the length of the string
assert_true(reader.peek_char() is None)
}
///|
impl CSVReader for StringReader with is_eof(self) -> Bool {
self.pos >= self.source.length()
}