rscsv 0.1.1 → 0.2.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 +22 -20
- data/Cargo.toml +2 -2
- data/README.md +6 -2
- data/bin/benchmark +18 -0
- data/lib/rscsv/version.rb +1 -1
- data/lib/rscsv.rb +1 -0
- data/rscsv.gemspec +2 -3
- data/src/lib.rs +63 -11
- metadata +7 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 33297a5689b1597d449a3c0779895ce85b7c764c
|
|
4
|
+
data.tar.gz: 5c1ae9a22753cc171b73044bec4c11ff8cce924a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f4b8863ca0859d40012f2d595ef7f75ab7405c9d0361ba02776b577814e23a4fc051983143f2b51ec812b29b46ac51c049efe96ae57a8ddc5fad3390a54925e2
|
|
7
|
+
data.tar.gz: be1e68c1f448be078683b2e29762802ce5d8cbff3f2916b952e002156eac3d15c483df93969b522d85fbd7b5673e0e9ab984b45d8ac47e5fb65456ee03b5671f
|
data/Cargo.lock
CHANGED
|
@@ -2,15 +2,10 @@
|
|
|
2
2
|
name = "rscsv"
|
|
3
3
|
version = "0.1.0"
|
|
4
4
|
dependencies = [
|
|
5
|
-
"csv 0.
|
|
6
|
-
"helix 0.6.
|
|
5
|
+
"csv 1.0.0-beta.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
6
|
+
"helix 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
7
7
|
]
|
|
8
8
|
|
|
9
|
-
[[package]]
|
|
10
|
-
name = "byteorder"
|
|
11
|
-
version = "1.0.0"
|
|
12
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
13
|
-
|
|
14
9
|
[[package]]
|
|
15
10
|
name = "cslice"
|
|
16
11
|
version = "0.3.0"
|
|
@@ -23,23 +18,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
|
23
18
|
|
|
24
19
|
[[package]]
|
|
25
20
|
name = "csv"
|
|
26
|
-
version = "0.
|
|
21
|
+
version = "1.0.0-beta.1"
|
|
22
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
23
|
+
dependencies = [
|
|
24
|
+
"csv-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
25
|
+
"serde 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
[[package]]
|
|
29
|
+
name = "csv-core"
|
|
30
|
+
version = "0.1.0"
|
|
27
31
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
28
32
|
dependencies = [
|
|
29
|
-
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
30
33
|
"memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
31
|
-
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
32
34
|
]
|
|
33
35
|
|
|
34
36
|
[[package]]
|
|
35
37
|
name = "helix"
|
|
36
|
-
version = "0.6.
|
|
38
|
+
version = "0.6.1"
|
|
37
39
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
38
40
|
dependencies = [
|
|
39
41
|
"cslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
40
42
|
"cstr-macro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
41
43
|
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
42
|
-
"libcruby-sys 0.6.
|
|
44
|
+
"libcruby-sys 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
43
45
|
]
|
|
44
46
|
|
|
45
47
|
[[package]]
|
|
@@ -49,7 +51,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
|
49
51
|
|
|
50
52
|
[[package]]
|
|
51
53
|
name = "libcruby-sys"
|
|
52
|
-
version = "0.6.
|
|
54
|
+
version = "0.6.1"
|
|
53
55
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
54
56
|
dependencies = [
|
|
55
57
|
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
@@ -64,17 +66,17 @@ dependencies = [
|
|
|
64
66
|
]
|
|
65
67
|
|
|
66
68
|
[[package]]
|
|
67
|
-
name = "
|
|
68
|
-
version = "0.
|
|
69
|
+
name = "serde"
|
|
70
|
+
version = "1.0.7"
|
|
69
71
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
70
72
|
|
|
71
73
|
[metadata]
|
|
72
|
-
"checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8"
|
|
73
74
|
"checksum cslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0f8cb7306107e4b10e64994de6d3274bd08996a7c1322a27b86482392f96be0a"
|
|
74
75
|
"checksum cstr-macro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db53fddba18cdd35477a7213a3ef6acfbfa333c31b42ce019e544c4a1420a06f"
|
|
75
|
-
"checksum csv 0.
|
|
76
|
-
"checksum
|
|
76
|
+
"checksum csv 1.0.0-beta.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81675dd89651e2aa0989e6a5249dc5c5bcfc13772baec7f9652208e7691e0955"
|
|
77
|
+
"checksum csv-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6a11ab3094dd197341f9d66753789a5cdf29ce35450a7d6e7968024e2d44519c"
|
|
78
|
+
"checksum helix 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b97612e592273062bb127433a22b201c9b58375c95fc7ace355ee2fc6be61ebe"
|
|
77
79
|
"checksum libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)" = "babb8281da88cba992fa1f4ddec7d63ed96280a1a53ec9b919fd37b53d71e502"
|
|
78
|
-
"checksum libcruby-sys 0.6.
|
|
80
|
+
"checksum libcruby-sys 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d9ae575f064157bc55bb543589971959e3a0163fd49be03fef4c1f3440146114"
|
|
79
81
|
"checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4"
|
|
80
|
-
"checksum
|
|
82
|
+
"checksum serde 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c0c3d79316a6051231925504f6ef893d45088e8823c77a8331a3dcf427ee9087"
|
data/Cargo.toml
CHANGED
data/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Rscsv
|
|
2
2
|
|
|
3
|
-
Fast CSV using Rust extensions.
|
|
3
|
+
Fast CSV using Rust extensions. Can read arrays of arrays from strings and write
|
|
4
|
+
strings from arrays of arrays.
|
|
4
5
|
|
|
5
6
|
[](https://travis-ci.org/lautis/rscsv)
|
|
6
7
|
|
|
@@ -22,6 +23,9 @@ Rscsv::Writer.generate_lines([['1', '2', '3'], ['3', '4', '5']])
|
|
|
22
23
|
# => 1,2,3\n4,5,6\n
|
|
23
24
|
Rscsv::Writer.generate_line(['1', '2', '3'])
|
|
24
25
|
# => 1,2,3\n
|
|
26
|
+
|
|
27
|
+
Rscsv::Reader.parse("1,2,3\n4,5,6")
|
|
28
|
+
# => [["1", "2", "3"], ["4", "5", "6"]]
|
|
25
29
|
```
|
|
26
30
|
|
|
27
|
-
This is 3x faster than using native Ruby `CSV.generate`.
|
|
31
|
+
This is ~3x faster than using native Ruby `CSV.generate` or `CSV.parse`.
|
data/bin/benchmark
CHANGED
|
@@ -11,6 +11,10 @@ rows = (0...1000).map do
|
|
|
11
11
|
(0...10).map { SecureRandom.hex }
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
+
csv_string = CSV.generate do |csv|
|
|
15
|
+
rows.each { |row| csv << row }
|
|
16
|
+
end
|
|
17
|
+
|
|
14
18
|
Benchmark.ips do |x|
|
|
15
19
|
x.report('Ruby CSV') do |times|
|
|
16
20
|
times.times do
|
|
@@ -26,3 +30,17 @@ Benchmark.ips do |x|
|
|
|
26
30
|
|
|
27
31
|
x.compare!
|
|
28
32
|
end
|
|
33
|
+
|
|
34
|
+
Benchmark.ips do |x|
|
|
35
|
+
x.report('Ruby CSV') do |times|
|
|
36
|
+
times.times do
|
|
37
|
+
CSV.parse(csv_string)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
x.report('rscsv') do |times|
|
|
42
|
+
times.times { Rscsv::Reader.parse(csv_string) }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
x.compare!
|
|
46
|
+
end
|
data/lib/rscsv/version.rb
CHANGED
data/lib/rscsv.rb
CHANGED
data/rscsv.gemspec
CHANGED
|
@@ -10,8 +10,7 @@ Gem::Specification.new do |spec|
|
|
|
10
10
|
spec.email = ['lautis@gmail.com']
|
|
11
11
|
|
|
12
12
|
spec.summary = 'Rust-powered CSV'
|
|
13
|
-
spec.description = 'Fast CSV using Rust extensions.'
|
|
14
|
-
'Currently only writes CSV.'
|
|
13
|
+
spec.description = 'Fast CSV using Rust extensions.'
|
|
15
14
|
spec.homepage = 'https://github.com/lautis/rscsv'
|
|
16
15
|
spec.license = 'MIT'
|
|
17
16
|
|
|
@@ -23,7 +22,7 @@ Gem::Specification.new do |spec|
|
|
|
23
22
|
spec.require_paths = ['lib']
|
|
24
23
|
spec.extensions = Dir['ext/extconf.rb']
|
|
25
24
|
|
|
26
|
-
spec.add_dependency 'helix_runtime', '
|
|
25
|
+
spec.add_dependency 'helix_runtime', '0.6.1'
|
|
27
26
|
spec.add_dependency 'rake', '>= 10.0'
|
|
28
27
|
spec.add_development_dependency 'bundler', '~> 1.14'
|
|
29
28
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
data/src/lib.rs
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
extern crate helix;
|
|
3
3
|
extern crate csv;
|
|
4
4
|
|
|
5
|
+
use std::error::Error;
|
|
5
6
|
use helix::sys;
|
|
6
7
|
use helix::sys::VALUE;
|
|
7
|
-
use helix::{UncheckedValue, CheckResult, CheckedValue, ToRust};
|
|
8
|
+
use helix::{UncheckedValue, CheckResult, CheckedValue, ToRust, ToRuby};
|
|
8
9
|
|
|
9
10
|
struct VecWrap<T>(Vec<T>);
|
|
10
11
|
|
|
@@ -64,23 +65,74 @@ impl ToRust<VecWrap<VecWrap<String>>> for CheckedValue<VecWrap<VecWrap<String>>>
|
|
|
64
65
|
}
|
|
65
66
|
}
|
|
66
67
|
|
|
68
|
+
#[cfg_attr(windows, link(name="helix-runtime"))]
|
|
69
|
+
extern "C" {
|
|
70
|
+
pub fn rb_ary_new_capa(capa: isize) -> VALUE;
|
|
71
|
+
pub fn rb_ary_entry(ary: VALUE, offset: isize) -> VALUE;
|
|
72
|
+
pub fn rb_ary_push(ary: VALUE, item: VALUE) -> VALUE;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
impl ToRuby for VecWrap<csv::StringRecord> {
|
|
76
|
+
fn to_ruby(self) -> VALUE {
|
|
77
|
+
let ary = unsafe { rb_ary_new_capa(self.0.len() as isize) };
|
|
78
|
+
for row in self.0 {
|
|
79
|
+
let inner_array = unsafe { rb_ary_new_capa(row.len() as isize) };
|
|
80
|
+
for column in row.iter() {
|
|
81
|
+
unsafe {
|
|
82
|
+
rb_ary_push(inner_array, column.to_ruby());
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
unsafe {
|
|
86
|
+
rb_ary_push(ary, inner_array);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
ary
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
fn generate_lines(rows: VecWrap<VecWrap<String>>) -> Result<String, Box<Error>> {
|
|
94
|
+
let mut wtr = csv::WriterBuilder::new().from_writer(vec![]);
|
|
95
|
+
for row in rows.0 {
|
|
96
|
+
wtr.write_record(&(row.0))?;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return Ok(String::from_utf8(wtr.into_inner()?)?);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
fn parse_csv(data: String) -> Result<Vec<csv::StringRecord>, csv::Error> {
|
|
103
|
+
let mut reader = csv::ReaderBuilder::new()
|
|
104
|
+
.has_headers(false)
|
|
105
|
+
.from_reader(data.as_bytes());
|
|
106
|
+
let records = reader
|
|
107
|
+
.records()
|
|
108
|
+
.collect::<Result<Vec<csv::StringRecord>, csv::Error>>();
|
|
109
|
+
return records;
|
|
110
|
+
}
|
|
111
|
+
|
|
67
112
|
ruby! {
|
|
113
|
+
class RscsvReader {
|
|
114
|
+
def parse(data: String) -> VecWrap<csv::StringRecord> {
|
|
115
|
+
match parse_csv(data) {
|
|
116
|
+
Err(_) => throw!("Error parsing CSV"),
|
|
117
|
+
Ok(result) => return VecWrap(result)
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
68
121
|
class RscsvWriter {
|
|
69
122
|
def generate_line(row: VecWrap<String>) -> String {
|
|
70
|
-
let mut
|
|
71
|
-
|
|
72
|
-
|
|
123
|
+
let mut wtr = csv::WriterBuilder::new().from_writer(vec![]);
|
|
124
|
+
let result = wtr.write_record(&(row.0));
|
|
125
|
+
match result {
|
|
126
|
+
Err(_) => throw!("Error generating csv"),
|
|
127
|
+
Ok(_) => return String::from_utf8(wtr.into_inner().unwrap()).unwrap(),
|
|
128
|
+
};
|
|
73
129
|
}
|
|
74
130
|
|
|
75
131
|
def generate_lines(rows: VecWrap<VecWrap<String>>) -> String {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
for row in vec {
|
|
80
|
-
writer.write(row.0.into_iter()).unwrap();
|
|
132
|
+
match generate_lines(rows) {
|
|
133
|
+
Err(_) => throw!("Error generating csv"),
|
|
134
|
+
Ok(csv) => csv
|
|
81
135
|
}
|
|
82
|
-
|
|
83
|
-
return writer.into_string();
|
|
84
136
|
}
|
|
85
137
|
}
|
|
86
138
|
}
|
metadata
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rscsv
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.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-05-
|
|
11
|
+
date: 2017-05-25 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: helix_runtime
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- -
|
|
17
|
+
- - '='
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: 0.6.
|
|
19
|
+
version: 0.6.1
|
|
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.6.
|
|
26
|
+
version: 0.6.1
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: rake
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -80,7 +80,7 @@ dependencies:
|
|
|
80
80
|
- - "~>"
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
82
|
version: '2.7'
|
|
83
|
-
description: Fast CSV using Rust extensions.
|
|
83
|
+
description: Fast CSV using Rust extensions.
|
|
84
84
|
email:
|
|
85
85
|
- lautis@gmail.com
|
|
86
86
|
executables: []
|