faster_path 0.2.5 → 0.2.6
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 +9 -9
- data/Cargo.toml +1 -1
- data/README.md +2 -1
- data/lib/faster_path/optional/monkeypatches.rb +4 -0
- data/lib/faster_path/optional/refinements.rb +4 -0
- data/lib/faster_path/version.rb +1 -1
- data/src/chop_basename.rs +12 -35
- data/src/cleanpath_aggressive.rs +1 -1
- data/src/cleanpath_conservative.rs +2 -2
- data/src/debug.rs +29 -0
- data/src/helpers.rs +10 -38
- data/src/lib.rs +15 -3
- data/src/pathname.rs +32 -3
- data/src/pathname_sys.rs +13 -9
- data/src/plus.rs +4 -4
- data/src/relative_path_from.rs +90 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 64eada185c9f0597ca475f6f94f77299b5ebf0458fe6de87d5a041d7a6d69dfe
|
4
|
+
data.tar.gz: 5d14a11a8a468eba873da3b6e4d2628e8fdbb5d88150c60575b6266a4df5f726
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c2121f4aa08b8979818480b78980f07563483befa52c2493821f7a562d0f213a762f192ed1b7ec3c67050c9f0a72bccbb65a0dcb1d7258316ffbe0ae7480c2f
|
7
|
+
data.tar.gz: 0c16b9cd5e5ff583717d664228bfac6ac4b6b5e46c7a92c8a3170ae050ae9ec6974dc597a1c9aff8232e77515b3d5cd70bfccd33c5fa67402091af660dd7f502
|
data/Cargo.lock
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
[[package]]
|
2
2
|
name = "array_tool"
|
3
|
-
version = "0.
|
3
|
+
version = "1.0.1"
|
4
4
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
5
5
|
|
6
6
|
[[package]]
|
7
7
|
name = "faster_path"
|
8
8
|
version = "0.0.1"
|
9
9
|
dependencies = [
|
10
|
-
"array_tool 0.
|
10
|
+
"array_tool 1.0.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
13
|
"ruby-sys 0.3.0 (git+https://github.com/danielpclark/ruby-sys?branch=playground)",
|
@@ -26,7 +26,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
26
26
|
|
27
27
|
[[package]]
|
28
28
|
name = "libc"
|
29
|
-
version = "0.2.
|
29
|
+
version = "0.2.37"
|
30
30
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
31
31
|
|
32
32
|
[[package]]
|
@@ -34,31 +34,31 @@ name = "memchr"
|
|
34
34
|
version = "2.0.1"
|
35
35
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
36
36
|
dependencies = [
|
37
|
-
"libc 0.2.
|
37
|
+
"libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
38
38
|
]
|
39
39
|
|
40
40
|
[[package]]
|
41
41
|
name = "ruby-sys"
|
42
42
|
version = "0.3.0"
|
43
|
-
source = "git+https://github.com/danielpclark/ruby-sys?branch=playground#
|
43
|
+
source = "git+https://github.com/danielpclark/ruby-sys?branch=playground#184a3cd3bd39b525ff956f7cba1770bbf1522d8b"
|
44
44
|
dependencies = [
|
45
|
-
"libc 0.2.
|
45
|
+
"libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
46
46
|
]
|
47
47
|
|
48
48
|
[[package]]
|
49
49
|
name = "ruru"
|
50
50
|
version = "0.9.3"
|
51
|
-
source = "git+https://github.com/danielpclark/ruru?branch=playground#
|
51
|
+
source = "git+https://github.com/danielpclark/ruru?branch=playground#c9b59118ebcf034874d491a0c1f3b57ef05c183a"
|
52
52
|
dependencies = [
|
53
53
|
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
54
54
|
"ruby-sys 0.3.0 (git+https://github.com/danielpclark/ruby-sys?branch=playground)",
|
55
55
|
]
|
56
56
|
|
57
57
|
[metadata]
|
58
|
-
"checksum array_tool 0.
|
58
|
+
"checksum array_tool 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7894b81e06d8a2376f015b34dd89770c549932ff90bba6427f7cd83243bb629b"
|
59
59
|
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
|
60
60
|
"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
|
61
|
-
"checksum libc 0.2.
|
61
|
+
"checksum libc 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)" = "56aebce561378d99a0bb578f8cb15b6114d2a1814a6c7949bbe646d968bb4fa9"
|
62
62
|
"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
|
63
63
|
"checksum ruby-sys 0.3.0 (git+https://github.com/danielpclark/ruby-sys?branch=playground)" = "<none>"
|
64
64
|
"checksum ruru 0.9.3 (git+https://github.com/danielpclark/ruru?branch=playground)" = "<none>"
|
data/Cargo.toml
CHANGED
@@ -15,6 +15,6 @@ crate-type = ["dylib"]
|
|
15
15
|
[dependencies]
|
16
16
|
ruby-sys = { git = "https://github.com/danielpclark/ruby-sys", branch = "playground" }
|
17
17
|
ruru = { git = "https://github.com/danielpclark/ruru", branch = "playground" }
|
18
|
-
array_tool = "0
|
18
|
+
array_tool = "1.0"
|
19
19
|
lazy_static = "1.0"
|
20
20
|
memchr = "2.0.1"
|
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)
|
@@ -151,6 +151,7 @@ Current methods implemented:
|
|
151
151
|
| `FasterPath.plus` | `Pathname#join` | 66.4% |
|
152
152
|
| `FasterPath.plus` | `Pathname#plus` | 81.4% |
|
153
153
|
| `FasterPath.relative?` | `Pathname#relative?` | 84.1% |
|
154
|
+
| `FasterPath.relative_path_from` | `Pathname#relative_path_from` | 69.8% |
|
154
155
|
|
155
156
|
You may choose to use the methods directly, or scope change to rewrite behavior on the
|
156
157
|
standard library with the included refinements, or even call a method to monkeypatch
|
data/lib/faster_path/version.rb
CHANGED
data/src/chop_basename.rs
CHANGED
@@ -1,54 +1,31 @@
|
|
1
1
|
use std::path::MAIN_SEPARATOR;
|
2
2
|
use std::str;
|
3
3
|
|
4
|
-
pub fn chop_basename(input: &str) -> Option<(
|
4
|
+
pub fn chop_basename<'a>(input: &'a str) -> Option<(&'a str, &'a str)> {
|
5
5
|
if input.is_empty() {
|
6
6
|
return None;
|
7
7
|
}
|
8
8
|
|
9
|
-
let
|
10
|
-
let
|
11
|
-
|
12
|
-
match trailing_slashes.next() {
|
13
|
-
Some(MAIN_SEPARATOR) => { offset = offset + 1 },
|
14
|
-
_ => { break },
|
15
|
-
}
|
16
|
-
}
|
17
|
-
|
18
|
-
let input = &input[0..input.len()-offset];
|
19
|
-
let base = input.rsplit_terminator(MAIN_SEPARATOR).nth(0).unwrap_or("");
|
9
|
+
let input = input.trim_right_matches(MAIN_SEPARATOR);
|
10
|
+
let end = input.rsplitn(2, MAIN_SEPARATOR).nth(0).unwrap().len();
|
11
|
+
let base = &input[input.len()-end..input.len()];
|
20
12
|
let directory = &input[0..input.len()-base.len()];
|
21
13
|
|
22
14
|
if directory.is_empty() && (base.is_empty() || base.chars().next().unwrap() == MAIN_SEPARATOR) {
|
23
15
|
return None
|
24
16
|
};
|
25
17
|
|
26
|
-
Some((directory
|
18
|
+
Some((directory, base))
|
27
19
|
}
|
28
20
|
|
29
21
|
#[test]
|
30
22
|
fn it_chops_the_basename_and_dirname() {
|
31
|
-
assert_eq!(chop_basename(
|
32
|
-
assert_eq!(chop_basename(
|
33
|
-
assert_eq!(
|
34
|
-
|
35
|
-
|
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
|
-
);
|
23
|
+
assert_eq!(chop_basename(""), None );
|
24
|
+
assert_eq!(chop_basename("/"), None );
|
25
|
+
assert_eq!(chop_basename("."), Some(("", ".")) );
|
26
|
+
assert_eq!(chop_basename("asdf/asdf"), Some(("asdf/", "asdf")) );
|
27
|
+
assert_eq!(chop_basename("asdf.txt"), Some(("", "asdf.txt")) );
|
28
|
+
assert_eq!(chop_basename("asdf/"), Some(("", "asdf")) );
|
29
|
+
assert_eq!(chop_basename("/asdf/"), Some(("/", "asdf")) );
|
53
30
|
}
|
54
31
|
|
data/src/cleanpath_aggressive.rs
CHANGED
@@ -10,7 +10,7 @@ pub fn cleanpath_aggressive(path: &str) -> String {
|
|
10
10
|
let mut names: Vec<String> = vec![];
|
11
11
|
let mut pre = path.to_string();
|
12
12
|
loop {
|
13
|
-
match chop_basename(&pre) {
|
13
|
+
match chop_basename(&pre.clone()) {
|
14
14
|
Some((ref p, ref base)) => {
|
15
15
|
pre = p.to_string();
|
16
16
|
match base.as_ref() {
|
@@ -11,7 +11,7 @@ pub fn cleanpath_conservative(path: &str) -> String {
|
|
11
11
|
let mut names: Vec<String> = vec![];
|
12
12
|
let mut pre = path.to_string();
|
13
13
|
loop {
|
14
|
-
match chop_basename(&pre) {
|
14
|
+
match chop_basename(&pre.clone()) {
|
15
15
|
Some((ref p, ref base)) => {
|
16
16
|
pre = p.to_string();
|
17
17
|
match base.as_ref() {
|
@@ -90,7 +90,7 @@ fn it_conservatively_cleans_the_path() {
|
|
90
90
|
assert_eq!(cleanpath_conservative("a/../."), "a/..");
|
91
91
|
assert_eq!(cleanpath_conservative("/../.././../a"), "/a");
|
92
92
|
assert_eq!(cleanpath_conservative("a/b/../../../../c/../d"), "a/b/../../../../c/../d");
|
93
|
-
|
93
|
+
|
94
94
|
// Future Windows Support
|
95
95
|
//
|
96
96
|
// DOSISH = File::ALT_SEPARATOR != nil
|
data/src/debug.rs
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
use ruru::{
|
2
|
+
RString,
|
3
|
+
AnyObject,
|
4
|
+
Object,
|
5
|
+
};
|
6
|
+
|
7
|
+
#[derive(Debug)]
|
8
|
+
pub struct RubyDebugInfo {
|
9
|
+
object_id: String,
|
10
|
+
class: String,
|
11
|
+
inspect: String,
|
12
|
+
}
|
13
|
+
|
14
|
+
impl From<AnyObject> for RubyDebugInfo {
|
15
|
+
fn from(ao: AnyObject) -> Self {
|
16
|
+
let object_id = ao.send("object_id", None).send("to_s", None).
|
17
|
+
try_convert_to::<RString>().unwrap_or(RString::new("Failed to get object_id!")).to_string();
|
18
|
+
let class = ao.send("class", None).send("to_s", None).
|
19
|
+
try_convert_to::<RString>().unwrap_or(RString::new("Failed to get class!")).to_string();
|
20
|
+
let inspect = ao.send("inspect", None).
|
21
|
+
try_convert_to::<RString>().unwrap_or(RString::new("Failed to get inspect!")).to_string();
|
22
|
+
|
23
|
+
RubyDebugInfo {
|
24
|
+
object_id: object_id,
|
25
|
+
class: class,
|
26
|
+
inspect: inspect,
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
data/src/helpers.rs
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
use ruru::{RString, Object, Class, AnyObject};
|
2
|
-
use
|
2
|
+
use debug::RubyDebugInfo;
|
3
|
+
|
4
|
+
#[inline]
|
5
|
+
pub fn is_same_path(a: &str, b: &str) -> bool {
|
6
|
+
if cfg!(windows) {
|
7
|
+
a.to_uppercase() == b.to_uppercase()
|
8
|
+
} else {
|
9
|
+
a == b
|
10
|
+
}
|
11
|
+
}
|
3
12
|
|
4
13
|
pub fn anyobject_to_string(item: AnyObject) -> Result<String, RubyDebugInfo> {
|
5
14
|
let result = &item;
|
@@ -24,40 +33,3 @@ pub fn anyobject_to_string(item: AnyObject) -> Result<String, RubyDebugInfo> {
|
|
24
33
|
|
25
34
|
Ok(RString::from(result.send("to_s", None).value()).to_string())
|
26
35
|
}
|
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
|
-
}
|
63
|
-
}
|
data/src/lib.rs
CHANGED
@@ -4,6 +4,8 @@
|
|
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
|
+
#![feature(try_from)]
|
8
|
+
|
7
9
|
#[macro_use]
|
8
10
|
extern crate ruru;
|
9
11
|
|
@@ -12,6 +14,7 @@ extern crate lazy_static;
|
|
12
14
|
|
13
15
|
module!(FasterPath);
|
14
16
|
|
17
|
+
mod debug;
|
15
18
|
mod helpers;
|
16
19
|
mod pathname;
|
17
20
|
mod basename;
|
@@ -25,6 +28,10 @@ mod plus;
|
|
25
28
|
mod prepend_prefix;
|
26
29
|
pub mod rust_arch_bits;
|
27
30
|
mod path_parsing;
|
31
|
+
mod relative_path_from;
|
32
|
+
|
33
|
+
use pathname::Pathname;
|
34
|
+
use pathname_sys::raise;
|
28
35
|
|
29
36
|
use ruru::{Module, Object, RString, Boolean, Array, AnyObject};
|
30
37
|
|
@@ -139,8 +146,12 @@ methods!(
|
|
139
146
|
|
140
147
|
// fn r_split_names(pth: RString){}
|
141
148
|
|
142
|
-
|
143
|
-
|
149
|
+
fn pub_relative_path_from(itself: RString, base_directory: AnyObject) -> Pathname {
|
150
|
+
let to_string = |i: AnyObject| { RString::from(i.send("to_s", None).value()) };
|
151
|
+
|
152
|
+
pathname::pn_relative_path_from(itself, base_directory.map(to_string)).
|
153
|
+
map_err(|e| raise(e) ).unwrap()
|
154
|
+
}
|
144
155
|
|
145
156
|
// fn pub_rmtree(pth: RString) -> NilClass {
|
146
157
|
// pathname::pn_rmtree(pth)
|
@@ -149,7 +160,7 @@ methods!(
|
|
149
160
|
|
150
161
|
#[allow(non_snake_case)]
|
151
162
|
#[no_mangle]
|
152
|
-
pub extern "C" fn Init_faster_pathname(){
|
163
|
+
pub extern "C" fn Init_faster_pathname() {
|
153
164
|
Module::from_existing("FasterPath").define(|itself| {
|
154
165
|
itself.def_self("absolute?", pub_is_absolute);
|
155
166
|
itself.def_self("add_trailing_separator", pub_add_trailing_separator);
|
@@ -164,6 +175,7 @@ pub extern "C" fn Init_faster_pathname(){
|
|
164
175
|
pathname_sys::define_singleton_method(itself.value(), "join", pub_join);
|
165
176
|
itself.def_self("plus", pub_plus);
|
166
177
|
itself.def_self("relative?", pub_is_relative);
|
178
|
+
itself.def_self("relative_path_from", pub_relative_path_from);
|
167
179
|
itself.define_nested_class("Public", None);
|
168
180
|
});
|
169
181
|
|
data/src/pathname.rs
CHANGED
@@ -6,9 +6,22 @@ use cleanpath_conservative;
|
|
6
6
|
use dirname;
|
7
7
|
use extname;
|
8
8
|
use plus;
|
9
|
+
use relative_path_from;
|
10
|
+
use debug;
|
11
|
+
use std::convert::TryFrom;
|
9
12
|
|
10
13
|
use ruru;
|
11
|
-
use ruru::{
|
14
|
+
use ruru::{
|
15
|
+
RString,
|
16
|
+
Boolean,
|
17
|
+
Array,
|
18
|
+
AnyObject,
|
19
|
+
NilClass,
|
20
|
+
Object,
|
21
|
+
Class,
|
22
|
+
VerifiedObject,
|
23
|
+
AnyException as Exception
|
24
|
+
};
|
12
25
|
use ruru::types::{Value, ValueType};
|
13
26
|
use std::path::{MAIN_SEPARATOR,Path};
|
14
27
|
use std::fs;
|
@@ -40,6 +53,19 @@ impl From<Value> for Pathname {
|
|
40
53
|
}
|
41
54
|
}
|
42
55
|
|
56
|
+
impl TryFrom<AnyObject> for Pathname {
|
57
|
+
type Error = debug::RubyDebugInfo;
|
58
|
+
fn try_from(obj: AnyObject) -> Result<Pathname, Self::Error> {
|
59
|
+
if Class::from_existing("String").case_equals(&obj) {
|
60
|
+
Ok(Pathname::new(&RString::from(obj.value()).to_string()))
|
61
|
+
} else if Class::from_existing("Pathname").case_equals(&obj) {
|
62
|
+
Ok(Pathname::from(obj.value()))
|
63
|
+
} else {
|
64
|
+
Err(Self::Error::from(obj))
|
65
|
+
}
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
43
69
|
impl Object for Pathname {
|
44
70
|
#[inline]
|
45
71
|
fn value(&self) -> Value {
|
@@ -151,7 +177,8 @@ pub fn pn_children_compat(pth: MaybeString, with_dir: MaybeBoolean) -> AnyObject
|
|
151
177
|
|
152
178
|
pub fn pn_chop_basename(pth: MaybeString) -> Array {
|
153
179
|
let mut arr = Array::with_capacity(2);
|
154
|
-
let
|
180
|
+
let pth = pth.ok().unwrap_or(RString::new(""));
|
181
|
+
let results = chop_basename::chop_basename(pth.to_str());
|
155
182
|
match results {
|
156
183
|
Some((dirname, basename)) => {
|
157
184
|
arr.push(RString::new(&dirname[..]));
|
@@ -341,7 +368,9 @@ pub fn pn_is_relative(pth: MaybeString) -> Boolean {
|
|
341
368
|
|
342
369
|
// pub fn pn_split_names(pth: MaybeString){}
|
343
370
|
|
344
|
-
|
371
|
+
pub fn pn_relative_path_from(itself: MaybeString, base_directory: MaybeString) -> Result<Pathname, Exception> {
|
372
|
+
relative_path_from::relative_path_from(itself, base_directory)
|
373
|
+
}
|
345
374
|
|
346
375
|
// pub fn pn_rmtree(pth: MaybeString) -> NilClass {
|
347
376
|
// NilClass::new()
|
data/src/pathname_sys.rs
CHANGED
@@ -1,22 +1,26 @@
|
|
1
|
-
use ruru::{AnyObject, Array, Object};
|
1
|
+
use ruru::{AnyObject, Array, Object, AnyException};
|
2
2
|
use ruru::types::{Argc, Value, CallbackPtr};
|
3
3
|
use ruru::util::str_to_cstring;
|
4
4
|
extern crate ruby_sys;
|
5
|
-
use self::ruby_sys::{class, util};
|
5
|
+
use self::ruby_sys::{class, util, vm};
|
6
6
|
use ::pathname;
|
7
7
|
|
8
|
+
pub fn raise(exception: AnyException) {
|
9
|
+
unsafe { vm::rb_exc_raise(exception.value()); }
|
10
|
+
}
|
11
|
+
|
8
12
|
pub type ValueCallback<I, O> = extern "C" fn(Argc, *const Value, I) -> O;
|
9
13
|
|
10
14
|
pub fn define_singleton_method<I: Object, O: Object>(
|
11
|
-
|
12
|
-
|
13
|
-
|
15
|
+
klass: Value,
|
16
|
+
name: &str,
|
17
|
+
callback: ValueCallback<I, O>,
|
14
18
|
) {
|
15
|
-
|
19
|
+
let name = str_to_cstring(name);
|
16
20
|
|
17
|
-
|
18
|
-
|
19
|
-
|
21
|
+
unsafe {
|
22
|
+
class::rb_define_singleton_method(klass, name.as_ptr(), callback as CallbackPtr, -1);
|
23
|
+
}
|
20
24
|
}
|
21
25
|
|
22
26
|
// ruru doesn't support splat arguments yet
|
data/src/plus.rs
CHANGED
@@ -13,10 +13,10 @@ pub fn plus_paths(path1: &str, path2: &str) -> String {
|
|
13
13
|
let mut basename_list2: Vec<String> = vec![];
|
14
14
|
|
15
15
|
loop {
|
16
|
-
match chop_basename(&prefix2[..]) {
|
16
|
+
match chop_basename(&prefix2.clone()[..]) {
|
17
17
|
None => { break },
|
18
18
|
Some((pfx2, basename2)) => {
|
19
|
-
prefix2 = pfx2.
|
19
|
+
prefix2 = pfx2.to_string();
|
20
20
|
index_list2.unshift(pfx2.len());
|
21
21
|
basename_list2.unshift(basename2.to_owned());
|
22
22
|
},
|
@@ -33,10 +33,10 @@ pub fn plus_paths(path1: &str, path2: &str) -> String {
|
|
33
33
|
index_list2.shift();
|
34
34
|
basename_list2.shift();
|
35
35
|
}
|
36
|
-
match chop_basename(&prefix1[..]) {
|
36
|
+
match chop_basename(&prefix1.clone()[..]) {
|
37
37
|
None => { break },
|
38
38
|
Some((pfx1, basename1)) => {
|
39
|
-
prefix1 = pfx1.
|
39
|
+
prefix1 = pfx1.to_string();
|
40
40
|
if basename1 == "." { continue };
|
41
41
|
if basename1 == ".." || basename_list2.is_empty() || basename_list2.first().unwrap() != ".." {
|
42
42
|
prefix1.push_str(&basename1);
|
@@ -0,0 +1,90 @@
|
|
1
|
+
use helpers::is_same_path;
|
2
|
+
use path_parsing::SEP_STR;
|
3
|
+
extern crate array_tool;
|
4
|
+
use self::array_tool::vec::{Shift, Join};
|
5
|
+
use self::array_tool::iter::ZipOpt;
|
6
|
+
use pathname;
|
7
|
+
use ruru;
|
8
|
+
use chop_basename;
|
9
|
+
use pathname::Pathname;
|
10
|
+
use ruru::{Exception as Exc, AnyException as Exception};
|
11
|
+
|
12
|
+
type MaybeString = Result<ruru::RString, ruru::result::Error>;
|
13
|
+
|
14
|
+
pub fn relative_path_from(itself: MaybeString, base_directory: MaybeString) -> Result<Pathname, Exception> {
|
15
|
+
let dest_directory = pathname::pn_cleanpath_aggressive(itself).to_string();
|
16
|
+
let base_directory = pathname::pn_cleanpath_aggressive(base_directory).to_string();
|
17
|
+
|
18
|
+
let mut dest_prefix = dest_directory.clone();
|
19
|
+
let mut dest_names: Vec<String> = vec![];
|
20
|
+
loop {
|
21
|
+
match chop_basename::chop_basename(&dest_prefix.clone()) {
|
22
|
+
Some((ref dest, ref basename)) => {
|
23
|
+
dest_prefix = dest.to_string();
|
24
|
+
if basename != &"." {
|
25
|
+
dest_names.unshift(basename.to_string())
|
26
|
+
}
|
27
|
+
},
|
28
|
+
None => break,
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
let mut base_prefix = base_directory.clone();
|
33
|
+
let mut base_names: Vec<String> = vec![];
|
34
|
+
loop {
|
35
|
+
match chop_basename::chop_basename(&base_prefix.clone()) {
|
36
|
+
Some((ref base, ref basename)) => {
|
37
|
+
base_prefix = base.to_string();
|
38
|
+
if basename != &"." {
|
39
|
+
base_names.unshift(basename.to_string())
|
40
|
+
}
|
41
|
+
},
|
42
|
+
None => break,
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
if !is_same_path(&dest_prefix, &base_prefix) {
|
47
|
+
return Err(
|
48
|
+
Exception::new(
|
49
|
+
"ArgumentError",
|
50
|
+
Some(&format!("different prefix: {} and {}", dest_prefix, base_prefix)[..])
|
51
|
+
)
|
52
|
+
);
|
53
|
+
}
|
54
|
+
|
55
|
+
let (dest_names, base_names): (Vec<String>, Vec<String>) = dest_names.
|
56
|
+
iter().
|
57
|
+
zip_option(base_names.iter()).
|
58
|
+
skip_while(|&(a, b)| {
|
59
|
+
match (a, b) {
|
60
|
+
(Some(x), Some(y)) => is_same_path(x,y),
|
61
|
+
_ => false,
|
62
|
+
}
|
63
|
+
}).
|
64
|
+
fold((vec![], vec![]), |mut acc, (a, b)| {
|
65
|
+
if let Some(v) = a {
|
66
|
+
acc.0.push(v.to_string());
|
67
|
+
}
|
68
|
+
if let Some(v) = b {
|
69
|
+
acc.1.push(v.to_string());
|
70
|
+
}
|
71
|
+
acc
|
72
|
+
});
|
73
|
+
|
74
|
+
if base_names.contains(&"..".to_string()) {
|
75
|
+
return Err(
|
76
|
+
Exception::new(
|
77
|
+
"ArgumentError",
|
78
|
+
Some(&format!("base_directory has ..: {}", base_directory)[..])
|
79
|
+
)
|
80
|
+
);
|
81
|
+
}
|
82
|
+
|
83
|
+
let base_names: Vec<String> = base_names.into_iter().map(|_| "..".to_string()).collect();
|
84
|
+
|
85
|
+
if base_names.is_empty() && dest_names.is_empty() {
|
86
|
+
Ok(Pathname::new("."))
|
87
|
+
} else {
|
88
|
+
Ok(Pathname::new(&base_names.iter().chain(dest_names.iter()).collect::<Vec<&String>>().join(&SEP_STR)))
|
89
|
+
}
|
90
|
+
}
|
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.6
|
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-
|
11
|
+
date: 2018-03-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -149,6 +149,7 @@ files:
|
|
149
149
|
- src/chop_basename.rs
|
150
150
|
- src/cleanpath_aggressive.rs
|
151
151
|
- src/cleanpath_conservative.rs
|
152
|
+
- src/debug.rs
|
152
153
|
- src/dirname.rs
|
153
154
|
- src/extname.rs
|
154
155
|
- src/helpers.rs
|
@@ -158,6 +159,7 @@ files:
|
|
158
159
|
- src/pathname_sys.rs
|
159
160
|
- src/plus.rs
|
160
161
|
- src/prepend_prefix.rs
|
162
|
+
- src/relative_path_from.rs
|
161
163
|
- src/rust_arch_bits.rs
|
162
164
|
homepage: https://github.com/danielpclark/faster_path
|
163
165
|
licenses:
|