Skip to content

Commit 389cf76

Browse files
author
Grahame Bowland
committed
add iteration interface
1 parent 9b895e2 commit 389cf76

File tree

1 file changed

+31
-11
lines changed

1 file changed

+31
-11
lines changed

csv.rs

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ enum fieldtype {
4141

4242
iface rowiter {
4343
fn readrow(&row: [str]) -> bool;
44+
fn iter(f: fn(&row: [str]) -> bool);
4445
}
4546

4647
fn new_reader(+f: io::reader, +delim: char, +quote: char) -> rowreader {
@@ -80,16 +81,16 @@ fn statestr(state: state) -> str {
8081
}
8182
}
8283

83-
fn unescape(escaped: [char]) -> [char] {
84+
fn unescape(escaped: [char], quote: char) -> [char] {
8485
let mut r : [char] = [];
8586
vec::reserve(r, vec::len(escaped));
8687
let mut in_q = false;
8788
for c in escaped {
8889
if in_q {
89-
assert(c == '"');
90+
assert(c == quote);
9091
in_q = false;
9192
} else {
92-
in_q = c == '"';
93+
in_q = c == quote;
9394
r += [c];
9495
}
9596
}
@@ -100,7 +101,7 @@ impl of rowiter for rowreader {
100101
#[inline]
101102
fn readrow(&row: [str]) -> bool {
102103
fn row_from_buf(self: rowreader, &fields: [str]) -> bool {
103-
fn decode(buffers: [[char]], field: fieldtype) -> str {
104+
fn decode(buffers: [[char]], field: fieldtype, quote: char) -> str {
104105
alt field {
105106
emptyfield() { "" }
106107
bufferfield(desc) {
@@ -120,7 +121,7 @@ impl of rowiter for rowreader {
120121
i = i + 1u;
121122
}
122123
if desc.escaped {
123-
buf = unescape(buf);
124+
buf = unescape(buf, quote);
124125
}
125126
str::from_chars(buf)
126127
}
@@ -159,24 +160,24 @@ impl of rowiter for rowreader {
159160
self.state = inquotedfield(cbuffer, coffset);
160161
} else if c == '\n' {
161162
if after_delim {
162-
fields += [decode(self.buffers, emptyfield)];
163+
fields += [decode(self.buffers, emptyfield, self.quote)];
163164
}
164165
ret true;
165166
} else if c == self.delim {
166167
self.state = fieldstart(true);
167-
fields += [decode(self.buffers, emptyfield)];
168+
fields += [decode(self.buffers, emptyfield, self.quote)];
168169
} else {
169170
self.state = infield(cbuffer, coffset);
170171
}
171172
}
172173
infield(b,o) {
173174
#debug("field : %u %u", b, o);
174175
if c == '\n' {
175-
fields += [decode(self.buffers, new_bufferfield(self, false, b, o, coffset))];
176+
fields += [decode(self.buffers, new_bufferfield(self, false, b, o, coffset), self.quote)];
176177
ret true;
177178
} else if c == self.delim {
178179
self.state = fieldstart(true);
179-
fields += [decode(self.buffers, new_bufferfield(self, false, b, o, coffset))];
180+
fields += [decode(self.buffers, new_bufferfield(self, false, b, o, coffset), self.quote)];
180181
}
181182
}
182183
inquotedfield(b, o) {
@@ -188,13 +189,13 @@ impl of rowiter for rowreader {
188189
inquote(b, o) {
189190
#debug("inquote : %u %u", b, o);
190191
if c == '\n' {
191-
fields += [decode(self.buffers, new_bufferfield(self, true, b, o, coffset))];
192+
fields += [decode(self.buffers, new_bufferfield(self, true, b, o, coffset), self.quote)];
192193
ret true;
193194
} else if c == self.quote {
194195
self.state = inquotedfield(b, o);
195196
} else if c == self.delim {
196197
self.state = fieldstart(true);
197-
fields += [decode(self.buffers, new_bufferfield(self, true, b, o, coffset))];
198+
fields += [decode(self.buffers, new_bufferfield(self, true, b, o, coffset), self.quote)];
198199
}
199200
// swallow odd chars, eg. space between field and "
200201
}
@@ -240,6 +241,15 @@ impl of rowiter for rowreader {
240241
}
241242
ret false;
242243
}
244+
245+
fn iter(f: fn(&row: [str]) -> bool) {
246+
let mut row = [];
247+
while self.readrow(row) {
248+
if !f(row) {
249+
break;
250+
}
251+
}
252+
}
243253
}
244254

245255
#[cfg(test)]
@@ -340,5 +350,15 @@ mod test {
340350
fn blank_line() {
341351
rowmatch("\n\n", [[], []]);
342352
}
353+
354+
#[test]
355+
fn iter_test() {
356+
let f = io::str_reader("a brown,cat");
357+
let r : rowreader = new_reader(f, ',', '"');
358+
for r.iter() { |row|
359+
assert(row[0] == "a brown");
360+
assert(row[1] == "cat");
361+
}
362+
}
343363
}
344364

0 commit comments

Comments
 (0)