rscsv 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Cargo.lock +23 -27
- data/Cargo.toml +2 -2
- data/lib/rscsv/version.rb +1 -1
- data/rscsv.gemspec +1 -1
- data/src/lib.rs +66 -31
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 147b5e77ae27df3d9db307249e6dca18bdcc6c438238c7b53ccf0637288c6a9c
|
|
4
|
+
data.tar.gz: d3eea2efba98f4dcd80c0d7c67fa0684ee02f4efc3df666a1fa88a954364ed94
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b83963c68975702176dd3fc3c16bc3d65fc211c8444cf6f36ec3ba5cd6ef954328a3034fdebfe07937fa651ab6708bf50d6646f643690f1e5b0d6d526880f601
|
|
7
|
+
data.tar.gz: a766556bb9de6518c77ee11071a7dfa8f8fb73d6d6b2035085d0a108a0146ec4540e5df0aafd3570a42fc46778149499f8bef720bcf798693930bd55b1dd28ba
|
data/Cargo.lock
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
[[package]]
|
|
2
|
-
name = "cslice"
|
|
3
|
-
version = "0.3.0"
|
|
4
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
5
|
-
|
|
6
1
|
[[package]]
|
|
7
2
|
name = "cstr-macro"
|
|
8
3
|
version = "0.1.0"
|
|
@@ -13,67 +8,68 @@ name = "csv"
|
|
|
13
8
|
version = "1.0.0-beta.5"
|
|
14
9
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
15
10
|
dependencies = [
|
|
16
|
-
"csv-core 0.1.
|
|
17
|
-
"serde 1.0.
|
|
11
|
+
"csv-core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
12
|
+
"serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
18
13
|
]
|
|
19
14
|
|
|
20
15
|
[[package]]
|
|
21
16
|
name = "csv-core"
|
|
22
|
-
version = "0.1.
|
|
17
|
+
version = "0.1.4"
|
|
23
18
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
24
19
|
dependencies = [
|
|
25
|
-
"memchr
|
|
20
|
+
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
26
21
|
]
|
|
27
22
|
|
|
28
23
|
[[package]]
|
|
29
24
|
name = "helix"
|
|
30
|
-
version = "0.7.
|
|
25
|
+
version = "0.7.3"
|
|
31
26
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
32
27
|
dependencies = [
|
|
33
|
-
"cslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
34
28
|
"cstr-macro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
35
|
-
"libc 0.2.
|
|
36
|
-
"libcruby-sys 0.7.
|
|
29
|
+
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
30
|
+
"libcruby-sys 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
37
31
|
]
|
|
38
32
|
|
|
39
33
|
[[package]]
|
|
40
34
|
name = "libc"
|
|
41
|
-
version = "0.2.
|
|
35
|
+
version = "0.2.39"
|
|
42
36
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
43
37
|
|
|
44
38
|
[[package]]
|
|
45
39
|
name = "libcruby-sys"
|
|
46
|
-
version = "0.7.
|
|
40
|
+
version = "0.7.3"
|
|
47
41
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
48
42
|
dependencies = [
|
|
49
|
-
"libc 0.2.
|
|
43
|
+
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
50
44
|
]
|
|
51
45
|
|
|
52
46
|
[[package]]
|
|
53
47
|
name = "memchr"
|
|
54
|
-
version = "
|
|
48
|
+
version = "2.0.1"
|
|
55
49
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
50
|
+
dependencies = [
|
|
51
|
+
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
52
|
+
]
|
|
56
53
|
|
|
57
54
|
[[package]]
|
|
58
55
|
name = "rscsv"
|
|
59
|
-
version = "0.
|
|
56
|
+
version = "0.5.0"
|
|
60
57
|
dependencies = [
|
|
61
58
|
"csv 1.0.0-beta.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
62
|
-
"helix 0.7.
|
|
59
|
+
"helix 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
63
60
|
]
|
|
64
61
|
|
|
65
62
|
[[package]]
|
|
66
63
|
name = "serde"
|
|
67
|
-
version = "1.0.
|
|
64
|
+
version = "1.0.29"
|
|
68
65
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
69
66
|
|
|
70
67
|
[metadata]
|
|
71
|
-
"checksum cslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0f8cb7306107e4b10e64994de6d3274bd08996a7c1322a27b86482392f96be0a"
|
|
72
68
|
"checksum cstr-macro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db53fddba18cdd35477a7213a3ef6acfbfa333c31b42ce019e544c4a1420a06f"
|
|
73
69
|
"checksum csv 1.0.0-beta.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e7a9e063dcebdb56c306f23e672bfd31df3da8ec5f6d696b35f2c29c2a9572f0"
|
|
74
|
-
"checksum csv-core 0.1.
|
|
75
|
-
"checksum helix 0.7.
|
|
76
|
-
"checksum libc 0.2.
|
|
77
|
-
"checksum libcruby-sys 0.7.
|
|
78
|
-
"checksum memchr
|
|
79
|
-
"checksum serde 1.0.
|
|
70
|
+
"checksum csv-core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4dd8e6d86f7ba48b4276ef1317edc8cc36167546d8972feb4a2b5fec0b374105"
|
|
71
|
+
"checksum helix 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1a5e45d09f37327fded2b1e0939ab4c061e181b0c007f82c53ccd03e869cf085"
|
|
72
|
+
"checksum libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)" = "f54263ad99207254cf58b5f701ecb432c717445ea2ee8af387334bdd1a03fdff"
|
|
73
|
+
"checksum libcruby-sys 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b0fb9beb529127d706dd12e26f961be3e527badb74a7b2e5d6b9d928fe6059"
|
|
74
|
+
"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
|
|
75
|
+
"checksum serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "4763b773978e495252615e814d2ad04773b2c1f85421c7913869a537f35cb406"
|
data/Cargo.toml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "rscsv"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.5.0"
|
|
4
4
|
authors = ["Ville Lautanala <lautis@gmail.com>"]
|
|
5
5
|
|
|
6
6
|
[lib]
|
|
@@ -8,5 +8,5 @@ authors = ["Ville Lautanala <lautis@gmail.com>"]
|
|
|
8
8
|
crate-type = ["cdylib"]
|
|
9
9
|
|
|
10
10
|
[dependencies]
|
|
11
|
-
helix = "0.7.
|
|
11
|
+
helix = "0.7.3"
|
|
12
12
|
csv = "1.0.0-beta.4"
|
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.7.
|
|
24
|
+
spec.add_dependency 'helix_runtime', '0.7.3'
|
|
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
|
@@ -5,21 +5,14 @@ extern crate csv;
|
|
|
5
5
|
use std::error::Error;
|
|
6
6
|
use std::io::Read;
|
|
7
7
|
use helix::sys;
|
|
8
|
-
use helix::sys::{
|
|
8
|
+
use helix::sys::{VALUE, RubyException};
|
|
9
9
|
use helix::{FromRuby, CheckResult, ToRuby};
|
|
10
|
-
use helix::libc::
|
|
10
|
+
use helix::libc::{c_void};
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
extern "C" {
|
|
14
|
-
pub fn rb_block_given_p() -> c_int;
|
|
15
|
-
pub fn rb_yield(value: VALUE);
|
|
16
|
-
pub fn rb_funcall(value: VALUE, name: ID, nargs: c_int, ...) -> VALUE;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
fn generate_lines(rows: Vec<Vec<String>>) -> Result<String, Box<Error>> {
|
|
12
|
+
fn generate_lines(rows: &[Vec<String>]) -> Result<String, Box<Error>> {
|
|
20
13
|
let mut wtr = csv::WriterBuilder::new().from_writer(vec![]);
|
|
21
14
|
for row in rows {
|
|
22
|
-
wtr.write_record(
|
|
15
|
+
wtr.write_record(row)?;
|
|
23
16
|
}
|
|
24
17
|
|
|
25
18
|
Ok(String::from_utf8(wtr.into_inner()?)?)
|
|
@@ -37,6 +30,33 @@ fn record_to_ruby(record: &csv::ByteRecord) -> VALUE {
|
|
|
37
30
|
inner_array
|
|
38
31
|
}
|
|
39
32
|
|
|
33
|
+
extern fn protect_wrapper<F>(closure: *mut c_void) -> VALUE
|
|
34
|
+
where F: FnOnce() -> VALUE {
|
|
35
|
+
let closure_option = closure as *mut Option<F>;
|
|
36
|
+
unsafe {
|
|
37
|
+
(*closure_option).take().unwrap()()
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
pub fn protect<F>(func: F) -> Result<VALUE, RubyException>
|
|
42
|
+
where
|
|
43
|
+
F: FnOnce() -> VALUE,
|
|
44
|
+
{
|
|
45
|
+
let mut state = sys::EMPTY_EXCEPTION;
|
|
46
|
+
let value = unsafe {
|
|
47
|
+
sys::rb_protect(
|
|
48
|
+
protect_wrapper::<F>,
|
|
49
|
+
&func as *const _ as *mut c_void,
|
|
50
|
+
&mut state,
|
|
51
|
+
)
|
|
52
|
+
};
|
|
53
|
+
if state == sys::EMPTY_EXCEPTION {
|
|
54
|
+
Ok(value)
|
|
55
|
+
} else {
|
|
56
|
+
Err(state)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
40
60
|
struct Enumerator {
|
|
41
61
|
value: VALUE,
|
|
42
62
|
}
|
|
@@ -89,24 +109,33 @@ impl EnumeratorRead {
|
|
|
89
109
|
}
|
|
90
110
|
|
|
91
111
|
fn read_from_external(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
|
92
|
-
let next = unsafe {
|
|
93
|
-
rb_funcall(
|
|
94
|
-
self.value,
|
|
95
|
-
sys::rb_intern("next\0".as_ptr() as *const i8),
|
|
96
|
-
0,
|
|
97
|
-
)
|
|
98
|
-
};
|
|
99
112
|
|
|
100
|
-
let
|
|
113
|
+
let value = self.value;
|
|
114
|
+
let result = protect(|| {
|
|
115
|
+
unsafe { sys::rb_funcall(
|
|
116
|
+
value,
|
|
117
|
+
sys::rb_intern("next\0".as_ptr() as *const i8),
|
|
118
|
+
0)
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
match result {
|
|
122
|
+
Ok(next) => {
|
|
123
|
+
let string = String::from_ruby_unwrap(next);
|
|
124
|
+
self.read_and_store_overflow(buf, string.as_bytes())
|
|
125
|
+
},
|
|
126
|
+
Err(state) => {
|
|
127
|
+
unsafe { sys::rb_jump_tag(state) };
|
|
128
|
+
//Err(std::io::Error::new(ErrorKind::Other, "Ruby Exception"))
|
|
129
|
+
}
|
|
130
|
+
}
|
|
101
131
|
|
|
102
|
-
self.read_and_store_overflow(buf, string.as_bytes())
|
|
103
132
|
}
|
|
104
133
|
}
|
|
105
134
|
|
|
106
135
|
impl Read for EnumeratorRead {
|
|
107
136
|
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
|
108
|
-
match self.next.
|
|
109
|
-
Some(inner) => self.read_and_store_overflow(buf,
|
|
137
|
+
match self.next.take() {
|
|
138
|
+
Some(ref inner) => self.read_and_store_overflow(buf, inner),
|
|
110
139
|
None => self.read_from_external(buf),
|
|
111
140
|
}
|
|
112
141
|
}
|
|
@@ -119,39 +148,45 @@ fn csv_reader<R: Read>(reader: R) -> csv::Reader<R> {
|
|
|
119
148
|
.from_reader(reader)
|
|
120
149
|
}
|
|
121
150
|
|
|
122
|
-
fn yield_csv(data: Enumerator) -> Result<(), csv::Error> {
|
|
151
|
+
fn yield_csv(data: &Enumerator) -> Result<(), csv::Error> {
|
|
123
152
|
let mut reader = csv_reader(EnumeratorRead::new(data.value));
|
|
124
153
|
let mut record = csv::ByteRecord::new();
|
|
125
154
|
|
|
126
155
|
while reader.read_byte_record(&mut record)? {
|
|
127
156
|
let inner_array = record_to_ruby(&record);
|
|
128
|
-
|
|
129
|
-
|
|
157
|
+
let result = protect(|| {
|
|
158
|
+
unsafe {
|
|
159
|
+
return sys::rb_yield(inner_array);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
if result.is_err() {
|
|
164
|
+
unsafe { sys::rb_jump_tag(result.unwrap_err()) };
|
|
130
165
|
}
|
|
131
166
|
}
|
|
132
167
|
|
|
133
168
|
Ok(())
|
|
134
169
|
}
|
|
135
170
|
|
|
136
|
-
fn parse_csv(data:
|
|
171
|
+
fn parse_csv(data: &str) -> Result<Vec<Vec<VALUE>>, csv::Error> {
|
|
137
172
|
csv_reader(data.as_bytes())
|
|
138
173
|
.records()
|
|
139
|
-
.map(|r| r.map(record_to_vec))
|
|
174
|
+
.map(|r| r.map(|v| record_to_vec(&v)))
|
|
140
175
|
.collect()
|
|
141
176
|
}
|
|
142
177
|
|
|
143
|
-
fn record_to_vec(record: csv::StringRecord) -> Vec<VALUE> {
|
|
178
|
+
fn record_to_vec(record: &csv::StringRecord) -> Vec<VALUE> {
|
|
144
179
|
record.iter().map(|s| s.to_ruby().unwrap()).collect()
|
|
145
180
|
}
|
|
146
181
|
|
|
147
182
|
ruby! {
|
|
148
183
|
class RscsvReader {
|
|
149
184
|
def each_internal(data: Enumerator) -> Result<(), &'static str> {
|
|
150
|
-
yield_csv(data).map_err(|_| "Error parsing CSV")
|
|
185
|
+
yield_csv(&data).map_err(|_| "Error parsing CSV")
|
|
151
186
|
}
|
|
152
187
|
|
|
153
188
|
def parse(data: String) -> Result<Vec<Vec<VALUE>>, &'static str> {
|
|
154
|
-
parse_csv(data).map_err(|_| "Error parsing CSV")
|
|
189
|
+
parse_csv(&data).map_err(|_| "Error parsing CSV")
|
|
155
190
|
}
|
|
156
191
|
}
|
|
157
192
|
|
|
@@ -165,7 +200,7 @@ ruby! {
|
|
|
165
200
|
}
|
|
166
201
|
|
|
167
202
|
def generate_lines(rows: Vec<Vec<String>>) -> Result<String, &'static str> {
|
|
168
|
-
generate_lines(rows).map_err(|_| "Error generating csv")
|
|
203
|
+
generate_lines(&rows).map_err(|_| "Error generating csv")
|
|
169
204
|
}
|
|
170
205
|
}
|
|
171
206
|
}
|
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.5.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:
|
|
11
|
+
date: 2018-03-18 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.7.
|
|
19
|
+
version: 0.7.3
|
|
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.7.
|
|
26
|
+
version: 0.7.3
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: rake
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|