faster_path 0.2.4 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![TravisCI Build Status](https://travis-ci.org/danielpclark/faster_path.svg?branch=master)](https://travis-ci.org/danielpclark/faster_path)
|
4
4
|
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/10ul0gk3cwhlt2lj/branch/master?svg=true)](https://ci.appveyor.com/project/danielpclark/faster-path/branch/master)
|
5
5
|
[![Latest Tag](https://img.shields.io/github/tag/danielpclark/faster_path.svg)](https://github.com/danielpclark/faster_path/tags)
|
6
|
-
[![Commits Since Last Release](https://img.shields.io/github/commits-since/danielpclark/faster_path/v0.2.
|
6
|
+
[![Commits Since Last Release](https://img.shields.io/github/commits-since/danielpclark/faster_path/v0.2.5.svg)](https://github.com/danielpclark/faster_path/pulse)
|
7
7
|
[![Binary Release](https://img.shields.io/github/release/danielpclark/faster_path.svg)](https://github.com/danielpclark/faster_path/releases)
|
8
8
|
[![Coverage Status](https://coveralls.io/repos/github/danielpclark/faster_path/badge.svg)](https://coveralls.io/github/danielpclark/faster_path)
|
9
9
|
[![Inline docs](http://inch-ci.org/github/danielpclark/faster_path.svg?branch=master)](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']
|