faster_path 0.2.4 → 0.2.5
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 +10 -9
- data/Cargo.toml +1 -0
- data/MIT-LICENSE.txt +1 -1
- data/README.md +15 -12
- data/lib/faster_path/optional/monkeypatches.rb +14 -0
- data/lib/faster_path/optional/refinements.rb +14 -0
- data/lib/faster_path/version.rb +1 -1
- data/lib/faster_path.rb +0 -1
- data/src/cleanpath_conservative.rs +110 -0
- data/src/helpers.rs +62 -12
- data/src/lib.rs +14 -6
- data/src/pathname.rs +110 -18
- data/src/pathname_sys.rs +36 -0
- metadata +4 -3
- data/lib/faster_path/asset_resolution.rb +0 -60
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1f459170e11712e3d18dc8937e433ea724dd7dd016b3e5cbf5a7e6da722b4dfe
|
|
4
|
+
data.tar.gz: a3c27c26aee46ca61237635c42add31fb307a787706af74b87eb62eb74c17dda
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c7d6b3a879a2acbfe48eeb96acd9bc53674c6525e0637820c40de7d988a45647a6310dfbbaab96b9d46856a9722ed595d9b957bc8fbc1c04b1a690e2e937f73d
|
|
7
|
+
data.tar.gz: e8c3bf596e1a508647a1f21ba3323796e9fa7f29a8145275b7dc8a91aa8c852bf7438216db1f36c3d4c602b36b79a7b1c9e9f01e3e2126db4427f47dd9477809
|
data/Cargo.lock
CHANGED
|
@@ -10,12 +10,13 @@ dependencies = [
|
|
|
10
10
|
"array_tool 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
11
11
|
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
12
12
|
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
13
|
+
"ruby-sys 0.3.0 (git+https://github.com/danielpclark/ruby-sys?branch=playground)",
|
|
13
14
|
"ruru 0.9.3 (git+https://github.com/danielpclark/ruru?branch=playground)",
|
|
14
15
|
]
|
|
15
16
|
|
|
16
17
|
[[package]]
|
|
17
18
|
name = "lazy_static"
|
|
18
|
-
version = "0.2.
|
|
19
|
+
version = "0.2.11"
|
|
19
20
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
20
21
|
|
|
21
22
|
[[package]]
|
|
@@ -25,7 +26,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
|
25
26
|
|
|
26
27
|
[[package]]
|
|
27
28
|
name = "libc"
|
|
28
|
-
version = "0.2.
|
|
29
|
+
version = "0.2.36"
|
|
29
30
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
30
31
|
|
|
31
32
|
[[package]]
|
|
@@ -33,31 +34,31 @@ name = "memchr"
|
|
|
33
34
|
version = "2.0.1"
|
|
34
35
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
35
36
|
dependencies = [
|
|
36
|
-
"libc 0.2.
|
|
37
|
+
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
37
38
|
]
|
|
38
39
|
|
|
39
40
|
[[package]]
|
|
40
41
|
name = "ruby-sys"
|
|
41
42
|
version = "0.3.0"
|
|
42
|
-
source = "git+https://github.com/danielpclark/ruby-sys?branch=playground#
|
|
43
|
+
source = "git+https://github.com/danielpclark/ruby-sys?branch=playground#a71d5783e92d9dfd3602f81adc96f640ff377f21"
|
|
43
44
|
dependencies = [
|
|
44
|
-
"libc 0.2.
|
|
45
|
+
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
45
46
|
]
|
|
46
47
|
|
|
47
48
|
[[package]]
|
|
48
49
|
name = "ruru"
|
|
49
50
|
version = "0.9.3"
|
|
50
|
-
source = "git+https://github.com/danielpclark/ruru?branch=playground#
|
|
51
|
+
source = "git+https://github.com/danielpclark/ruru?branch=playground#e35b9dd88d86f3b8bb9cede7a74b04781bd4da89"
|
|
51
52
|
dependencies = [
|
|
52
|
-
"lazy_static 0.2.
|
|
53
|
+
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
53
54
|
"ruby-sys 0.3.0 (git+https://github.com/danielpclark/ruby-sys?branch=playground)",
|
|
54
55
|
]
|
|
55
56
|
|
|
56
57
|
[metadata]
|
|
57
58
|
"checksum array_tool 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a07ccb27c611e5cda99e498e99ba71b3ecdb7db5df02096cef42a3df5b84542"
|
|
58
|
-
"checksum lazy_static 0.2.
|
|
59
|
+
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
|
|
59
60
|
"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
|
|
60
|
-
"checksum libc 0.2.
|
|
61
|
+
"checksum libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "1e5d97d6708edaa407429faa671b942dc0f2727222fb6b6539bf1db936e4b121"
|
|
61
62
|
"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
|
|
62
63
|
"checksum ruby-sys 0.3.0 (git+https://github.com/danielpclark/ruby-sys?branch=playground)" = "<none>"
|
|
63
64
|
"checksum ruru 0.9.3 (git+https://github.com/danielpclark/ruru?branch=playground)" = "<none>"
|
data/Cargo.toml
CHANGED
|
@@ -13,6 +13,7 @@ name = "faster_path"
|
|
|
13
13
|
crate-type = ["dylib"]
|
|
14
14
|
|
|
15
15
|
[dependencies]
|
|
16
|
+
ruby-sys = { git = "https://github.com/danielpclark/ruby-sys", branch = "playground" }
|
|
16
17
|
ruru = { git = "https://github.com/danielpclark/ruru", branch = "playground" }
|
|
17
18
|
array_tool = "0.4.1"
|
|
18
19
|
lazy_static = "1.0"
|
data/MIT-LICENSE.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
The MIT License (MIT)
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2016-
|
|
3
|
+
Copyright (c) 2016-2018 Daniel P. Clark & FasterPath Contributors
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://travis-ci.org/danielpclark/faster_path)
|
|
4
4
|
[](https://ci.appveyor.com/project/danielpclark/faster-path/branch/master)
|
|
5
5
|
[](https://github.com/danielpclark/faster_path/tags)
|
|
6
|
-
[](https://github.com/danielpclark/faster_path/pulse)
|
|
7
7
|
[](https://github.com/danielpclark/faster_path/releases)
|
|
8
8
|
[](https://coveralls.io/github/danielpclark/faster_path)
|
|
9
9
|
[](http://inch-ci.org/github/danielpclark/faster_path)
|
|
@@ -136,18 +136,21 @@ improvement result for the `chop_basename` method.
|
|
|
136
136
|
|
|
137
137
|
Current methods implemented:
|
|
138
138
|
|
|
139
|
-
|FasterPath Rust Implementation|Ruby 2.
|
|
139
|
+
|FasterPath Rust Implementation|Ruby 2.5.0 Implementation|Time Shaved Off|
|
|
140
140
|
|---|---|:---:|
|
|
141
|
-
| `FasterPath.absolute?` | `Pathname#absolute?` |
|
|
142
|
-
| `FasterPath.add_trailing_separator` | `Pathname#add_trailing_separator` | 31.
|
|
143
|
-
| `FasterPath.children` | `Pathname#children` |
|
|
144
|
-
| `FasterPath.chop_basename` | `Pathname#chop_basename` |
|
|
145
|
-
| `FasterPath.cleanpath_aggressive` | `Pathname#cleanpath_aggressive` |
|
|
146
|
-
| `FasterPath.
|
|
147
|
-
| `FasterPath.
|
|
148
|
-
| `FasterPath.
|
|
149
|
-
| `FasterPath.
|
|
150
|
-
| `FasterPath.
|
|
141
|
+
| `FasterPath.absolute?` | `Pathname#absolute?` | 91.9% |
|
|
142
|
+
| `FasterPath.add_trailing_separator` | `Pathname#add_trailing_separator` | 31.2% |
|
|
143
|
+
| `FasterPath.children` | `Pathname#children` | 13.2% |
|
|
144
|
+
| `FasterPath.chop_basename` | `Pathname#chop_basename` | 54.5% |
|
|
145
|
+
| `FasterPath.cleanpath_aggressive` | `Pathname#cleanpath_aggressive` | 73.8% |
|
|
146
|
+
| `FasterPath.cleanpath_conservative` | `Pathname#cleanpath_conservative` | 70.7% |
|
|
147
|
+
| `FasterPath.del_trailing_separator` | `Pathname#del_trailing_separator` | 80.6% |
|
|
148
|
+
| `FasterPath.directory?` | `Pathname#directory?` | 11.3% |
|
|
149
|
+
| `FasterPath.entries` | `Pathname#entries` | 8.4% |
|
|
150
|
+
| `FasterPath.has_trailing_separator?` | `Pathname#has_trailing_separator` | 67.6% |
|
|
151
|
+
| `FasterPath.plus` | `Pathname#join` | 66.4% |
|
|
152
|
+
| `FasterPath.plus` | `Pathname#plus` | 81.4% |
|
|
153
|
+
| `FasterPath.relative?` | `Pathname#relative?` | 84.1% |
|
|
151
154
|
|
|
152
155
|
You may choose to use the methods directly, or scope change to rewrite behavior on the
|
|
153
156
|
standard library with the included refinements, or even call a method to monkeypatch
|
|
@@ -52,6 +52,16 @@ module FasterPath
|
|
|
52
52
|
end
|
|
53
53
|
private :cleanpath_aggressive
|
|
54
54
|
|
|
55
|
+
def cleanpath_conservative
|
|
56
|
+
Pathname.new(FasterPath.cleanpath_conservative(@path))
|
|
57
|
+
end
|
|
58
|
+
private :cleanpath_conservative
|
|
59
|
+
|
|
60
|
+
def del_trailing_separator(pth)
|
|
61
|
+
FasterPath.del_trailing_separator(pth)
|
|
62
|
+
end
|
|
63
|
+
private :del_trailing_separator
|
|
64
|
+
|
|
55
65
|
def directory?
|
|
56
66
|
FasterPath.directory?(@path)
|
|
57
67
|
end
|
|
@@ -65,6 +75,10 @@ module FasterPath
|
|
|
65
75
|
end
|
|
66
76
|
private :has_trailing_separator?
|
|
67
77
|
|
|
78
|
+
def join(*args)
|
|
79
|
+
FasterPath.join(self, *args)
|
|
80
|
+
end
|
|
81
|
+
|
|
68
82
|
def plus(pth, pth2)
|
|
69
83
|
FasterPath.plus(pth, pth2)
|
|
70
84
|
end
|
|
@@ -48,6 +48,16 @@ module FasterPath
|
|
|
48
48
|
end
|
|
49
49
|
private :cleanpath_aggressive
|
|
50
50
|
|
|
51
|
+
def cleanpath_conservative
|
|
52
|
+
Pathname.new(FasterPath.cleanpath_conservative(@path))
|
|
53
|
+
end
|
|
54
|
+
private :cleanpath_conservative
|
|
55
|
+
|
|
56
|
+
def del_trailing_separator(pth)
|
|
57
|
+
FasterPath.del_trailing_separator(pth)
|
|
58
|
+
end
|
|
59
|
+
private :del_trailing_separator
|
|
60
|
+
|
|
51
61
|
def directory?
|
|
52
62
|
FasterPath.directory?(@path)
|
|
53
63
|
end
|
|
@@ -60,6 +70,10 @@ module FasterPath
|
|
|
60
70
|
FasterPath.has_trailing_separator?(pth)
|
|
61
71
|
end
|
|
62
72
|
|
|
73
|
+
def join(*args)
|
|
74
|
+
FasterPath.join(self, *args)
|
|
75
|
+
end
|
|
76
|
+
|
|
63
77
|
def plus(pth, pth2)
|
|
64
78
|
FasterPath.plus(pth, pth2)
|
|
65
79
|
end
|
data/lib/faster_path/version.rb
CHANGED
data/lib/faster_path.rb
CHANGED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
use prepend_prefix::prepend_prefix;
|
|
2
|
+
use basename::basename;
|
|
3
|
+
use dirname::dirname;
|
|
4
|
+
use chop_basename::chop_basename;
|
|
5
|
+
extern crate array_tool;
|
|
6
|
+
use self::array_tool::vec::Shift;
|
|
7
|
+
use std::path::MAIN_SEPARATOR;
|
|
8
|
+
|
|
9
|
+
pub fn cleanpath_conservative(path: &str) -> String {
|
|
10
|
+
let sep = MAIN_SEPARATOR.to_string();
|
|
11
|
+
let mut names: Vec<String> = vec![];
|
|
12
|
+
let mut pre = path.to_string();
|
|
13
|
+
loop {
|
|
14
|
+
match chop_basename(&pre) {
|
|
15
|
+
Some((ref p, ref base)) => {
|
|
16
|
+
pre = p.to_string();
|
|
17
|
+
match base.as_ref() {
|
|
18
|
+
"." => {},
|
|
19
|
+
_ => names.unshift(base.to_string()),
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
None => break,
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// // Windows Feature
|
|
26
|
+
//
|
|
27
|
+
// ```ruby
|
|
28
|
+
// pre.tr!(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR
|
|
29
|
+
// ```
|
|
30
|
+
//
|
|
31
|
+
if basename(&pre, "").contains(&sep) {
|
|
32
|
+
loop {
|
|
33
|
+
if names.first() == Some(&"..".to_string()) {
|
|
34
|
+
let _ = names.shift();
|
|
35
|
+
} else {
|
|
36
|
+
break
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if names.is_empty() {
|
|
42
|
+
return dirname(&pre).to_string();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if names.last() != Some(&"..".to_string()) && basename(&path, "") == &".".to_string() {
|
|
46
|
+
names.push(".".to_string());
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let result = prepend_prefix(&pre, &names.join(&sep)[..]);
|
|
50
|
+
let last = names.last();
|
|
51
|
+
|
|
52
|
+
if !(last == Some(&".".to_string()) || last == Some(&"..".to_string())) &&
|
|
53
|
+
chop_basename(path).map(|(a, b)| a.len() + b.len()).unwrap() < path.len() {
|
|
54
|
+
format!("{}{}", last.unwrap(), MAIN_SEPARATOR)
|
|
55
|
+
} else {
|
|
56
|
+
result
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
#[test]
|
|
61
|
+
fn it_conservatively_cleans_the_path() {
|
|
62
|
+
assert_eq!(cleanpath_conservative("/"), "/");
|
|
63
|
+
assert_eq!(cleanpath_conservative(""), ".");
|
|
64
|
+
assert_eq!(cleanpath_conservative("."), ".");
|
|
65
|
+
assert_eq!(cleanpath_conservative(".."), "..");
|
|
66
|
+
assert_eq!(cleanpath_conservative("a"), "a");
|
|
67
|
+
assert_eq!(cleanpath_conservative("/."), "/");
|
|
68
|
+
assert_eq!(cleanpath_conservative("/.."), "/");
|
|
69
|
+
assert_eq!(cleanpath_conservative("/a"), "/a");
|
|
70
|
+
assert_eq!(cleanpath_conservative("./"), ".");
|
|
71
|
+
assert_eq!(cleanpath_conservative("../"), "..");
|
|
72
|
+
assert_eq!(cleanpath_conservative("a/"), "a/");
|
|
73
|
+
assert_eq!(cleanpath_conservative("a//b"), "a/b");
|
|
74
|
+
assert_eq!(cleanpath_conservative("a/."), "a/.");
|
|
75
|
+
assert_eq!(cleanpath_conservative("a/./"), "a/.");
|
|
76
|
+
assert_eq!(cleanpath_conservative("a/../"), "a/..");
|
|
77
|
+
assert_eq!(cleanpath_conservative("/a/."), "/a/.");
|
|
78
|
+
assert_eq!(cleanpath_conservative("./.."), "..");
|
|
79
|
+
assert_eq!(cleanpath_conservative("../."), "..");
|
|
80
|
+
assert_eq!(cleanpath_conservative("./../"), "..");
|
|
81
|
+
assert_eq!(cleanpath_conservative(".././"), "..");
|
|
82
|
+
assert_eq!(cleanpath_conservative("/./.."), "/");
|
|
83
|
+
assert_eq!(cleanpath_conservative("/../."), "/");
|
|
84
|
+
assert_eq!(cleanpath_conservative("/./../"), "/");
|
|
85
|
+
assert_eq!(cleanpath_conservative("/.././"), "/");
|
|
86
|
+
assert_eq!(cleanpath_conservative("a/b/c"), "a/b/c");
|
|
87
|
+
assert_eq!(cleanpath_conservative("./b/c"), "b/c");
|
|
88
|
+
assert_eq!(cleanpath_conservative("a/./c"), "a/c");
|
|
89
|
+
assert_eq!(cleanpath_conservative("a/b/."), "a/b/.");
|
|
90
|
+
assert_eq!(cleanpath_conservative("a/../."), "a/..");
|
|
91
|
+
assert_eq!(cleanpath_conservative("/../.././../a"), "/a");
|
|
92
|
+
assert_eq!(cleanpath_conservative("a/b/../../../../c/../d"), "a/b/../../../../c/../d");
|
|
93
|
+
;
|
|
94
|
+
// Future Windows Support
|
|
95
|
+
//
|
|
96
|
+
// DOSISH = File::ALT_SEPARATOR != nil
|
|
97
|
+
// DOSISH_DRIVE_LETTER = File.dirname("A:") == "A:."
|
|
98
|
+
// DOSISH_UNC = File.dirname("//") == "//"
|
|
99
|
+
//
|
|
100
|
+
//
|
|
101
|
+
// if DOSISH
|
|
102
|
+
// assert_eq!(cleanpath_conservative, 'c:/foo/bar', 'c:\\foo\\bar')
|
|
103
|
+
// end
|
|
104
|
+
//
|
|
105
|
+
// if DOSISH_UNC
|
|
106
|
+
// assert_eq!(cleanpath_conservative, '//', '//')
|
|
107
|
+
// else
|
|
108
|
+
// assert_eq!(cleanpath_conservative, '/', '//')
|
|
109
|
+
// end
|
|
110
|
+
}
|
data/src/helpers.rs
CHANGED
|
@@ -1,13 +1,63 @@
|
|
|
1
|
-
use ruru::{RString, Object, Class};
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
)
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
)
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
use ruru::{RString, Object, Class, AnyObject};
|
|
2
|
+
use pathname::Pathname;
|
|
3
|
+
|
|
4
|
+
pub fn anyobject_to_string(item: AnyObject) -> Result<String, RubyDebugInfo> {
|
|
5
|
+
let result = &item;
|
|
6
|
+
if Class::from_existing("String").case_equals(result) {
|
|
7
|
+
return Ok(RString::from(result.value()).to_string())
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if Class::from_existing("Pathname").case_equals(result) {
|
|
11
|
+
return Ok(result.instance_variable_get("@path").
|
|
12
|
+
try_convert_to::<RString>().
|
|
13
|
+
unwrap_or(RString::new("")).
|
|
14
|
+
to_string())
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if result.respond_to("to_path") {
|
|
18
|
+
return Ok(Class::from(result.send("to_path", None).value()).
|
|
19
|
+
instance_variable_get("@path").
|
|
20
|
+
try_convert_to::<RString>().
|
|
21
|
+
unwrap_or(RString::new("")).
|
|
22
|
+
to_string())
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
Ok(RString::from(result.send("to_s", None).value()).to_string())
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
#[allow(dead_code)]
|
|
29
|
+
pub fn into_pathname(itself: AnyObject) -> Result<AnyObject, RubyDebugInfo> {
|
|
30
|
+
if Class::from_existing("String").case_equals(&itself) {
|
|
31
|
+
Ok(Pathname::new(
|
|
32
|
+
&RString::from(itself.value()).to_string()
|
|
33
|
+
).to_any_object())
|
|
34
|
+
} else if Class::from_existing("Pathname").case_equals(&itself) {
|
|
35
|
+
Ok(itself)
|
|
36
|
+
} else {
|
|
37
|
+
Err(RubyDebugInfo::from(itself))
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
#[derive(Debug)]
|
|
42
|
+
pub struct RubyDebugInfo {
|
|
43
|
+
object_id: String,
|
|
44
|
+
class: String,
|
|
45
|
+
inspect: String,
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
impl From<AnyObject> for RubyDebugInfo {
|
|
49
|
+
fn from(ao: AnyObject) -> Self {
|
|
50
|
+
let object_id = ao.send("object_id", None).send("to_s", None).
|
|
51
|
+
try_convert_to::<RString>().unwrap_or(RString::new("Failed to get object_id!")).to_string();
|
|
52
|
+
let class = ao.send("class", None).send("to_s", None).
|
|
53
|
+
try_convert_to::<RString>().unwrap_or(RString::new("Failed to get class!")).to_string();
|
|
54
|
+
let inspect = ao.send("inspect", None).
|
|
55
|
+
try_convert_to::<RString>().unwrap_or(RString::new("Failed to get inspect!")).to_string();
|
|
56
|
+
|
|
57
|
+
RubyDebugInfo {
|
|
58
|
+
object_id: object_id,
|
|
59
|
+
class: class,
|
|
60
|
+
inspect: inspect,
|
|
61
|
+
}
|
|
62
|
+
}
|
|
13
63
|
}
|
data/src/lib.rs
CHANGED
|
@@ -17,8 +17,10 @@ mod pathname;
|
|
|
17
17
|
mod basename;
|
|
18
18
|
mod chop_basename;
|
|
19
19
|
mod cleanpath_aggressive;
|
|
20
|
+
mod cleanpath_conservative;
|
|
20
21
|
mod dirname;
|
|
21
22
|
mod extname;
|
|
23
|
+
mod pathname_sys;
|
|
22
24
|
mod plus;
|
|
23
25
|
mod prepend_prefix;
|
|
24
26
|
pub mod rust_arch_bits;
|
|
@@ -26,8 +28,8 @@ mod path_parsing;
|
|
|
26
28
|
|
|
27
29
|
use ruru::{Module, Object, RString, Boolean, Array, AnyObject};
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
use pathname_sys::*;
|
|
32
|
+
|
|
31
33
|
methods!(
|
|
32
34
|
FasterPath,
|
|
33
35
|
_itself,
|
|
@@ -65,9 +67,13 @@ methods!(
|
|
|
65
67
|
pathname::pn_cleanpath_aggressive(pth)
|
|
66
68
|
}
|
|
67
69
|
|
|
68
|
-
|
|
70
|
+
fn pub_cleanpath_conservative(pth: RString) -> RString {
|
|
71
|
+
pathname::pn_cleanpath_conservative(pth)
|
|
72
|
+
}
|
|
69
73
|
|
|
70
|
-
|
|
74
|
+
fn pub_del_trailing_separator(pth: RString) -> RString {
|
|
75
|
+
pathname::pn_del_trailing_separator(pth)
|
|
76
|
+
}
|
|
71
77
|
|
|
72
78
|
// fn r_descend(){}
|
|
73
79
|
|
|
@@ -107,8 +113,6 @@ methods!(
|
|
|
107
113
|
pathname::pn_has_trailing_separator(pth)
|
|
108
114
|
}
|
|
109
115
|
|
|
110
|
-
// fn r_join(args: Array){}
|
|
111
|
-
|
|
112
116
|
// fn pub_mkpath(pth: RString) -> NilClass {
|
|
113
117
|
// pathname::pn_mkpath(pth)
|
|
114
118
|
// }
|
|
@@ -149,11 +153,15 @@ pub extern "C" fn Init_faster_pathname(){
|
|
|
149
153
|
Module::from_existing("FasterPath").define(|itself| {
|
|
150
154
|
itself.def_self("absolute?", pub_is_absolute);
|
|
151
155
|
itself.def_self("add_trailing_separator", pub_add_trailing_separator);
|
|
156
|
+
itself.def_self("del_trailing_separator", pub_del_trailing_separator);
|
|
152
157
|
itself.def_self("cleanpath_aggressive", pub_cleanpath_aggressive);
|
|
158
|
+
itself.def_self("cleanpath_conservative", pub_cleanpath_conservative);
|
|
153
159
|
itself.def_self("directory?", pub_is_directory);
|
|
154
160
|
itself.def_self("dirname", pub_dirname);
|
|
155
161
|
itself.def_self("extname", pub_extname);
|
|
156
162
|
itself.def_self("has_trailing_separator?", pub_has_trailing_separator);
|
|
163
|
+
//itself.def_self("join", pub_join);
|
|
164
|
+
pathname_sys::define_singleton_method(itself.value(), "join", pub_join);
|
|
157
165
|
itself.def_self("plus", pub_plus);
|
|
158
166
|
itself.def_self("relative?", pub_is_relative);
|
|
159
167
|
itself.define_nested_class("Public", None);
|
data/src/pathname.rs
CHANGED
|
@@ -1,19 +1,63 @@
|
|
|
1
|
-
use helpers
|
|
1
|
+
use helpers::*;
|
|
2
2
|
use basename;
|
|
3
3
|
use chop_basename;
|
|
4
4
|
use cleanpath_aggressive;
|
|
5
|
+
use cleanpath_conservative;
|
|
5
6
|
use dirname;
|
|
6
7
|
use extname;
|
|
7
8
|
use plus;
|
|
8
9
|
|
|
9
10
|
use ruru;
|
|
10
|
-
use ruru::{RString, Boolean, Array, AnyObject, NilClass, Object};
|
|
11
|
+
use ruru::{RString, Boolean, Array, AnyObject, NilClass, Object, Class, VerifiedObject};
|
|
12
|
+
use ruru::types::{Value, ValueType};
|
|
11
13
|
use std::path::{MAIN_SEPARATOR,Path};
|
|
12
14
|
use std::fs;
|
|
13
15
|
|
|
16
|
+
type MaybeArray = Result<ruru::Array, ruru::result::Error>;
|
|
14
17
|
type MaybeString = Result<ruru::RString, ruru::result::Error>;
|
|
15
18
|
type MaybeBoolean = Result<ruru::Boolean, ruru::result::Error>;
|
|
16
19
|
|
|
20
|
+
pub struct Pathname {
|
|
21
|
+
value: Value
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
impl Pathname {
|
|
25
|
+
pub fn new(path: &str) -> Pathname {
|
|
26
|
+
let mut instance = Class::from_existing("Pathname").allocate();
|
|
27
|
+
instance.instance_variable_set("@path", RString::new(path).to_any_object());
|
|
28
|
+
|
|
29
|
+
Pathname { value: instance.value() }
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
pub fn to_any_object(&self) -> AnyObject {
|
|
33
|
+
AnyObject::from(self.value())
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
impl From<Value> for Pathname {
|
|
38
|
+
fn from(value: Value) -> Self {
|
|
39
|
+
Pathname { value: value }
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
impl Object for Pathname {
|
|
44
|
+
#[inline]
|
|
45
|
+
fn value(&self) -> Value {
|
|
46
|
+
self.value
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
impl VerifiedObject for Pathname {
|
|
51
|
+
fn is_correct_type<T: Object>(object: &T) -> bool {
|
|
52
|
+
object.value().ty() == ValueType::Class &&
|
|
53
|
+
Class::from_existing("Pathname").case_equals(object)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
fn error_message() -> &'static str {
|
|
57
|
+
"Error converting to Pathname"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
17
61
|
pub fn pn_add_trailing_separator(pth: MaybeString) -> RString {
|
|
18
62
|
let p = pth.ok().unwrap();
|
|
19
63
|
let x = format!("{}{}", p.to_str(), "a");
|
|
@@ -42,7 +86,6 @@ pub fn pn_basename(pth: MaybeString, ext: MaybeString) -> RString {
|
|
|
42
86
|
}
|
|
43
87
|
|
|
44
88
|
pub fn pn_children(pth: MaybeString, with_dir: MaybeBoolean) -> AnyObject {
|
|
45
|
-
let mut arr = Array::new();
|
|
46
89
|
let val = pth.ok().unwrap_or(RString::new("."));
|
|
47
90
|
let val = val.to_str();
|
|
48
91
|
|
|
@@ -52,6 +95,7 @@ pub fn pn_children(pth: MaybeString, with_dir: MaybeBoolean) -> AnyObject {
|
|
|
52
95
|
with_directory = false;
|
|
53
96
|
}
|
|
54
97
|
|
|
98
|
+
let mut arr = Array::new();
|
|
55
99
|
for entry in entries {
|
|
56
100
|
if with_directory {
|
|
57
101
|
match entry {
|
|
@@ -75,7 +119,6 @@ pub fn pn_children(pth: MaybeString, with_dir: MaybeBoolean) -> AnyObject {
|
|
|
75
119
|
}
|
|
76
120
|
|
|
77
121
|
pub fn pn_children_compat(pth: MaybeString, with_dir: MaybeBoolean) -> AnyObject {
|
|
78
|
-
let mut arr = Array::new();
|
|
79
122
|
let val = pth.ok().unwrap_or(RString::new("."));
|
|
80
123
|
let val = val.to_str();
|
|
81
124
|
|
|
@@ -85,14 +128,15 @@ pub fn pn_children_compat(pth: MaybeString, with_dir: MaybeBoolean) -> AnyObject
|
|
|
85
128
|
with_directory = false;
|
|
86
129
|
}
|
|
87
130
|
|
|
131
|
+
let mut arr = Array::new();
|
|
88
132
|
for entry in entries {
|
|
89
133
|
if with_directory {
|
|
90
134
|
if let Ok(v) = entry {
|
|
91
|
-
arr.push(
|
|
135
|
+
arr.push(Pathname::new(v.path().to_str().unwrap()));
|
|
92
136
|
};
|
|
93
137
|
} else {
|
|
94
138
|
if let Ok(v) = entry {
|
|
95
|
-
arr.push(
|
|
139
|
+
arr.push(Pathname::new(v.file_name().to_str().unwrap()));
|
|
96
140
|
};
|
|
97
141
|
}
|
|
98
142
|
}
|
|
@@ -128,9 +172,33 @@ pub fn pn_cleanpath_aggressive(pth: MaybeString) -> RString {
|
|
|
128
172
|
RString::new(&path)
|
|
129
173
|
}
|
|
130
174
|
|
|
131
|
-
|
|
175
|
+
pub fn pn_cleanpath_conservative(pth: MaybeString) -> RString {
|
|
176
|
+
let path = cleanpath_conservative::cleanpath_conservative(
|
|
177
|
+
pth.ok().unwrap_or(RString::new("")).to_str()
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
RString::new(&path)
|
|
181
|
+
}
|
|
132
182
|
|
|
133
|
-
|
|
183
|
+
pub fn pn_del_trailing_separator(pth: MaybeString) -> RString {
|
|
184
|
+
if let &Ok(ref path) = &pth {
|
|
185
|
+
let path = path.to_str();
|
|
186
|
+
|
|
187
|
+
if !path.is_empty() {
|
|
188
|
+
let path = path.trim_right_matches('/');
|
|
189
|
+
|
|
190
|
+
if path.is_empty() {
|
|
191
|
+
return RString::new("/");
|
|
192
|
+
} else {
|
|
193
|
+
return RString::new(path);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
} else {
|
|
197
|
+
return RString::new("");
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
pth.unwrap()
|
|
201
|
+
}
|
|
134
202
|
|
|
135
203
|
// pub fn pn_descend(){}
|
|
136
204
|
|
|
@@ -157,9 +225,9 @@ pub fn pn_dirname(pth: MaybeString) -> RString {
|
|
|
157
225
|
// }
|
|
158
226
|
|
|
159
227
|
pub fn pn_entries(pth: MaybeString) -> AnyObject {
|
|
160
|
-
let mut arr = Array::new();
|
|
161
|
-
|
|
162
228
|
if let Ok(files) = fs::read_dir(pth.ok().unwrap_or(RString::new("")).to_str()) {
|
|
229
|
+
let mut arr = Array::new();
|
|
230
|
+
|
|
163
231
|
arr.push(RString::new("."));
|
|
164
232
|
arr.push(RString::new(".."));
|
|
165
233
|
|
|
@@ -177,15 +245,15 @@ pub fn pn_entries(pth: MaybeString) -> AnyObject {
|
|
|
177
245
|
}
|
|
178
246
|
|
|
179
247
|
pub fn pn_entries_compat(pth: MaybeString) -> AnyObject {
|
|
180
|
-
let mut arr = Array::new();
|
|
181
|
-
|
|
182
248
|
if let Ok(files) = fs::read_dir(pth.ok().unwrap_or(RString::new("")).to_str()) {
|
|
183
|
-
arr
|
|
184
|
-
|
|
249
|
+
let mut arr = Array::new();
|
|
250
|
+
|
|
251
|
+
arr.push(Pathname::new("."));
|
|
252
|
+
arr.push(Pathname::new(".."));
|
|
185
253
|
|
|
186
254
|
for file in files {
|
|
187
255
|
let file_name_str = file.unwrap().file_name().into_string().unwrap();
|
|
188
|
-
arr.push(
|
|
256
|
+
arr.push(Pathname::new(&file_name_str));
|
|
189
257
|
}
|
|
190
258
|
|
|
191
259
|
arr.to_any_object()
|
|
@@ -202,7 +270,7 @@ pub fn pn_extname(pth: MaybeString) -> RString {
|
|
|
202
270
|
)
|
|
203
271
|
}
|
|
204
272
|
|
|
205
|
-
// pub fn pn_find(pth: MaybeString
|
|
273
|
+
// pub fn pn_find(pth: MaybeString, ignore_error: Boolean){}
|
|
206
274
|
|
|
207
275
|
pub fn pn_has_trailing_separator(pth: MaybeString) -> Boolean {
|
|
208
276
|
let v = pth.ok().unwrap_or(RString::new(""));
|
|
@@ -214,7 +282,32 @@ pub fn pn_has_trailing_separator(pth: MaybeString) -> Boolean {
|
|
|
214
282
|
}
|
|
215
283
|
}
|
|
216
284
|
|
|
217
|
-
|
|
285
|
+
pub fn pn_join(args: MaybeArray) -> AnyObject {
|
|
286
|
+
let mut args = args.unwrap();
|
|
287
|
+
let path_self = anyobject_to_string(args.shift()).unwrap();
|
|
288
|
+
let mut qty = args.length();
|
|
289
|
+
if qty <= 0 {
|
|
290
|
+
return Pathname::new(&path_self).to_any_object();
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
let mut result = String::new();
|
|
294
|
+
|
|
295
|
+
loop {
|
|
296
|
+
if qty == 0 { break; }
|
|
297
|
+
|
|
298
|
+
let item = args.pop();
|
|
299
|
+
result = plus::plus_paths(&anyobject_to_string(item).unwrap(), &result);
|
|
300
|
+
if result.chars().next() == Some(MAIN_SEPARATOR) {
|
|
301
|
+
return Pathname::new(&result).to_any_object()
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
qty -= 1;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
let result = plus::plus_paths(&path_self, &result);
|
|
308
|
+
|
|
309
|
+
Pathname::new(&result).to_any_object()
|
|
310
|
+
}
|
|
218
311
|
|
|
219
312
|
// pub fn pn_mkpath(pth: MaybeString) -> NilClass {
|
|
220
313
|
// NilClass::new()
|
|
@@ -224,7 +317,6 @@ pub fn pn_has_trailing_separator(pth: MaybeString) -> Boolean {
|
|
|
224
317
|
|
|
225
318
|
// pub fn pn_parent(pth: MaybeString){}
|
|
226
319
|
|
|
227
|
-
// also need impl +
|
|
228
320
|
pub fn pn_plus(pth1: MaybeString, pth2: MaybeString) -> RString {
|
|
229
321
|
RString::new(
|
|
230
322
|
&plus::plus_paths(
|
data/src/pathname_sys.rs
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
use ruru::{AnyObject, Array, Object};
|
|
2
|
+
use ruru::types::{Argc, Value, CallbackPtr};
|
|
3
|
+
use ruru::util::str_to_cstring;
|
|
4
|
+
extern crate ruby_sys;
|
|
5
|
+
use self::ruby_sys::{class, util};
|
|
6
|
+
use ::pathname;
|
|
7
|
+
|
|
8
|
+
pub type ValueCallback<I, O> = extern "C" fn(Argc, *const Value, I) -> O;
|
|
9
|
+
|
|
10
|
+
pub fn define_singleton_method<I: Object, O: Object>(
|
|
11
|
+
klass: Value,
|
|
12
|
+
name: &str,
|
|
13
|
+
callback: ValueCallback<I, O>,
|
|
14
|
+
) {
|
|
15
|
+
let name = str_to_cstring(name);
|
|
16
|
+
|
|
17
|
+
unsafe {
|
|
18
|
+
class::rb_define_singleton_method(klass, name.as_ptr(), callback as CallbackPtr, -1);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// ruru doesn't support splat arguments yet
|
|
23
|
+
pub extern fn pub_join(argc: Argc, argv: *const Value, _: AnyObject) -> AnyObject {
|
|
24
|
+
let args = Value::from(0);
|
|
25
|
+
|
|
26
|
+
unsafe {
|
|
27
|
+
util::rb_scan_args(
|
|
28
|
+
argc,
|
|
29
|
+
argv,
|
|
30
|
+
str_to_cstring("*").as_ptr(),
|
|
31
|
+
&args
|
|
32
|
+
)
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
pathname::pn_join(Ok(Array::from(args)))
|
|
36
|
+
}
|
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.2.
|
|
4
|
+
version: 0.2.5
|
|
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: 2018-02-
|
|
11
|
+
date: 2018-02-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -141,7 +141,6 @@ files:
|
|
|
141
141
|
- ext/faster_path/extconf.rb
|
|
142
142
|
- faster_path.gemspec
|
|
143
143
|
- lib/faster_path.rb
|
|
144
|
-
- lib/faster_path/asset_resolution.rb
|
|
145
144
|
- lib/faster_path/optional/monkeypatches.rb
|
|
146
145
|
- lib/faster_path/optional/refinements.rb
|
|
147
146
|
- lib/faster_path/platform.rb
|
|
@@ -149,12 +148,14 @@ files:
|
|
|
149
148
|
- src/basename.rs
|
|
150
149
|
- src/chop_basename.rs
|
|
151
150
|
- src/cleanpath_aggressive.rs
|
|
151
|
+
- src/cleanpath_conservative.rs
|
|
152
152
|
- src/dirname.rs
|
|
153
153
|
- src/extname.rs
|
|
154
154
|
- src/helpers.rs
|
|
155
155
|
- src/lib.rs
|
|
156
156
|
- src/path_parsing.rs
|
|
157
157
|
- src/pathname.rs
|
|
158
|
+
- src/pathname_sys.rs
|
|
158
159
|
- src/plus.rs
|
|
159
160
|
- src/prepend_prefix.rs
|
|
160
161
|
- src/rust_arch_bits.rs
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
# This is a redundancy check for the rust compiled library needed for this gem.
|
|
2
|
-
# If the asset is not available and we can't compile it from this code then FAIL
|
|
3
|
-
# on require of 'faster_path' with a very clear message as to why."
|
|
4
|
-
|
|
5
|
-
require_relative './platform'
|
|
6
|
-
|
|
7
|
-
module FasterPath
|
|
8
|
-
module AssetResolution # BREAK IN CASE OF EMERGENCY ;-)
|
|
9
|
-
class << self
|
|
10
|
-
def verify!
|
|
11
|
-
return lib_file if file?
|
|
12
|
-
|
|
13
|
-
if rust?
|
|
14
|
-
compile!
|
|
15
|
-
raise "Rust failed to compile asset! The dynamic library for this package was not found." unless file?
|
|
16
|
-
return lib_file
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
raise "The dynamic library for this package was not found nor was Rust's cargo executable found. This package will not work without it!"
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
private
|
|
23
|
-
|
|
24
|
-
def compile!
|
|
25
|
-
require 'open3'
|
|
26
|
-
Dir.chdir(File.expand_path('../../', __dir__)) do
|
|
27
|
-
Open3.popen3("rake build_lib") do |stdin, stdout, stderr, wait_thr|
|
|
28
|
-
stdin.close
|
|
29
|
-
|
|
30
|
-
wait_thr && wait_thr.value.exitstatus
|
|
31
|
-
out = Thread.new { stdout.read }.value.strip
|
|
32
|
-
Thread.new { stderr.read }.value
|
|
33
|
-
out
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
File.exist? lib_file
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def rust?
|
|
40
|
-
require 'mkmf'
|
|
41
|
-
MakeMakefile::Logging.instance_variable_set(:@log, File.open(File::NULL, 'w'))
|
|
42
|
-
MakeMakefile.instance_eval "undef :message; def message(*); end"
|
|
43
|
-
MakeMakefile.find_executable('cargo')
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def file?
|
|
47
|
-
File.exist? lib_file
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def lib_dir
|
|
51
|
-
File.expand_path("../../target/release/", __dir__)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def lib_file
|
|
55
|
-
Platform.ffi_library()
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
FasterPath::AssetResolution.verify! unless ENV['TEST']
|