faster_path 0.1.13 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Cargo.lock +26 -1
- data/Cargo.toml +1 -1
- data/Rakefile +32 -2
- data/lib/faster_path.rb +43 -65
- data/lib/faster_path/optional/monkeypatches.rb +2 -1
- data/lib/faster_path/optional/refinements.rb +1 -1
- data/lib/faster_path/version.rb +1 -1
- data/src/basename.rs +16 -34
- data/src/chop_basename.rs +46 -48
- data/src/dirname.rs +23 -38
- data/src/extname.rs +4 -11
- data/src/lib.rs +134 -28
- data/src/plus.rs +4 -31
- data/src/rust_arch_bits.rs +1 -1
- metadata +2 -14
- data/src/add_trailing_separator.rs +0 -29
- data/src/basename_for_chop.rs +0 -31
- data/src/both_are_blank.rs +0 -22
- data/src/dirname_for_chop.rs +0 -36
- data/src/entries.rs +0 -30
- data/src/has_trailing_separator.rs +0 -27
- data/src/is_absolute.rs +0 -17
- data/src/is_blank.rs +0 -15
- data/src/is_directory.rs +0 -18
- data/src/is_relative.rs +0 -16
- data/src/ruby_array.rs +0 -20
- data/src/ruby_string.rs +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4b227f5a94ba3ae27a33eab04fa65c80d95b9842
|
4
|
+
data.tar.gz: 6cf955a639547780ecd12279dd50c8f00343b772
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2571373e3f523f8db360b7b68593d192b10b4e718ba8f12cdc47292479c9e6facb74498d799dca7121aa4e895a7d2088b8d921855bd6857a3c9f1c7512617fcb
|
7
|
+
data.tar.gz: 3e2c243a5921e93c3e0f47e028aa2e7b10cbdf5eb304830093e869a6abca1159b6b86dc627516c548e404b5ce738ecbc8fd2f5a5b5e48ef802d8e20a7c392d34
|
data/Cargo.lock
CHANGED
@@ -3,7 +3,7 @@ name = "faster_path"
|
|
3
3
|
version = "0.0.1"
|
4
4
|
dependencies = [
|
5
5
|
"array_tool 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
6
|
-
"
|
6
|
+
"ruru 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
7
7
|
]
|
8
8
|
|
9
9
|
[[package]]
|
@@ -11,11 +11,36 @@ name = "array_tool"
|
|
11
11
|
version = "0.4.1"
|
12
12
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
13
13
|
|
14
|
+
[[package]]
|
15
|
+
name = "lazy_static"
|
16
|
+
version = "0.2.8"
|
17
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
18
|
+
|
14
19
|
[[package]]
|
15
20
|
name = "libc"
|
16
21
|
version = "0.2.30"
|
17
22
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
18
23
|
|
24
|
+
[[package]]
|
25
|
+
name = "ruby-sys"
|
26
|
+
version = "0.2.20"
|
27
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
28
|
+
dependencies = [
|
29
|
+
"libc 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
30
|
+
]
|
31
|
+
|
32
|
+
[[package]]
|
33
|
+
name = "ruru"
|
34
|
+
version = "0.9.3"
|
35
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
36
|
+
dependencies = [
|
37
|
+
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
38
|
+
"ruby-sys 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
39
|
+
]
|
40
|
+
|
19
41
|
[metadata]
|
20
42
|
"checksum array_tool 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a07ccb27c611e5cda99e498e99ba71b3ecdb7db5df02096cef42a3df5b84542"
|
43
|
+
"checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf"
|
21
44
|
"checksum libc 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)" = "2370ca07ec338939e356443dac2296f581453c35fe1e3a3ed06023c49435f915"
|
45
|
+
"checksum ruby-sys 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = "e71509f17ce93733dc196258e168b58050490a156b04563816a8120a74ba04c7"
|
46
|
+
"checksum ruru 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6486d6c50b7a08246a492a61893635c1977d41c138041d443eb603f6298e0273"
|
data/Cargo.toml
CHANGED
data/Rakefile
CHANGED
@@ -24,8 +24,38 @@ task :sysinfo do
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
desc "Add libruby to deps"
|
28
|
+
task :libruby_release do
|
29
|
+
filename = RbConfig::CONFIG["LIBRUBY_ALIASES"].split(" ").first
|
30
|
+
libfile = File.join(RbConfig::CONFIG["libdir"], filename)
|
31
|
+
deps = "target/release/deps"
|
32
|
+
|
33
|
+
printf "Copying libruby.so ... "
|
34
|
+
unless File.exist? "#{deps}/#{filename}"
|
35
|
+
FileUtils.mkdir_p deps
|
36
|
+
FileUtils.cp libfile, deps
|
37
|
+
end
|
38
|
+
exit 1 unless File.exist? "#{deps}/#{filename}"
|
39
|
+
puts "libruby.so copied."
|
40
|
+
end
|
41
|
+
|
42
|
+
desc "Add libruby to debug deps"
|
43
|
+
task :libruby_debug do
|
44
|
+
filename = RbConfig::CONFIG["LIBRUBY_ALIASES"].split(" ").first
|
45
|
+
libfile = File.join(RbConfig::CONFIG["libdir"], filename)
|
46
|
+
deps = "target/debug/deps"
|
47
|
+
|
48
|
+
printf "Copying libruby.so ... "
|
49
|
+
unless File.exist? "#{deps}/#{filename}"
|
50
|
+
FileUtils.mkdir_p deps
|
51
|
+
FileUtils.cp libfile, deps
|
52
|
+
end
|
53
|
+
exit 1 unless File.exist? "#{deps}/#{filename}"
|
54
|
+
puts "libruby.so copied."
|
55
|
+
end
|
56
|
+
|
27
57
|
desc "Build Rust extension"
|
28
|
-
task :
|
58
|
+
task build_src: :libruby_release do
|
29
59
|
puts "Building extension..."
|
30
60
|
sh "cargo build --release"
|
31
61
|
end
|
@@ -58,7 +88,7 @@ task :lint do
|
|
58
88
|
end
|
59
89
|
|
60
90
|
desc "Run Rust Tests"
|
61
|
-
task :
|
91
|
+
task cargo: :libruby_debug do
|
62
92
|
sh "cargo test -- --nocapture"
|
63
93
|
end
|
64
94
|
|
data/lib/faster_path.rb
CHANGED
@@ -4,6 +4,26 @@ require "ffi"
|
|
4
4
|
require 'faster_path/asset_resolution'
|
5
5
|
|
6
6
|
module FasterPath
|
7
|
+
FFI_LIBRARY = begin
|
8
|
+
prefix = Gem.win_platform? ? "" : "lib"
|
9
|
+
"#{File.expand_path("../target/release/", __dir__)}/#{prefix}faster_path.#{FFI::Platform::LIBSUFFIX}"
|
10
|
+
end
|
11
|
+
require 'fiddle'
|
12
|
+
library = Fiddle.dlopen(FFI_LIBRARY)
|
13
|
+
Fiddle::Function.
|
14
|
+
new(library['Init_faster_pathname'], [], Fiddle::TYPE_VOIDP).
|
15
|
+
call
|
16
|
+
|
17
|
+
FasterPathname.class_eval do
|
18
|
+
private :add_trailing_separator
|
19
|
+
private :basename
|
20
|
+
private :chop_basename
|
21
|
+
private :dirname
|
22
|
+
private :entries
|
23
|
+
private :extname
|
24
|
+
private :plus
|
25
|
+
end
|
26
|
+
|
7
27
|
def self.rust_arch_bits
|
8
28
|
Rust.rust_arch_bits
|
9
29
|
end
|
@@ -12,102 +32,60 @@ module FasterPath
|
|
12
32
|
1.size * 8
|
13
33
|
end
|
14
34
|
|
15
|
-
# Spec to Pathname#absolute?
|
16
35
|
def self.absolute?(pth)
|
17
|
-
|
36
|
+
FasterPathname.allocate.send(:absolute?, pth)
|
18
37
|
end
|
19
38
|
|
20
|
-
|
21
|
-
|
22
|
-
Rust.is_directory(pth)
|
39
|
+
def self.add_trailing_separator(pth)
|
40
|
+
FasterPathname.allocate.send(:add_trailing_separator, pth)
|
23
41
|
end
|
24
42
|
|
25
|
-
|
26
|
-
|
27
|
-
Rust.is_relative(pth)
|
43
|
+
def self.blank?(str)
|
44
|
+
"#{str}".strip.empty?
|
28
45
|
end
|
29
46
|
|
30
|
-
def self.
|
31
|
-
|
47
|
+
def self.basename(pth, ext="")
|
48
|
+
FasterPathname.allocate.send(:basename, pth, ext)
|
32
49
|
end
|
33
50
|
|
34
|
-
# Spec to Pathname#chop_basename
|
35
|
-
# WARNING! Pathname#chop_basename in STDLIB doesn't handle blank strings correctly!
|
36
|
-
# This implementation correctly handles blank strings just as Pathname had intended
|
37
|
-
# to handle non-path strings.
|
38
51
|
def self.chop_basename(pth)
|
39
|
-
|
40
|
-
|
41
|
-
[d, b] unless Rust.both_are_blank(d, b)
|
52
|
+
result = FasterPathname.allocate.send(:chop_basename, pth)
|
53
|
+
result unless result.empty?
|
42
54
|
end
|
43
55
|
|
44
|
-
def self.
|
45
|
-
|
56
|
+
def self.directory?(pth)
|
57
|
+
FasterPathname.allocate.send(:directory?, pth)
|
46
58
|
end
|
47
59
|
|
48
|
-
def self.
|
49
|
-
|
60
|
+
def self.dirname(pth)
|
61
|
+
FasterPathname.allocate.send(:dirname, pth)
|
50
62
|
end
|
51
63
|
|
52
|
-
def self.
|
53
|
-
|
64
|
+
def self.entries(pth)
|
65
|
+
FasterPathname.allocate.send(:entries, pth)
|
54
66
|
end
|
55
67
|
|
56
|
-
def self.
|
57
|
-
|
68
|
+
def self.extname(pth)
|
69
|
+
FasterPathname.allocate.send(:extname, pth)
|
58
70
|
end
|
59
71
|
|
60
72
|
def self.has_trailing_separator?(pth)
|
61
|
-
|
73
|
+
FasterPathname.allocate.send(:has_trailing_separator?, pth)
|
62
74
|
end
|
63
75
|
|
64
|
-
def self.
|
65
|
-
|
76
|
+
def self.plus(pth, pth2)
|
77
|
+
FasterPathname.allocate.send(:plus, pth, pth2)
|
66
78
|
end
|
67
79
|
|
68
|
-
def self.
|
69
|
-
|
80
|
+
def self.relative?(pth)
|
81
|
+
FasterPathname.allocate.send(:relative?, pth)
|
70
82
|
end
|
71
83
|
|
72
|
-
# EXAMPLE
|
73
|
-
# def self.one_and_two
|
74
|
-
# Rust.one_and_two.to_a
|
75
|
-
# end
|
76
|
-
|
77
84
|
module Rust
|
78
85
|
extend FFI::Library
|
79
|
-
ffi_lib
|
80
|
-
prefix = Gem.win_platform? ? "" : "lib"
|
81
|
-
"#{File.expand_path("../target/release/", __dir__)}/#{prefix}faster_path.#{FFI::Platform::LIBSUFFIX}"
|
82
|
-
end
|
83
|
-
|
84
|
-
class FromRustArray < FFI::Struct
|
85
|
-
layout :len, :size_t, # dynamic array layout
|
86
|
-
:data, :pointer #
|
87
|
-
|
88
|
-
def to_a
|
89
|
-
self[:data].get_array_of_string(0, self[:len]).compact
|
90
|
-
end
|
91
|
-
end
|
86
|
+
ffi_lib ::FasterPath::FFI_LIBRARY
|
92
87
|
|
93
88
|
attach_function :rust_arch_bits, [], :int32
|
94
|
-
attach_function :is_absolute, [ :string ], :bool
|
95
|
-
attach_function :is_directory, [ :string ], :bool
|
96
|
-
attach_function :is_relative, [ :string ], :bool
|
97
|
-
attach_function :is_blank, [ :string ], :bool
|
98
|
-
attach_function :both_are_blank, [ :string, :string ], :bool
|
99
|
-
attach_function :basename, [ :string, :string ], :string
|
100
|
-
attach_function :plus, [ :string, :string ], :string
|
101
|
-
attach_function :dirname, [ :string ], :string
|
102
|
-
attach_function :basename_for_chop, [ :string ], :string # decoupling behavior
|
103
|
-
attach_function :dirname_for_chop, [ :string ], :string # decoupling behavior
|
104
|
-
attach_function :add_trailing_separator, [ :string ], :string
|
105
|
-
attach_function :has_trailing_separator, [ :string ], :bool
|
106
|
-
attach_function :extname, [ :string ], :string
|
107
|
-
attach_function :entries, [ :string ], FromRustArray.by_value
|
108
|
-
|
109
|
-
# EXAMPLE
|
110
|
-
# attach_function :one_and_two, [], FromRustArray.by_value
|
111
89
|
end
|
112
90
|
private_constant :Rust
|
113
91
|
end
|
@@ -3,11 +3,12 @@ require 'pathname'
|
|
3
3
|
module FasterPath
|
4
4
|
module MonkeyPatches
|
5
5
|
# rubocop:disable Metrics/CyclomaticComplexity
|
6
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
6
7
|
def self._ruby_core_file!
|
7
8
|
::File.class_eval do
|
8
9
|
def self.basename(pth, ext = '')
|
9
10
|
pth = pth.to_path if pth.respond_to? :to_path
|
10
|
-
raise TypeError unless pth.is_a? String
|
11
|
+
raise TypeError unless pth.is_a?(String) && ext.is_a?(String)
|
11
12
|
FasterPath.basename(pth, ext)
|
12
13
|
end
|
13
14
|
|
data/lib/faster_path/version.rb
CHANGED
data/src/basename.rs
CHANGED
@@ -1,41 +1,23 @@
|
|
1
|
-
|
2
|
-
use
|
1
|
+
extern crate array_tool;
|
2
|
+
use path_parsing::extract_last_path_segment;
|
3
|
+
use self::array_tool::string::Squeeze;
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
return
|
5
|
+
pub fn basename(pth: &str, ext: &str) -> String {
|
6
|
+
// Known edge case
|
7
|
+
match &pth.squeeze("/")[..] {
|
8
|
+
"/" => { return "/".to_string() }
|
9
|
+
_ => {}
|
8
10
|
}
|
9
|
-
let pth = unsafe { CStr::from_ptr(c_pth) }.to_str().unwrap();
|
10
|
-
let ext = unsafe { CStr::from_ptr(c_ext) }.to_str().unwrap();
|
11
11
|
|
12
|
-
let name =
|
13
|
-
|
14
|
-
CString::new(name).unwrap().into_raw()
|
15
|
-
}
|
16
|
-
|
17
|
-
pub mod rust {
|
18
|
-
extern crate array_tool;
|
19
|
-
use path_parsing::extract_last_path_segment;
|
20
|
-
use self::array_tool::string::Squeeze;
|
12
|
+
let mut name = extract_last_path_segment(pth);
|
21
13
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
"/" => { return "/".to_string() }
|
26
|
-
_ => {}
|
14
|
+
if ext == ".*" {
|
15
|
+
if let Some(dot_i) = name.rfind('.') {
|
16
|
+
name = &name[0..dot_i];
|
27
17
|
}
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
if let Some(dot_i) = name.rfind('.') {
|
33
|
-
name = &name[0..dot_i];
|
34
|
-
}
|
35
|
-
} else if name.ends_with(ext) {
|
36
|
-
name = &name[..name.len() - ext.len()];
|
37
|
-
};
|
38
|
-
name.to_string()
|
39
|
-
}
|
18
|
+
} else if name.ends_with(ext) {
|
19
|
+
name = &name[..name.len() - ext.len()];
|
20
|
+
};
|
21
|
+
name.to_string()
|
40
22
|
}
|
41
23
|
|
data/src/chop_basename.rs
CHANGED
@@ -1,56 +1,54 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
use std::str;
|
1
|
+
use std::path::MAIN_SEPARATOR;
|
2
|
+
use std::str;
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
pub fn chop_basename(input: &str) -> Option<(String,String)> {
|
5
|
+
if input.is_empty() {
|
6
|
+
return None;
|
7
|
+
}
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
}
|
9
|
+
let mut offset = 0;
|
10
|
+
let mut trailing_slashes = input.chars().rev();
|
11
|
+
loop {
|
12
|
+
match trailing_slashes.next() {
|
13
|
+
Some(MAIN_SEPARATOR) => { offset = offset + 1 },
|
14
|
+
_ => { break },
|
17
15
|
}
|
16
|
+
}
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
if directory.is_empty() && (base.is_empty() || base == "/") {
|
24
|
-
return None
|
25
|
-
};
|
18
|
+
let input = &input[0..input.len()-offset];
|
19
|
+
let base = input.rsplit_terminator(MAIN_SEPARATOR).nth(0).unwrap_or("");
|
20
|
+
let directory = &input[0..input.len()-base.len()];
|
26
21
|
|
27
|
-
|
28
|
-
|
22
|
+
if directory.is_empty() && (base.is_empty() || base.chars().next().unwrap() == MAIN_SEPARATOR) {
|
23
|
+
return None
|
24
|
+
};
|
29
25
|
|
30
|
-
|
31
|
-
|
32
|
-
assert_eq!(chop_basename(&""[..]), None);
|
33
|
-
assert_eq!(chop_basename(&"/"[..]), None);
|
34
|
-
assert_eq!(
|
35
|
-
chop_basename(&"."[..]),
|
36
|
-
Some(("".to_string(), ".".to_string()))
|
37
|
-
);
|
38
|
-
assert_eq!(
|
39
|
-
chop_basename(&"asdf/asdf"[..]),
|
40
|
-
Some(("asdf/".to_string(), "asdf".to_string()))
|
41
|
-
);
|
42
|
-
assert_eq!(
|
43
|
-
chop_basename(&"asdf.txt"[..]),
|
44
|
-
Some(("".to_string(), "asdf.txt".to_string()))
|
45
|
-
);
|
46
|
-
assert_eq!(
|
47
|
-
chop_basename(&"asdf/"[..]),
|
48
|
-
Some(("".to_string(), "asdf".to_string()))
|
49
|
-
);
|
50
|
-
assert_eq!(
|
51
|
-
chop_basename(&"/asdf/"[..]),
|
52
|
-
Some(("/".to_string(), "asdf".to_string()))
|
53
|
-
);
|
54
|
-
}
|
26
|
+
Some((directory.to_string(), base.to_string()))
|
27
|
+
}
|
55
28
|
|
29
|
+
#[test]
|
30
|
+
fn it_chops_the_basename_and_dirname() {
|
31
|
+
assert_eq!(chop_basename(&""[..]), None);
|
32
|
+
assert_eq!(chop_basename(&"/"[..]), None);
|
33
|
+
assert_eq!(
|
34
|
+
chop_basename(&"."[..]),
|
35
|
+
Some(("".to_string(), ".".to_string()))
|
36
|
+
);
|
37
|
+
assert_eq!(
|
38
|
+
chop_basename(&"asdf/asdf"[..]),
|
39
|
+
Some(("asdf/".to_string(), "asdf".to_string()))
|
40
|
+
);
|
41
|
+
assert_eq!(
|
42
|
+
chop_basename(&"asdf.txt"[..]),
|
43
|
+
Some(("".to_string(), "asdf.txt".to_string()))
|
44
|
+
);
|
45
|
+
assert_eq!(
|
46
|
+
chop_basename(&"asdf/"[..]),
|
47
|
+
Some(("".to_string(), "asdf".to_string()))
|
48
|
+
);
|
49
|
+
assert_eq!(
|
50
|
+
chop_basename(&"/asdf/"[..]),
|
51
|
+
Some(("/".to_string(), "asdf".to_string()))
|
52
|
+
);
|
56
53
|
}
|
54
|
+
|
data/src/dirname.rs
CHANGED
@@ -1,46 +1,31 @@
|
|
1
|
-
use
|
2
|
-
use
|
1
|
+
use std::path::MAIN_SEPARATOR;
|
2
|
+
use path_parsing::{last_sep_i, last_non_sep_i, last_non_sep_i_before};
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
if
|
7
|
-
return
|
4
|
+
pub fn dirname(path: &str) -> String {
|
5
|
+
let r_str = path;
|
6
|
+
if r_str.is_empty() {
|
7
|
+
return ".".to_string();
|
8
8
|
}
|
9
|
-
let
|
10
|
-
|
11
|
-
|
12
|
-
}
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
return MAIN_SEPARATOR.to_string();
|
26
|
-
}
|
27
|
-
let sep_i = last_sep_i(r_str, non_sep_i);
|
28
|
-
if sep_i == -1 {
|
29
|
-
return ".".to_string();
|
30
|
-
}
|
31
|
-
if sep_i == 0 {
|
32
|
-
return MAIN_SEPARATOR.to_string();
|
33
|
-
}
|
34
|
-
let non_sep_i2 = last_non_sep_i_before(r_str, sep_i);
|
35
|
-
if non_sep_i2 != -1 {
|
36
|
-
return r_str[..(non_sep_i2 + 1) as usize].to_string();
|
37
|
-
} else {
|
38
|
-
return MAIN_SEPARATOR.to_string();
|
39
|
-
}
|
9
|
+
let non_sep_i = last_non_sep_i(r_str);
|
10
|
+
if non_sep_i == -1 {
|
11
|
+
return MAIN_SEPARATOR.to_string();
|
12
|
+
}
|
13
|
+
let sep_i = last_sep_i(r_str, non_sep_i);
|
14
|
+
if sep_i == -1 {
|
15
|
+
return ".".to_string();
|
16
|
+
}
|
17
|
+
if sep_i == 0 {
|
18
|
+
return MAIN_SEPARATOR.to_string();
|
19
|
+
}
|
20
|
+
let non_sep_i2 = last_non_sep_i_before(r_str, sep_i);
|
21
|
+
if non_sep_i2 != -1 {
|
22
|
+
return r_str[..(non_sep_i2 + 1) as usize].to_string();
|
23
|
+
} else {
|
24
|
+
return MAIN_SEPARATOR.to_string();
|
40
25
|
}
|
41
26
|
}
|
42
27
|
|
43
28
|
#[test]
|
44
29
|
fn returns_dot_for_empty_string(){
|
45
|
-
assert_eq!(
|
30
|
+
assert_eq!(dirname(""), ".".to_string());
|
46
31
|
}
|
data/src/extname.rs
CHANGED
@@ -1,20 +1,13 @@
|
|
1
|
-
use libc::c_char;
|
2
|
-
use std::ffi::{CStr, CString};
|
3
1
|
use path_parsing::extract_last_path_segment;
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
if c_pth.is_null() {
|
8
|
-
return c_pth
|
9
|
-
}
|
10
|
-
|
11
|
-
let name = extract_last_path_segment(unsafe { CStr::from_ptr(c_pth) }.to_str().unwrap());
|
3
|
+
pub fn extname(pth: &str) -> String {
|
4
|
+
let name = extract_last_path_segment(pth);
|
12
5
|
|
13
6
|
if let Some(dot_i) = name.rfind('.') {
|
14
7
|
if dot_i > 0 && dot_i < name.len() - 1 && name[..dot_i].chars().rev().next().unwrap() != '.' {
|
15
|
-
return
|
8
|
+
return String::from(&name[dot_i..])
|
16
9
|
}
|
17
10
|
}
|
18
11
|
|
19
|
-
|
12
|
+
String::from("")
|
20
13
|
}
|
data/src/lib.rs
CHANGED
@@ -4,34 +4,140 @@
|
|
4
4
|
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
5
5
|
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
6
6
|
// copied, modified, or distributed except according to those terms.
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
pub mod plus;
|
18
|
-
pub mod dirname;
|
19
|
-
pub mod chop_basename;
|
20
|
-
pub mod basename_for_chop;
|
21
|
-
pub mod dirname_for_chop;
|
22
|
-
pub mod add_trailing_separator;
|
23
|
-
pub mod has_trailing_separator;
|
24
|
-
pub mod extname;
|
25
|
-
pub mod entries;
|
7
|
+
#[macro_use]
|
8
|
+
extern crate ruru;
|
9
|
+
|
10
|
+
class!(FasterPathname);
|
11
|
+
|
12
|
+
mod basename;
|
13
|
+
mod chop_basename;
|
14
|
+
mod dirname;
|
15
|
+
mod extname;
|
16
|
+
mod plus;
|
26
17
|
pub mod rust_arch_bits;
|
27
18
|
mod path_parsing;
|
28
19
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
20
|
+
use ruru::{Class, Object, RString, Boolean, Array};
|
21
|
+
use std::path::{MAIN_SEPARATOR,Path};
|
22
|
+
use std::fs;
|
23
|
+
|
24
|
+
methods!(
|
25
|
+
FasterPathname,
|
26
|
+
_itself,
|
27
|
+
|
28
|
+
fn r_add_trailing_separator(pth: RString) -> RString {
|
29
|
+
let p = pth.ok().unwrap();
|
30
|
+
let x = format!("{}{}", p.to_str(), "a");
|
31
|
+
match x.rsplit_terminator(MAIN_SEPARATOR).next() {
|
32
|
+
Some("a") => p,
|
33
|
+
_ => RString::new(format!("{}{}", p.to_str(), MAIN_SEPARATOR).as_str())
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
fn r_is_absolute(pth: RString) -> Boolean {
|
38
|
+
Boolean::new(match pth.ok().unwrap_or(RString::new("")).to_str().chars().next() {
|
39
|
+
Some(c) => c == MAIN_SEPARATOR,
|
40
|
+
None => false
|
41
|
+
})
|
42
|
+
}
|
43
|
+
|
44
|
+
fn r_basename(pth: RString, ext: RString) -> RString {
|
45
|
+
RString::new(
|
46
|
+
&basename::basename(
|
47
|
+
pth.ok().unwrap_or(RString::new("")).to_str(),
|
48
|
+
ext.ok().unwrap_or(RString::new("")).to_str()
|
49
|
+
)[..]
|
50
|
+
)
|
51
|
+
}
|
52
|
+
|
53
|
+
fn r_chop_basename(pth: RString) -> Array {
|
54
|
+
let mut arr = Array::with_capacity(2);
|
55
|
+
let results = chop_basename::chop_basename(pth.ok().unwrap_or(RString::new("")).to_str());
|
56
|
+
match results {
|
57
|
+
Some((dirname, basename)) => {
|
58
|
+
arr.push(RString::new(&dirname[..]));
|
59
|
+
arr.push(RString::new(&basename[..]));
|
60
|
+
arr
|
61
|
+
},
|
62
|
+
None => arr
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
fn r_is_directory(pth: RString) -> Boolean {
|
67
|
+
Boolean::new(
|
68
|
+
Path::new(
|
69
|
+
pth.ok().unwrap_or(RString::new("")).to_str()
|
70
|
+
).is_dir()
|
71
|
+
)
|
72
|
+
}
|
73
|
+
|
74
|
+
fn r_dirname(pth: RString) -> RString {
|
75
|
+
RString::new(
|
76
|
+
&dirname::dirname(
|
77
|
+
pth.ok().unwrap_or(RString::new("")).to_str()
|
78
|
+
)[..]
|
79
|
+
)
|
80
|
+
}
|
81
|
+
|
82
|
+
fn r_entries(pth: RString) -> Array {
|
83
|
+
let files = fs::read_dir(pth.ok().unwrap_or(RString::new("")).to_str()).unwrap();
|
84
|
+
let mut arr = Array::new();
|
85
|
+
|
86
|
+
arr.push(RString::new("."));
|
87
|
+
arr.push(RString::new(".."));
|
88
|
+
|
89
|
+
for file in files {
|
90
|
+
let file_name_str = file.unwrap().file_name().into_string().unwrap();
|
91
|
+
arr.push(RString::new(&file_name_str[..]));
|
92
|
+
}
|
93
|
+
|
94
|
+
arr
|
95
|
+
}
|
96
|
+
|
97
|
+
fn r_extname(pth: RString) -> RString {
|
98
|
+
RString::new(
|
99
|
+
&extname::extname(pth.ok().unwrap_or(RString::new("")).to_str())[..]
|
100
|
+
)
|
101
|
+
}
|
102
|
+
|
103
|
+
fn r_has_trailing_separator(pth: RString) -> Boolean {
|
104
|
+
let v = pth.ok().unwrap_or(RString::new(""));
|
105
|
+
match chop_basename::chop_basename(v.to_str()) {
|
106
|
+
Some((a,b)) => {
|
107
|
+
Boolean::new(a.len() + b.len() < v.to_str().len())
|
108
|
+
},
|
109
|
+
_ => Boolean::new(false)
|
110
|
+
}
|
111
|
+
}
|
112
|
+
|
113
|
+
fn r_plus(pth1: RString, pth2: RString) -> RString {
|
114
|
+
RString::new(&plus::plus_paths(pth1.ok().unwrap().to_str(), pth2.ok().unwrap().to_str())[..])
|
115
|
+
}
|
116
|
+
|
117
|
+
fn r_is_relative(pth: RString) -> Boolean {
|
118
|
+
Boolean::new(
|
119
|
+
match pth.ok().unwrap_or(RString::new(&MAIN_SEPARATOR.to_string()[..])).to_str().chars().next() {
|
120
|
+
Some(c) => c != MAIN_SEPARATOR,
|
121
|
+
None => true
|
122
|
+
}
|
123
|
+
)
|
124
|
+
}
|
125
|
+
);
|
126
|
+
|
127
|
+
#[allow(non_snake_case)]
|
128
|
+
#[no_mangle]
|
129
|
+
pub extern "C" fn Init_faster_pathname(){
|
130
|
+
Class::new("FasterPathname", None).define(|itself| {
|
131
|
+
itself.def("absolute?", r_is_absolute);
|
132
|
+
itself.def("add_trailing_separator", r_add_trailing_separator);
|
133
|
+
itself.def("basename", r_basename);
|
134
|
+
itself.def("chop_basename", r_chop_basename);
|
135
|
+
itself.def("directory?", r_is_directory);
|
136
|
+
itself.def("dirname", r_dirname);
|
137
|
+
itself.def("entries", r_entries);
|
138
|
+
itself.def("extname", r_extname);
|
139
|
+
itself.def("has_trailing_separator?", r_has_trailing_separator);
|
140
|
+
itself.def("plus", r_plus);
|
141
|
+
itself.def("relative?", r_is_relative);
|
142
|
+
});
|
143
|
+
}
|
data/src/plus.rs
CHANGED
@@ -1,40 +1,13 @@
|
|
1
1
|
extern crate array_tool;
|
2
2
|
use std::path::Path;
|
3
|
-
use libc::c_char;
|
4
|
-
use std::ffi::{CStr,CString};
|
5
3
|
use std::str;
|
6
|
-
use chop_basename::
|
7
|
-
use basename::
|
8
|
-
use dirname::
|
4
|
+
use chop_basename::chop_basename;
|
5
|
+
use basename::basename;
|
6
|
+
use dirname::dirname;
|
9
7
|
use self::array_tool::vec::Shift;
|
10
8
|
use std::ops::Index;
|
11
9
|
|
12
|
-
|
13
|
-
pub extern fn plus(string: *const c_char, string2: *const c_char) -> *const c_char {
|
14
|
-
let c_str = unsafe {
|
15
|
-
if string.is_null() {
|
16
|
-
return string;
|
17
|
-
}
|
18
|
-
CStr::from_ptr(string)
|
19
|
-
};
|
20
|
-
|
21
|
-
let c_str2 = unsafe {
|
22
|
-
if string2.is_null() {
|
23
|
-
return string2;
|
24
|
-
}
|
25
|
-
CStr::from_ptr(string2)
|
26
|
-
};
|
27
|
-
|
28
|
-
let r_str = str::from_utf8(c_str.to_bytes()).unwrap();
|
29
|
-
let r_str2 = str::from_utf8(c_str2.to_bytes()).unwrap();
|
30
|
-
|
31
|
-
let result = plus_paths(r_str, r_str2);
|
32
|
-
|
33
|
-
let output = CString::new(result).unwrap();
|
34
|
-
output.into_raw()
|
35
|
-
}
|
36
|
-
|
37
|
-
fn plus_paths(path1: &str, path2: &str) -> String {
|
10
|
+
pub fn plus_paths(path1: &str, path2: &str) -> String {
|
38
11
|
let mut prefix2 = path2.to_string();
|
39
12
|
let mut index_list2: Vec<usize> = vec![];
|
40
13
|
let mut basename_list2: Vec<String> = vec![];
|
data/src/rust_arch_bits.rs
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: faster_path
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel P. Clark
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-09-
|
11
|
+
date: 2017-09-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -173,25 +173,13 @@ files:
|
|
173
173
|
- lib/faster_path/optional/monkeypatches.rb
|
174
174
|
- lib/faster_path/optional/refinements.rb
|
175
175
|
- lib/faster_path/version.rb
|
176
|
-
- src/add_trailing_separator.rs
|
177
176
|
- src/basename.rs
|
178
|
-
- src/basename_for_chop.rs
|
179
|
-
- src/both_are_blank.rs
|
180
177
|
- src/chop_basename.rs
|
181
178
|
- src/dirname.rs
|
182
|
-
- src/dirname_for_chop.rs
|
183
|
-
- src/entries.rs
|
184
179
|
- src/extname.rs
|
185
|
-
- src/has_trailing_separator.rs
|
186
|
-
- src/is_absolute.rs
|
187
|
-
- src/is_blank.rs
|
188
|
-
- src/is_directory.rs
|
189
|
-
- src/is_relative.rs
|
190
180
|
- src/lib.rs
|
191
181
|
- src/path_parsing.rs
|
192
182
|
- src/plus.rs
|
193
|
-
- src/ruby_array.rs
|
194
|
-
- src/ruby_string.rs
|
195
183
|
- src/rust_arch_bits.rs
|
196
184
|
homepage: https://github.com/danielpclark/faster_path
|
197
185
|
licenses:
|
@@ -1,29 +0,0 @@
|
|
1
|
-
use std::path::{Path, MAIN_SEPARATOR};
|
2
|
-
use libc::c_char;
|
3
|
-
use std::ffi::{CStr, CString};
|
4
|
-
use std::str;
|
5
|
-
|
6
|
-
#[no_mangle]
|
7
|
-
pub extern fn add_trailing_separator(string: *const c_char) -> *const c_char {
|
8
|
-
let c_str = unsafe {
|
9
|
-
if string.is_null() {
|
10
|
-
return string;
|
11
|
-
}
|
12
|
-
CStr::from_ptr(string)
|
13
|
-
};
|
14
|
-
let r_str = str::from_utf8(c_str.to_bytes()).unwrap_or("");
|
15
|
-
|
16
|
-
if r_str.is_empty() {
|
17
|
-
return string;
|
18
|
-
}
|
19
|
-
|
20
|
-
let path = Path::new(r_str);
|
21
|
-
let out_str = if !(path.to_str().unwrap().chars().last().unwrap() == '/') {
|
22
|
-
format!("{}{}", path.to_str().unwrap(), MAIN_SEPARATOR)
|
23
|
-
} else {
|
24
|
-
path.to_str().unwrap().to_string()
|
25
|
-
};
|
26
|
-
|
27
|
-
let output = CString::new(out_str).unwrap();
|
28
|
-
output.into_raw()
|
29
|
-
}
|
data/src/basename_for_chop.rs
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
use std::path::MAIN_SEPARATOR;
|
2
|
-
use libc::c_char;
|
3
|
-
use std::ffi::{CStr,CString};
|
4
|
-
use std::str;
|
5
|
-
|
6
|
-
#[no_mangle]
|
7
|
-
pub extern fn basename_for_chop(string: *const c_char) -> *const c_char {
|
8
|
-
let c_str = unsafe {
|
9
|
-
if string.is_null() {
|
10
|
-
return string;
|
11
|
-
}
|
12
|
-
CStr::from_ptr(string)
|
13
|
-
};
|
14
|
-
|
15
|
-
let r_str = str::from_utf8(c_str.to_bytes()).unwrap();
|
16
|
-
|
17
|
-
let mut offset = 0;
|
18
|
-
let mut trailing_slashes = r_str.chars().rev();
|
19
|
-
loop {
|
20
|
-
match trailing_slashes.next() {
|
21
|
-
Some(MAIN_SEPARATOR) => { offset = offset + 1 },
|
22
|
-
_ => { break },
|
23
|
-
}
|
24
|
-
}
|
25
|
-
|
26
|
-
let r_str = &r_str[0..r_str.len()-offset];
|
27
|
-
let part = r_str.rsplit_terminator(MAIN_SEPARATOR).nth(0).unwrap_or("");
|
28
|
-
|
29
|
-
let output = CString::new(part).unwrap();
|
30
|
-
output.into_raw()
|
31
|
-
}
|
data/src/both_are_blank.rs
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
use libc::c_char;
|
2
|
-
use std::ffi::{CStr};
|
3
|
-
use std::str;
|
4
|
-
|
5
|
-
#[no_mangle]
|
6
|
-
pub extern fn both_are_blank(s1: *const c_char, s2: *const c_char) -> bool {
|
7
|
-
let c_str1 = unsafe {
|
8
|
-
if s1.is_null() {
|
9
|
-
return true;
|
10
|
-
}
|
11
|
-
CStr::from_ptr(s1)
|
12
|
-
};
|
13
|
-
let c_str2 = unsafe {
|
14
|
-
if s2.is_null() {
|
15
|
-
return true;
|
16
|
-
}
|
17
|
-
CStr::from_ptr(s2)
|
18
|
-
};
|
19
|
-
|
20
|
-
str::from_utf8(c_str1.to_bytes()).unwrap().trim().is_empty() &&
|
21
|
-
str::from_utf8(c_str2.to_bytes()).unwrap().trim().is_empty()
|
22
|
-
}
|
data/src/dirname_for_chop.rs
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
use std::path::MAIN_SEPARATOR;
|
2
|
-
use libc::c_char;
|
3
|
-
use std::ffi::{CStr,CString};
|
4
|
-
use std::str;
|
5
|
-
|
6
|
-
#[no_mangle]
|
7
|
-
pub extern fn dirname_for_chop(string: *const c_char) -> *const c_char {
|
8
|
-
let c_str = unsafe {
|
9
|
-
if string.is_null() {
|
10
|
-
return string
|
11
|
-
}
|
12
|
-
CStr::from_ptr(string)
|
13
|
-
};
|
14
|
-
|
15
|
-
let r_str = str::from_utf8(c_str.to_bytes()).unwrap();
|
16
|
-
|
17
|
-
if r_str.is_empty() {
|
18
|
-
return string
|
19
|
-
}
|
20
|
-
|
21
|
-
let mut offset = 0;
|
22
|
-
let mut trailing_slashes = r_str.chars().rev();
|
23
|
-
loop {
|
24
|
-
match trailing_slashes.next() {
|
25
|
-
Some(MAIN_SEPARATOR) => { offset = offset + 1 },
|
26
|
-
_ => { break },
|
27
|
-
}
|
28
|
-
}
|
29
|
-
|
30
|
-
let r_str = &r_str[0..r_str.len()-offset];
|
31
|
-
|
32
|
-
let base = r_str.rsplit_terminator(MAIN_SEPARATOR).nth(0).unwrap_or("");
|
33
|
-
|
34
|
-
let output = CString::new(&r_str[0..r_str.len()-base.len()]).unwrap();
|
35
|
-
output.into_raw()
|
36
|
-
}
|
data/src/entries.rs
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
use libc::c_char;
|
2
|
-
use std::ffi::{CStr,CString};
|
3
|
-
use std::str;
|
4
|
-
use std::fs;
|
5
|
-
use ruby_array::RubyArray;
|
6
|
-
|
7
|
-
#[no_mangle]
|
8
|
-
pub extern fn entries(string: *const c_char) -> RubyArray {
|
9
|
-
let c_str = unsafe {
|
10
|
-
assert!(!string.is_null());
|
11
|
-
|
12
|
-
CStr::from_ptr(string)
|
13
|
-
};
|
14
|
-
|
15
|
-
let r_str = str::from_utf8(c_str.to_bytes()).unwrap();
|
16
|
-
|
17
|
-
let files = fs::read_dir(r_str).unwrap();
|
18
|
-
let mut files_vec = vec![];
|
19
|
-
|
20
|
-
files_vec.push(CString::new(".").unwrap().into_raw());
|
21
|
-
files_vec.push(CString::new("..").unwrap().into_raw());
|
22
|
-
|
23
|
-
for file in files {
|
24
|
-
let file_name_str = file.unwrap().file_name().into_string().unwrap();
|
25
|
-
let file_name_cstr = CString::new(file_name_str).unwrap().into_raw();
|
26
|
-
files_vec.push(file_name_cstr);
|
27
|
-
}
|
28
|
-
|
29
|
-
RubyArray::from_vec(files_vec)
|
30
|
-
}
|
@@ -1,27 +0,0 @@
|
|
1
|
-
use std::path::{Path, MAIN_SEPARATOR};
|
2
|
-
use libc::c_char;
|
3
|
-
use std::ffi::CStr;
|
4
|
-
use std::str;
|
5
|
-
|
6
|
-
#[no_mangle]
|
7
|
-
pub extern "C" fn has_trailing_separator(string: *const c_char) -> bool {
|
8
|
-
let c_str = unsafe {
|
9
|
-
if string.is_null() {
|
10
|
-
return false
|
11
|
-
}
|
12
|
-
CStr::from_ptr(string)
|
13
|
-
};
|
14
|
-
|
15
|
-
let r_str = str::from_utf8(c_str.to_bytes()).unwrap_or("");
|
16
|
-
let path = Path::new(r_str);
|
17
|
-
let last_component = path.iter().last();
|
18
|
-
if last_component.is_none() {
|
19
|
-
false
|
20
|
-
} else {
|
21
|
-
let mut parts: Vec<&str> = r_str.rsplit_terminator(MAIN_SEPARATOR).collect();
|
22
|
-
parts.retain(|x| !x.is_empty());
|
23
|
-
let last_part = parts.first().unwrap_or(&"").chars().last().unwrap_or(MAIN_SEPARATOR);
|
24
|
-
let last_char = r_str.chars().last().unwrap();
|
25
|
-
(last_part != last_char) && (last_char == MAIN_SEPARATOR)
|
26
|
-
}
|
27
|
-
}
|
data/src/is_absolute.rs
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
use libc::c_char;
|
2
|
-
use std::ffi::{CStr};
|
3
|
-
use std::path::MAIN_SEPARATOR;
|
4
|
-
|
5
|
-
|
6
|
-
#[no_mangle]
|
7
|
-
pub extern fn is_absolute(path: *const c_char) -> bool {
|
8
|
-
if path.is_null() {
|
9
|
-
return false;
|
10
|
-
}
|
11
|
-
let r_str = unsafe { CStr::from_ptr(path) }.to_str().unwrap();
|
12
|
-
|
13
|
-
match r_str.chars().next() {
|
14
|
-
Some(c) => c == MAIN_SEPARATOR,
|
15
|
-
None => false
|
16
|
-
}
|
17
|
-
}
|
data/src/is_blank.rs
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
use libc::c_char;
|
2
|
-
use std::ffi::{CStr};
|
3
|
-
use std::str;
|
4
|
-
|
5
|
-
#[no_mangle]
|
6
|
-
pub extern fn is_blank(string: *const c_char) -> bool {
|
7
|
-
let c_str = unsafe {
|
8
|
-
if string.is_null() {
|
9
|
-
return true;
|
10
|
-
}
|
11
|
-
CStr::from_ptr(string)
|
12
|
-
};
|
13
|
-
|
14
|
-
str::from_utf8(c_str.to_bytes()).unwrap().trim().is_empty()
|
15
|
-
}
|
data/src/is_directory.rs
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
use libc::c_char;
|
2
|
-
use std::ffi::{CStr};
|
3
|
-
use std::str;
|
4
|
-
use std::path::Path;
|
5
|
-
|
6
|
-
#[no_mangle]
|
7
|
-
pub extern fn is_directory(string: *const c_char) -> bool {
|
8
|
-
let c_str = unsafe {
|
9
|
-
if string.is_null() {
|
10
|
-
return false;
|
11
|
-
}
|
12
|
-
CStr::from_ptr(string)
|
13
|
-
};
|
14
|
-
|
15
|
-
let r_str = str::from_utf8(c_str.to_bytes()).unwrap_or("");
|
16
|
-
|
17
|
-
Path::new(r_str).is_dir()
|
18
|
-
}
|
data/src/is_relative.rs
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
use std::path::MAIN_SEPARATOR;
|
2
|
-
use libc::c_char;
|
3
|
-
use std::ffi::{CStr};
|
4
|
-
|
5
|
-
#[no_mangle]
|
6
|
-
pub extern fn is_relative(path: *const c_char) -> bool {
|
7
|
-
if path.is_null() {
|
8
|
-
return false;
|
9
|
-
}
|
10
|
-
let r_str = unsafe { CStr::from_ptr(path) }.to_str().unwrap();
|
11
|
-
|
12
|
-
match r_str.chars().next() {
|
13
|
-
Some(c) => c != MAIN_SEPARATOR,
|
14
|
-
None => true
|
15
|
-
}
|
16
|
-
}
|
data/src/ruby_array.rs
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
use libc;
|
2
|
-
use std::mem;
|
3
|
-
|
4
|
-
#[repr(C)]
|
5
|
-
pub struct RubyArray {
|
6
|
-
len: libc::size_t,
|
7
|
-
data: *const libc::c_void,
|
8
|
-
}
|
9
|
-
|
10
|
-
impl RubyArray {
|
11
|
-
#[allow(dead_code)]
|
12
|
-
pub fn from_vec<T>(vec: Vec<T>) -> RubyArray {
|
13
|
-
let array = RubyArray {
|
14
|
-
data: vec.as_ptr() as *const libc::c_void,
|
15
|
-
len: vec.len() as libc::size_t
|
16
|
-
};
|
17
|
-
mem::forget(vec);
|
18
|
-
array
|
19
|
-
}
|
20
|
-
}
|
data/src/ruby_string.rs
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
use libc::c_char;
|
2
|
-
use std::ffi::{CStr,CString};
|
3
|
-
use std::str;
|
4
|
-
|
5
|
-
pub struct RubyString;
|
6
|
-
|
7
|
-
// Coercing strs into Strings has some loss of performance
|
8
|
-
// You may use these methods temporarily but it would be much better
|
9
|
-
// to write all of this code out in each method using just str.
|
10
|
-
//
|
11
|
-
// Using these methods you will still get you 10X (= 900%) performance
|
12
|
-
// gain regardless. But really consider not using String. If you do
|
13
|
-
// as I've intstructed the performance gains will go from 900% to 1250%.
|
14
|
-
impl RubyString {
|
15
|
-
#[allow(dead_code)]
|
16
|
-
// FOR QUICK IMPLEMENTATION. NOT FOR PRODUCTION.
|
17
|
-
// SEE BENCHMARKS FOR SANCTIONED IMPLEMENTATION.
|
18
|
-
fn from_ruby(s: *const c_char) -> String {
|
19
|
-
let c_str = unsafe {
|
20
|
-
assert!(!s.is_null());
|
21
|
-
CStr::from_ptr(s)
|
22
|
-
};
|
23
|
-
(*str::from_utf8(c_str.to_bytes()).unwrap_or("")).to_string()
|
24
|
-
}
|
25
|
-
|
26
|
-
#[allow(dead_code)]
|
27
|
-
// FOR QUICK IMPLEMENTATION. NOT FOR PRODUCTION.
|
28
|
-
// SEE BENCHMARKS FOR SANCTIONED IMPLEMENTATION.
|
29
|
-
fn to_ruby<S: Into<String>>(s: S) -> *const c_char {
|
30
|
-
let r_str = s.into();
|
31
|
-
let s_slice: &str = &r_str[..];
|
32
|
-
CString::new(s_slice).unwrap().into_raw()
|
33
|
-
}
|
34
|
-
}
|