rscsv 0.3.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +4 -3
- data/Cargo.lock +23 -26
- data/Cargo.toml +1 -1
- data/lib/rscsv/version.rb +1 -1
- data/rscsv.gemspec +1 -1
- data/src/lib.rs +42 -134
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 40a0b9b97f5c3273d2f29e60f1124cb84f71a17ad2f3cb4aca6c57527e6fd270
|
4
|
+
data.tar.gz: 11d1c58a01c0a826d11cdbe8d3fcec9b1fd687dc948449471b4b536242cae054
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ccb6484958de5857da020b74e52c57cf52373c777d67cb7710641832d7bdef9b71913108a0a143c70806c8b1dfe6d41f1cd6a70e008292be3bda78faf5d217cd
|
7
|
+
data.tar.gz: 2bef5822fad2b041333c063d05d3d5cf2565c7e022667600ce0daef586a3781df989573bf1053ecb8676de53a22c8c13101952172a05f3c70ea8e92c9ba88cdf
|
data/.travis.yml
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
sudo: false
|
2
2
|
language: ruby
|
3
3
|
rvm:
|
4
|
-
- 2.
|
5
|
-
- 2.
|
4
|
+
- 2.5.0
|
5
|
+
- 2.4.3
|
6
|
+
- 2.3.6
|
6
7
|
before_install:
|
7
|
-
- gem install bundler -v 1.
|
8
|
+
- gem install bundler -v 1.16.1
|
8
9
|
- if [ ! -e "$HOME/.cargo/bin" ]; then curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain stable -y; fi
|
9
10
|
- export PATH="$HOME/.cargo/bin:$PATH"
|
10
11
|
- rustup default stable
|
data/Cargo.lock
CHANGED
@@ -1,11 +1,3 @@
|
|
1
|
-
[root]
|
2
|
-
name = "rscsv"
|
3
|
-
version = "0.3.3"
|
4
|
-
dependencies = [
|
5
|
-
"csv 1.0.0-beta.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
6
|
-
"helix 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
7
|
-
]
|
8
|
-
|
9
1
|
[[package]]
|
10
2
|
name = "cslice"
|
11
3
|
version = "0.3.0"
|
@@ -18,11 +10,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
18
10
|
|
19
11
|
[[package]]
|
20
12
|
name = "csv"
|
21
|
-
version = "1.0.0-beta.
|
13
|
+
version = "1.0.0-beta.5"
|
22
14
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
23
15
|
dependencies = [
|
24
16
|
"csv-core 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
25
|
-
"serde 1.0.
|
17
|
+
"serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
26
18
|
]
|
27
19
|
|
28
20
|
[[package]]
|
@@ -30,53 +22,58 @@ name = "csv-core"
|
|
30
22
|
version = "0.1.3"
|
31
23
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
32
24
|
dependencies = [
|
33
|
-
"memchr 1.0.
|
25
|
+
"memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
34
26
|
]
|
35
27
|
|
36
28
|
[[package]]
|
37
29
|
name = "helix"
|
38
|
-
version = "0.
|
30
|
+
version = "0.7.2"
|
39
31
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
40
32
|
dependencies = [
|
41
33
|
"cslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
42
34
|
"cstr-macro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
43
|
-
"libc 0.2.
|
44
|
-
"libcruby-sys 0.
|
35
|
+
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
36
|
+
"libcruby-sys 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
45
37
|
]
|
46
38
|
|
47
39
|
[[package]]
|
48
40
|
name = "libc"
|
49
|
-
version = "0.2.
|
41
|
+
version = "0.2.34"
|
50
42
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
51
43
|
|
52
44
|
[[package]]
|
53
45
|
name = "libcruby-sys"
|
54
|
-
version = "0.
|
46
|
+
version = "0.7.2"
|
55
47
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
56
48
|
dependencies = [
|
57
|
-
"libc 0.2.
|
49
|
+
"libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
58
50
|
]
|
59
51
|
|
60
52
|
[[package]]
|
61
53
|
name = "memchr"
|
62
|
-
version = "1.0.
|
54
|
+
version = "1.0.2"
|
63
55
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
56
|
+
|
57
|
+
[[package]]
|
58
|
+
name = "rscsv"
|
59
|
+
version = "0.3.3"
|
64
60
|
dependencies = [
|
65
|
-
"
|
61
|
+
"csv 1.0.0-beta.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
62
|
+
"helix 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
66
63
|
]
|
67
64
|
|
68
65
|
[[package]]
|
69
66
|
name = "serde"
|
70
|
-
version = "1.0.
|
67
|
+
version = "1.0.24"
|
71
68
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
72
69
|
|
73
70
|
[metadata]
|
74
71
|
"checksum cslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0f8cb7306107e4b10e64994de6d3274bd08996a7c1322a27b86482392f96be0a"
|
75
72
|
"checksum cstr-macro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db53fddba18cdd35477a7213a3ef6acfbfa333c31b42ce019e544c4a1420a06f"
|
76
|
-
"checksum csv 1.0.0-beta.
|
73
|
+
"checksum csv 1.0.0-beta.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e7a9e063dcebdb56c306f23e672bfd31df3da8ec5f6d696b35f2c29c2a9572f0"
|
77
74
|
"checksum csv-core 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ae1fbabf21d9a52d04675cc5b032d7bae24ecdcd22646f7eefcd0496a122686c"
|
78
|
-
"checksum helix 0.
|
79
|
-
"checksum libc 0.2.
|
80
|
-
"checksum libcruby-sys 0.
|
81
|
-
"checksum memchr 1.0.
|
82
|
-
"checksum serde 1.0.
|
75
|
+
"checksum helix 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf45e0f51337f76d3481ac5a29693ca6138dcfa569a671988c7c65a6536d4cf"
|
76
|
+
"checksum libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "36fbc8a8929c632868295d0178dd8f63fc423fd7537ad0738372bd010b3ac9b0"
|
77
|
+
"checksum libcruby-sys 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a8d944129f388f0dfd391fb8308f4e0b9cde5c83ed1e66c1ee395445ad62282c"
|
78
|
+
"checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a"
|
79
|
+
"checksum serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "1c57ab4ec5fa85d08aaf8ed9245899d9bbdd66768945b21113b84d5f595cb6a1"
|
data/Cargo.toml
CHANGED
data/lib/rscsv/version.rb
CHANGED
data/rscsv.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.require_paths = ['lib']
|
22
22
|
spec.extensions = Dir['ext/extconf.rb']
|
23
23
|
|
24
|
-
spec.add_dependency 'helix_runtime', '0.
|
24
|
+
spec.add_dependency 'helix_runtime', '0.7.2'
|
25
25
|
spec.add_dependency 'rake', '>= 10.0'
|
26
26
|
spec.add_development_dependency 'bundler', '~> 1.14'
|
27
27
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
data/src/lib.rs
CHANGED
@@ -4,138 +4,54 @@ extern crate csv;
|
|
4
4
|
|
5
5
|
use std::error::Error;
|
6
6
|
use std::io::Read;
|
7
|
-
use std::slice::from_raw_parts;
|
8
7
|
use helix::sys;
|
9
8
|
use helix::sys::{ID, VALUE};
|
10
|
-
use helix::{
|
9
|
+
use helix::{FromRuby, CheckResult, ToRuby};
|
11
10
|
use helix::libc::c_int;
|
12
11
|
|
13
|
-
struct VecWrap<T>(Vec<T>);
|
14
|
-
|
15
|
-
impl<T> UncheckedValue<VecWrap<T>> for VALUE
|
16
|
-
where
|
17
|
-
VALUE: UncheckedValue<T>,
|
18
|
-
{
|
19
|
-
fn to_checked(self) -> CheckResult<VecWrap<T>> {
|
20
|
-
if unsafe { sys::RB_TYPE_P(self, sys::T_ARRAY) } {
|
21
|
-
let slice = ruby_array_to_slice(self);
|
22
|
-
for val in slice.iter() {
|
23
|
-
if let Err(error) = val.to_checked() {
|
24
|
-
return Err(format!("Failed to convert value for Vec<T>: {}", error));
|
25
|
-
}
|
26
|
-
}
|
27
|
-
Ok(unsafe { CheckedValue::<VecWrap<T>>::new(self) })
|
28
|
-
} else {
|
29
|
-
let val = unsafe { CheckedValue::<String>::new(sys::rb_inspect(self)) };
|
30
|
-
Err(format!(
|
31
|
-
"No implicit conversion of {} into Vec<String>",
|
32
|
-
val.to_rust()
|
33
|
-
))
|
34
|
-
}
|
35
|
-
}
|
36
|
-
}
|
37
|
-
|
38
|
-
fn ruby_array_to_slice<'a>(array: VALUE) -> &'a [VALUE] {
|
39
|
-
let length = unsafe { sys::RARRAY_LEN(array) } as usize;
|
40
|
-
unsafe { from_raw_parts(sys::RARRAY_CONST_PTR(array), length) }
|
41
|
-
}
|
42
|
-
|
43
|
-
impl ToRust<VecWrap<String>> for CheckedValue<VecWrap<String>>
|
44
|
-
where
|
45
|
-
VALUE: UncheckedValue<String>,
|
46
|
-
CheckedValue<String>: ToRust<String>,
|
47
|
-
{
|
48
|
-
fn to_rust(self) -> VecWrap<String> {
|
49
|
-
let slice = ruby_array_to_slice(self.inner);
|
50
|
-
let mut vec: Vec<String> = Vec::with_capacity(slice.len());
|
51
|
-
for val in slice.iter() {
|
52
|
-
let checked = val.to_checked().unwrap();
|
53
|
-
vec.push(checked.to_rust());
|
54
|
-
}
|
55
|
-
VecWrap(vec)
|
56
|
-
}
|
57
|
-
}
|
58
|
-
|
59
|
-
impl ToRust<VecWrap<VecWrap<String>>> for CheckedValue<VecWrap<VecWrap<String>>>
|
60
|
-
where
|
61
|
-
VALUE: UncheckedValue<VecWrap<String>>,
|
62
|
-
CheckedValue<VecWrap<String>>: ToRust<VecWrap<String>>,
|
63
|
-
{
|
64
|
-
fn to_rust(self) -> VecWrap<VecWrap<String>> {
|
65
|
-
let slice = ruby_array_to_slice(self.inner);
|
66
|
-
let mut vec: Vec<VecWrap<String>> = Vec::with_capacity(slice.len());
|
67
|
-
for val in slice.iter() {
|
68
|
-
let checked = val.to_checked().unwrap();
|
69
|
-
vec.push(checked.to_rust());
|
70
|
-
}
|
71
|
-
VecWrap(vec)
|
72
|
-
}
|
73
|
-
}
|
74
|
-
|
75
12
|
#[cfg_attr(windows, link(name = "helix-runtime"))]
|
76
13
|
extern "C" {
|
77
|
-
pub fn rb_ary_new_capa(capa: isize) -> VALUE;
|
78
|
-
pub fn rb_ary_entry(ary: VALUE, offset: isize) -> VALUE;
|
79
|
-
pub fn rb_ary_push(ary: VALUE, item: VALUE) -> VALUE;
|
80
14
|
pub fn rb_block_given_p() -> c_int;
|
81
15
|
pub fn rb_yield(value: VALUE);
|
82
16
|
pub fn rb_funcall(value: VALUE, name: ID, nargs: c_int, ...) -> VALUE;
|
83
17
|
}
|
84
18
|
|
85
|
-
|
86
|
-
fn to_ruby(self) -> VALUE {
|
87
|
-
let ary = unsafe { rb_ary_new_capa(self.0.len() as isize) };
|
88
|
-
for row in self.0 {
|
89
|
-
let inner_array = unsafe { rb_ary_new_capa(row.len() as isize) };
|
90
|
-
for column in row.iter() {
|
91
|
-
unsafe {
|
92
|
-
rb_ary_push(inner_array, column.to_ruby());
|
93
|
-
}
|
94
|
-
}
|
95
|
-
unsafe {
|
96
|
-
rb_ary_push(ary, inner_array);
|
97
|
-
}
|
98
|
-
}
|
99
|
-
ary
|
100
|
-
}
|
101
|
-
}
|
102
|
-
|
103
|
-
fn generate_lines(rows: VecWrap<VecWrap<String>>) -> Result<String, Box<Error>> {
|
19
|
+
fn generate_lines(rows: Vec<Vec<String>>) -> Result<String, Box<Error>> {
|
104
20
|
let mut wtr = csv::WriterBuilder::new().from_writer(vec![]);
|
105
|
-
for row in rows
|
106
|
-
wtr.write_record(&
|
21
|
+
for row in rows {
|
22
|
+
wtr.write_record(&row)?;
|
107
23
|
}
|
108
24
|
|
109
25
|
Ok(String::from_utf8(wtr.into_inner()?)?)
|
110
26
|
}
|
111
27
|
|
112
28
|
fn record_to_ruby(record: &csv::ByteRecord) -> VALUE {
|
113
|
-
let inner_array = unsafe { rb_ary_new_capa(record.len() as isize) };
|
29
|
+
let inner_array = unsafe { sys::rb_ary_new_capa(record.len() as isize) };
|
114
30
|
for column in record.iter() {
|
115
31
|
unsafe {
|
116
32
|
let column_value =
|
117
33
|
sys::rb_utf8_str_new(column.as_ptr() as *const i8, column.len() as i64);
|
118
|
-
rb_ary_push(inner_array, column_value);
|
34
|
+
sys::rb_ary_push(inner_array, column_value);
|
119
35
|
}
|
120
36
|
}
|
121
37
|
inner_array
|
122
38
|
}
|
123
39
|
|
124
|
-
|
125
|
-
|
126
|
-
fn to_checked(self) -> CheckResult<Enumerator> {
|
127
|
-
Ok(unsafe { CheckedValue::new(self) })
|
128
|
-
}
|
40
|
+
struct Enumerator {
|
41
|
+
value: VALUE,
|
129
42
|
}
|
130
43
|
|
131
|
-
impl
|
132
|
-
|
133
|
-
|
44
|
+
impl FromRuby for Enumerator {
|
45
|
+
type Checked = Enumerator;
|
46
|
+
|
47
|
+
fn from_ruby(value: VALUE) -> CheckResult<Enumerator> {
|
48
|
+
// TODO: validate this?
|
49
|
+
Ok(Enumerator { value })
|
134
50
|
}
|
135
|
-
}
|
136
51
|
|
137
|
-
|
138
|
-
|
52
|
+
fn from_checked(checked: Enumerator) -> Enumerator {
|
53
|
+
checked
|
54
|
+
}
|
139
55
|
}
|
140
56
|
|
141
57
|
struct EnumeratorRead {
|
@@ -146,7 +62,7 @@ struct EnumeratorRead {
|
|
146
62
|
impl EnumeratorRead {
|
147
63
|
fn new(value: VALUE) -> EnumeratorRead {
|
148
64
|
EnumeratorRead {
|
149
|
-
value
|
65
|
+
value,
|
150
66
|
next: None,
|
151
67
|
}
|
152
68
|
}
|
@@ -180,14 +96,10 @@ impl EnumeratorRead {
|
|
180
96
|
0,
|
181
97
|
)
|
182
98
|
};
|
183
|
-
let slice = unsafe {
|
184
|
-
from_raw_parts(
|
185
|
-
sys::RSTRING_PTR(next) as *const u8,
|
186
|
-
sys::RSTRING_LEN(next) as usize,
|
187
|
-
)
|
188
|
-
};
|
189
99
|
|
190
|
-
|
100
|
+
let string = String::from_ruby_unwrap(next);
|
101
|
+
|
102
|
+
self.read_and_store_overflow(buf, string.as_bytes())
|
191
103
|
}
|
192
104
|
}
|
193
105
|
|
@@ -221,43 +133,39 @@ fn yield_csv(data: Enumerator) -> Result<(), csv::Error> {
|
|
221
133
|
Ok(())
|
222
134
|
}
|
223
135
|
|
224
|
-
fn parse_csv(data: String) -> Result<Vec<
|
225
|
-
|
226
|
-
reader
|
136
|
+
fn parse_csv(data: String) -> Result<Vec<Vec<VALUE>>, csv::Error> {
|
137
|
+
csv_reader(data.as_bytes())
|
227
138
|
.records()
|
228
|
-
.
|
139
|
+
.map(|r| r.map(record_to_vec))
|
140
|
+
.collect()
|
141
|
+
}
|
142
|
+
|
143
|
+
fn record_to_vec(record: csv::StringRecord) -> Vec<VALUE> {
|
144
|
+
record.iter().map(|s| s.to_ruby().unwrap()).collect()
|
229
145
|
}
|
230
146
|
|
231
147
|
ruby! {
|
232
148
|
class RscsvReader {
|
233
|
-
def each_internal(data: Enumerator) {
|
234
|
-
|
235
|
-
Err(_) => throw!("Error parsing CSV"),
|
236
|
-
Ok(_) => ()
|
237
|
-
}
|
149
|
+
def each_internal(data: Enumerator) -> Result<(), &'static str> {
|
150
|
+
yield_csv(data).map_err(|_| "Error parsing CSV")
|
238
151
|
}
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
Ok(result) => VecWrap(result)
|
243
|
-
}
|
152
|
+
|
153
|
+
def parse(data: String) -> Result<Vec<Vec<VALUE>>, &'static str> {
|
154
|
+
parse_csv(data).map_err(|_| "Error parsing CSV")
|
244
155
|
}
|
245
156
|
}
|
157
|
+
|
246
158
|
class RscsvWriter {
|
247
|
-
def generate_line(row:
|
159
|
+
def generate_line(row: Vec<String>) -> Result<String, &'static str> {
|
248
160
|
let mut wtr = csv::WriterBuilder::new().from_writer(vec![]);
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
}
|
161
|
+
|
162
|
+
wtr.write_record(&row)
|
163
|
+
.map(|_| String::from_utf8(wtr.into_inner().unwrap()).unwrap())
|
164
|
+
.map_err(|_| "Error generating csv")
|
254
165
|
}
|
255
166
|
|
256
|
-
def generate_lines(rows:
|
257
|
-
|
258
|
-
Err(_) => throw!("Error generating csv"),
|
259
|
-
Ok(csv) => csv
|
260
|
-
}
|
167
|
+
def generate_lines(rows: Vec<Vec<String>>) -> Result<String, &'static str> {
|
168
|
+
generate_lines(rows).map_err(|_| "Error generating csv")
|
261
169
|
}
|
262
170
|
}
|
263
171
|
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rscsv
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ville Lautanala
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-12-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: helix_runtime
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.7.2
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: 0.7.2
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -128,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
128
128
|
version: '0'
|
129
129
|
requirements: []
|
130
130
|
rubyforge_project:
|
131
|
-
rubygems_version: 2.
|
131
|
+
rubygems_version: 2.7.3
|
132
132
|
signing_key:
|
133
133
|
specification_version: 4
|
134
134
|
summary: Rust-powered CSV
|