faster_path 0.0.1 → 0.0.2
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/.gitignore +3 -4
- data/Cargo.toml +1 -0
- data/{LICENSE.txt → MIT-LICENSE.txt} +0 -0
- data/README.md +36 -1
- data/Rakefile +27 -0
- data/ext/faster_path/extconf.rb +19 -0
- data/faster_path.gemspec +2 -1
- data/lib/faster_path.rb +20 -13
- data/lib/faster_path/optional/monkeypatches.rb +15 -0
- data/lib/faster_path/optional/refinements.rb +14 -0
- data/lib/faster_path/version.rb +1 -1
- data/src/lib.rs +90 -5
- metadata +10 -7
- data/target/release/libfaster_path.so +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab56b250d7522c94ed78c2754087e351691b4be2
|
4
|
+
data.tar.gz: ac3c62e7d2d87ccc264fc2e6cf5eced81c511a8b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e5171e63daf6173d3a57c37b446c015bd04b5abe5cac5b769ef9403734711c9a787b5070291c4bed6d6ef0ada61bb3f2be0b77a7f62a996ced1ed1ede6213114
|
7
|
+
data.tar.gz: 0d0f4ce1529dae792d785d7588ef3eb7b4dc4b9d4819ea230a3bb33dc9da889b88e2204fc99a2343822872ce90325950ce3edb94f04422cdeec61ba79f7fde68
|
data/.gitignore
CHANGED
data/Cargo.toml
CHANGED
File without changes
|
data/README.md
CHANGED
@@ -18,6 +18,14 @@ be a sledge hammer ;-)
|
|
18
18
|
|
19
19
|
## Installation
|
20
20
|
|
21
|
+
Ensure Rust is installed:
|
22
|
+
|
23
|
+
[Rust Downloads](https://www.rust-lang.org/downloads.html)
|
24
|
+
|
25
|
+
```
|
26
|
+
curl -sSf https://static.rust-lang.org/rustup.sh | sudo sh -s -- --channel=nightly
|
27
|
+
```
|
28
|
+
|
21
29
|
Add this line to your application's Gemfile:
|
22
30
|
|
23
31
|
```ruby
|
@@ -34,7 +42,34 @@ Or install it yourself as:
|
|
34
42
|
|
35
43
|
## Usage
|
36
44
|
|
37
|
-
|
45
|
+
Current methods implemented:
|
46
|
+
|
47
|
+
|Rust Implementation|Ruby Implementation|Performance Improvemant|
|
48
|
+
|---|---|---|
|
49
|
+
| `FasterPath.absolute?` | `Pathname#absolute?` | 545% to 1450% |
|
50
|
+
| `FasterPath.chop_basename` | `Pathname#chop_basename` | 6.7% to 54.6% |
|
51
|
+
| FasterPath.blank? | | |
|
52
|
+
|
53
|
+
You may choose to use the methods directly, or scope change to rewrite behavior on the
|
54
|
+
standard library with the included refinements, or even call a method to monkeypatch
|
55
|
+
everything everywhere.
|
56
|
+
|
57
|
+
**Note:** `Pathname#chop_basename` in Ruby STDLIB has a bug with blank strings, that is the
|
58
|
+
only difference in behavior against FasterPath's implementation.
|
59
|
+
|
60
|
+
For the scoped **refinements** you will need to
|
61
|
+
|
62
|
+
```
|
63
|
+
require "faster_path/optional/refinements"
|
64
|
+
using FasterPath::RefinePathname
|
65
|
+
```
|
66
|
+
|
67
|
+
And for the sldeghammer of monkey patching you can do
|
68
|
+
|
69
|
+
```
|
70
|
+
require "faster_path/optional/monkeypatching"
|
71
|
+
FasterPath.sledgehammer_everything!
|
72
|
+
```
|
38
73
|
|
39
74
|
## Development
|
40
75
|
|
data/Rakefile
CHANGED
@@ -1,5 +1,32 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
require "rake/testtask"
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
desc "Building extension..."
|
6
|
+
task :build_src do
|
7
|
+
puts "Building extension..."
|
8
|
+
system("cargo build --release")
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "Cleaning up build..."
|
12
|
+
task :clean_src do
|
13
|
+
puts "Cleaning up build..."
|
14
|
+
# Remove all but library file
|
15
|
+
FileUtils.
|
16
|
+
rm_rf(
|
17
|
+
Dir.
|
18
|
+
glob('target/release/*').
|
19
|
+
keep_if {|f|
|
20
|
+
# TODO: change regex to include other library extensions for other OS builds
|
21
|
+
!f[/\.so\z/]
|
22
|
+
}
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "Compiling Rust extension..."
|
27
|
+
task :build_lib => [:build_src, :clean_src] do
|
28
|
+
puts "Completed build!"
|
29
|
+
end
|
3
30
|
|
4
31
|
Rake::TestTask.new(:test) do |t|
|
5
32
|
t.libs << "test"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'mkmf'
|
2
|
+
|
3
|
+
have_header('Dummy Makefile')
|
4
|
+
|
5
|
+
unless find_executable('cargo')
|
6
|
+
puts "You need to have Rust installed for this gem to build natively."
|
7
|
+
puts "Please install the latest nightly build:"
|
8
|
+
puts
|
9
|
+
puts "curl -sSf https://static.rust-lang.org/rustup.sh | sudo sh -s -- --channel=nightly"
|
10
|
+
puts
|
11
|
+
END { puts "Exiting..."}
|
12
|
+
end
|
13
|
+
|
14
|
+
Dir.chdir('../../') do
|
15
|
+
system("rake build_src")
|
16
|
+
system("rake clean_src")
|
17
|
+
end
|
18
|
+
|
19
|
+
create_makefile('faster_path/dummy')
|
data/faster_path.gemspec
CHANGED
@@ -16,10 +16,11 @@ Gem::Specification.new do |spec|
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
17
|
spec.bindir = "exe"
|
18
18
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
|
+
spec.extensions << "ext/faster_path/extconf.rb"
|
19
20
|
spec.require_paths = ["lib"]
|
20
21
|
|
21
22
|
spec.add_dependency "ffi"
|
22
23
|
spec.add_development_dependency "bundler", "~> 1.12"
|
23
|
-
spec.add_development_dependency "rake", "~>
|
24
|
+
spec.add_development_dependency "rake", "~> 11.1"
|
24
25
|
spec.add_development_dependency "minitest", "~> 5.8"
|
25
26
|
end
|
data/lib/faster_path.rb
CHANGED
@@ -1,32 +1,39 @@
|
|
1
1
|
require "faster_path/version"
|
2
|
+
require 'pathname'
|
2
3
|
require "ffi"
|
3
4
|
|
4
5
|
module FasterPath
|
6
|
+
# Spec to Pathname#absolute?
|
5
7
|
def self.absolute?(pth)
|
6
|
-
Rust.
|
8
|
+
Rust.is_absolute(pth)
|
7
9
|
end
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
# Spec to Pathname#chop_basename
|
12
|
+
# WARNING! Pathname#chop_basename in STDLIB doesn't handle blank strings correctly!
|
13
|
+
# This implementation correctly handles blank strings just as Pathname had intended
|
14
|
+
# to handle non-path strings.
|
15
|
+
def self.chop_basename(pth)
|
16
|
+
d,b = [Rust.dirname(pth), Rust.basename(pth)]
|
17
|
+
if blank?(d) && blank?(b)
|
18
|
+
nil
|
19
|
+
else
|
20
|
+
[d,b]
|
14
21
|
end
|
15
22
|
end
|
16
23
|
|
17
|
-
|
18
|
-
|
19
|
-
def absolute?
|
20
|
-
FasterPath.absolute?(@path)
|
21
|
-
end
|
22
|
-
end
|
24
|
+
def self.blank?(str)
|
25
|
+
Rust.is_blank(str)
|
23
26
|
end
|
24
27
|
|
25
28
|
private
|
26
29
|
module Rust
|
27
30
|
extend FFI::Library
|
28
31
|
ffi_lib 'target/release/libfaster_path.so'
|
29
|
-
attach_function :
|
32
|
+
attach_function :is_absolute, [ :string ], :bool
|
33
|
+
attach_function :is_blank, [ :string ], :bool
|
34
|
+
attach_function :basename, [ :string ], :string
|
35
|
+
attach_function :dirname, [ :string ], :string
|
36
|
+
#attach_function :chop_basename, [ :string ], [:string]
|
30
37
|
end
|
31
38
|
private_constant :Rust
|
32
39
|
end
|
data/lib/faster_path/version.rb
CHANGED
data/src/lib.rs
CHANGED
@@ -5,13 +5,15 @@
|
|
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
7
|
extern crate libc;
|
8
|
+
//extern crate regex;
|
8
9
|
|
10
|
+
use std::path::{Path,MAIN_SEPARATOR};
|
9
11
|
use libc::c_char;
|
10
|
-
use std::ffi::CStr;
|
12
|
+
use std::ffi::{CStr,CString,OsStr};
|
11
13
|
use std::str;
|
12
14
|
|
13
15
|
#[no_mangle]
|
14
|
-
pub extern fn
|
16
|
+
pub extern fn is_absolute(string: *const c_char) -> bool {
|
15
17
|
let c_str = unsafe {
|
16
18
|
assert!(!string.is_null());
|
17
19
|
|
@@ -20,9 +22,92 @@ pub extern fn absolute(string: *const c_char) -> bool {
|
|
20
22
|
|
21
23
|
let r_str = str::from_utf8(c_str.to_bytes()).unwrap();
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
-
|
25
|
+
r_str.chars().next().unwrap() == MAIN_SEPARATOR
|
26
|
+
}
|
27
|
+
|
28
|
+
#[no_mangle]
|
29
|
+
pub extern fn is_blank(string: *const c_char) -> bool {
|
30
|
+
let c_str = unsafe {
|
31
|
+
assert!(!string.is_null());
|
32
|
+
|
33
|
+
CStr::from_ptr(string)
|
34
|
+
};
|
35
|
+
|
36
|
+
str::from_utf8(c_str.to_bytes()).unwrap().trim().is_empty()
|
37
|
+
}
|
38
|
+
|
39
|
+
#[no_mangle]
|
40
|
+
pub extern fn basename(string: *const c_char) -> *const c_char {
|
41
|
+
let c_str = unsafe {
|
42
|
+
assert!(!string.is_null());
|
43
|
+
|
44
|
+
CStr::from_ptr(string)
|
45
|
+
};
|
46
|
+
|
47
|
+
let r_str = str::from_utf8(c_str.to_bytes()).unwrap();
|
48
|
+
|
49
|
+
let part = Path::new(r_str).file_name().unwrap_or(OsStr::new("")).to_str();
|
50
|
+
|
51
|
+
let output = CString::new(format!("{}", part.unwrap())).unwrap();
|
52
|
+
output.into_raw()
|
53
|
+
}
|
54
|
+
|
55
|
+
#[no_mangle]
|
56
|
+
pub extern fn dirname(string: *const c_char) -> *const c_char {
|
57
|
+
let c_str = unsafe {
|
58
|
+
assert!(!string.is_null());
|
59
|
+
|
60
|
+
CStr::from_ptr(string)
|
61
|
+
};
|
62
|
+
|
63
|
+
let r_str = str::from_utf8(c_str.to_bytes()).unwrap();
|
64
|
+
|
65
|
+
if r_str.is_empty() {
|
66
|
+
return string
|
26
67
|
}
|
68
|
+
|
69
|
+
let path = Path::new(r_str).parent().unwrap_or(Path::new(""));
|
70
|
+
|
71
|
+
let out_str = if !path.to_str().unwrap().is_empty() {
|
72
|
+
format!("{}{}", path.to_str().unwrap(), MAIN_SEPARATOR)
|
73
|
+
} else {
|
74
|
+
format!("{}", path.to_str().unwrap())
|
75
|
+
};
|
76
|
+
|
77
|
+
let output = CString::new(out_str).unwrap();
|
78
|
+
output.into_raw()
|
27
79
|
}
|
28
80
|
|
81
|
+
//#[no_mangle]
|
82
|
+
//pub extern fn chop_basename(string: *const c_char) -> Vec<*const c_char> {
|
83
|
+
// let c_str = unsafe {
|
84
|
+
// assert!(!string.is_null());
|
85
|
+
//
|
86
|
+
// CStr::from_ptr(string)
|
87
|
+
// };
|
88
|
+
//
|
89
|
+
// let r_str = str::from_utf8(c_str.to_bytes()).unwrap();
|
90
|
+
// let mut parts: Vec<*const libc::c_char> = vec![];
|
91
|
+
//
|
92
|
+
// {
|
93
|
+
// use regex::Regex;
|
94
|
+
// let re = Regex::new(format!(r"\A{}?\z", MAIN_SEPARATOR).as_str()).unwrap();
|
95
|
+
// if re.is_match(r_str){
|
96
|
+
// return parts;
|
97
|
+
// }
|
98
|
+
// }
|
99
|
+
//
|
100
|
+
// let mut pieces = r_str.rsplitn(1, MAIN_SEPARATOR);
|
101
|
+
// loop {
|
102
|
+
// match pieces.next() {
|
103
|
+
// Some(val) => { parts.push(CString::new(val.to_string()).unwrap().into_raw()) },
|
104
|
+
// None => { break },
|
105
|
+
// }
|
106
|
+
// }
|
107
|
+
// parts
|
108
|
+
//}
|
109
|
+
|
110
|
+
//#[test]
|
111
|
+
//fn it_chops_basename() {
|
112
|
+
// let result = chop_basename(CString::new("/hello/world.txt").unwrap().as_ptr());
|
113
|
+
//}
|
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.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel P. Clark
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-06-
|
11
|
+
date: 2016-06-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '11.1'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '11.1'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: minitest
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -70,7 +70,8 @@ description: FasterPath is a reimplementation of Pathname for better performance
|
|
70
70
|
email:
|
71
71
|
- 6ftdan@gmail.com
|
72
72
|
executables: []
|
73
|
-
extensions:
|
73
|
+
extensions:
|
74
|
+
- ext/faster_path/extconf.rb
|
74
75
|
extra_rdoc_files: []
|
75
76
|
files:
|
76
77
|
- ".gitignore"
|
@@ -78,16 +79,18 @@ files:
|
|
78
79
|
- Cargo.lock
|
79
80
|
- Cargo.toml
|
80
81
|
- Gemfile
|
81
|
-
- LICENSE.txt
|
82
|
+
- MIT-LICENSE.txt
|
82
83
|
- README.md
|
83
84
|
- Rakefile
|
84
85
|
- bin/console
|
85
86
|
- bin/setup
|
87
|
+
- ext/faster_path/extconf.rb
|
86
88
|
- faster_path.gemspec
|
87
89
|
- lib/faster_path.rb
|
90
|
+
- lib/faster_path/optional/monkeypatches.rb
|
91
|
+
- lib/faster_path/optional/refinements.rb
|
88
92
|
- lib/faster_path/version.rb
|
89
93
|
- src/lib.rs
|
90
|
-
- target/release/libfaster_path.so
|
91
94
|
homepage: https://github.com/danielpclark/faster_path
|
92
95
|
licenses:
|
93
96
|
- MIT OR Apache-2.0
|
Binary file
|