faster_path 0.3.10 → 0.4.0
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 +19 -37
- data/Cargo.toml +5 -6
- data/Gemfile +3 -7
- data/README.md +94 -30
- data/Rakefile +11 -2
- data/faster_path.gemspec +6 -3
- data/lib/faster_path/version.rb +1 -1
- data/lib/faster_path.rb +4 -2
- data/src/basename.rs +166 -69
- data/src/chop_basename.rs +84 -21
- data/src/cleanpath_aggressive.rs +87 -71
- data/src/cleanpath_conservative.rs +175 -79
- data/src/dirname.rs +96 -32
- data/src/extname.rs +150 -20
- data/src/lib.rs +54 -104
- data/src/path_parsing.rs +282 -21
- data/src/pathname.rs +296 -256
- data/src/plus.rs +90 -74
- data/src/prepend_prefix.rs +11 -13
- data/src/relative_path_from.rs +72 -48
- data/src/ruby.rs +530 -0
- metadata +17 -18
- data/src/debug.rs +0 -29
- data/src/helpers.rs +0 -51
- data/src/memrnchr.rs +0 -70
- data/src/pathname_sys.rs +0 -41
data/src/helpers.rs
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
use ruru::{RString, Object, Class, AnyObject};
|
|
2
|
-
extern crate ruby_sys;
|
|
3
|
-
use debug::RubyDebugInfo;
|
|
4
|
-
use ruru;
|
|
5
|
-
|
|
6
|
-
type MaybeString = Result<ruru::RString, ruru::result::Error>;
|
|
7
|
-
|
|
8
|
-
pub trait TryFrom<T>: Sized {
|
|
9
|
-
type Error;
|
|
10
|
-
|
|
11
|
-
fn try_from(value: T) -> Result<Self, Self::Error>;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
#[cfg(windows)]
|
|
15
|
-
#[inline]
|
|
16
|
-
pub fn is_same_path(a: &str, b: &str) -> bool {
|
|
17
|
-
a.to_uppercase() == b.to_uppercase()
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
#[cfg(not(windows))]
|
|
21
|
-
#[inline]
|
|
22
|
-
pub fn is_same_path(a: &str, b: &str) -> bool {
|
|
23
|
-
a == b
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
pub fn anyobject_to_string(item: AnyObject) -> Result<String, RubyDebugInfo> {
|
|
27
|
-
let result = &item;
|
|
28
|
-
if Class::from_existing("String").case_equals(result) {
|
|
29
|
-
return Ok(RString::from(result.value()).to_string())
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if Class::from_existing("Pathname").case_equals(result) {
|
|
33
|
-
return Ok(result.instance_variable_get("@path").
|
|
34
|
-
try_convert_to::<RString>().
|
|
35
|
-
unwrap_or(RString::new("")).
|
|
36
|
-
to_string())
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if result.respond_to("to_path") {
|
|
40
|
-
return Ok(RString::from(result.send("to_path", None).value()).to_string())
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
Ok(RString::from(result.send("to_s", None).value()).to_string())
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
pub fn to_str(maybe_string: &MaybeString) -> &str {
|
|
47
|
-
match maybe_string {
|
|
48
|
-
&Ok(ref ruru_string) => ruru_string.to_str(),
|
|
49
|
-
&Err(_) => "",
|
|
50
|
-
}
|
|
51
|
-
}
|
data/src/memrnchr.rs
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
// The code below is based on the fallback `memrchr` implementation from the respective crate.
|
|
2
|
-
//
|
|
3
|
-
// We use this mainly to skip repeated `/`. If there is only one slash, `memrnchr` performs the same
|
|
4
|
-
// as a naive version (e.g. `rposition`). However, it is much faster in pathological cases.
|
|
5
|
-
|
|
6
|
-
use std::mem::size_of;
|
|
7
|
-
|
|
8
|
-
// Returns the byte offset of the last byte that is NOT equal to the given one.
|
|
9
|
-
#[inline(always)]
|
|
10
|
-
pub fn memrnchr(x: u8, text: &[u8]) -> Option<usize> {
|
|
11
|
-
// Scan for a single byte value by reading two `usize` words at a time.
|
|
12
|
-
//
|
|
13
|
-
// Split `text` in three parts
|
|
14
|
-
// - unaligned tail, after the last word aligned address in text
|
|
15
|
-
// - body, scan by 2 words at a time
|
|
16
|
-
// - the first remaining bytes, < 2 word size
|
|
17
|
-
let len = text.len();
|
|
18
|
-
let ptr = text.as_ptr();
|
|
19
|
-
|
|
20
|
-
// search to an aligned boundary
|
|
21
|
-
let end_align = (ptr as usize + len) & (size_of::<usize>() - 1);
|
|
22
|
-
let mut offset;
|
|
23
|
-
if end_align > 0 {
|
|
24
|
-
offset = if end_align >= len { 0 } else { len - end_align };
|
|
25
|
-
if let Some(index) = memrnchr_naive(x, &text[offset..]) {
|
|
26
|
-
return Some(offset + index);
|
|
27
|
-
}
|
|
28
|
-
} else {
|
|
29
|
-
offset = len;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// search the body of the text
|
|
33
|
-
let repeated_x = repeat_byte(x);
|
|
34
|
-
while offset >= 2 * size_of::<usize>() {
|
|
35
|
-
debug_assert_eq!((ptr as usize + offset) % size_of::<usize>(), 0);
|
|
36
|
-
unsafe {
|
|
37
|
-
let u = *(ptr.offset(offset as isize - 2 * size_of::<usize>() as isize) as *const usize);
|
|
38
|
-
let v = *(ptr.offset(offset as isize - size_of::<usize>() as isize) as *const usize);
|
|
39
|
-
if u & repeated_x != usize::max_value() || v & repeated_x != usize::max_value() {
|
|
40
|
-
break;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
offset -= 2 * size_of::<usize>();
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// find the byte before the point the body loop stopped
|
|
47
|
-
memrnchr_naive(x, &text[..offset])
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
#[inline(always)]
|
|
51
|
-
fn memrnchr_naive(x: u8, text: &[u8]) -> Option<usize> {
|
|
52
|
-
text.iter().rposition(|c| *c != x)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
#[cfg(target_pointer_width = "32")]
|
|
56
|
-
#[inline]
|
|
57
|
-
fn repeat_byte(b: u8) -> usize {
|
|
58
|
-
let mut rep = (b as usize) << 8 | b as usize;
|
|
59
|
-
rep = rep << 16 | rep;
|
|
60
|
-
rep
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
#[cfg(target_pointer_width = "64")]
|
|
64
|
-
#[inline]
|
|
65
|
-
fn repeat_byte(b: u8) -> usize {
|
|
66
|
-
let mut rep = (b as usize) << 8 | b as usize;
|
|
67
|
-
rep = rep << 16 | rep;
|
|
68
|
-
rep = rep << 32 | rep;
|
|
69
|
-
rep
|
|
70
|
-
}
|
data/src/pathname_sys.rs
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
use ruru::{AnyObject, Array, Object, AnyException};
|
|
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, vm};
|
|
6
|
-
use ::pathname;
|
|
7
|
-
extern crate memchr;
|
|
8
|
-
|
|
9
|
-
pub fn raise(exception: AnyException) {
|
|
10
|
-
unsafe { vm::rb_exc_raise(exception.value()); }
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
pub type ValueCallback<I, O> = extern "C" fn(Argc, *const Value, I) -> O;
|
|
14
|
-
|
|
15
|
-
pub fn define_singleton_method<I: Object, O: Object>(
|
|
16
|
-
klass: Value,
|
|
17
|
-
name: &str,
|
|
18
|
-
callback: ValueCallback<I, O>,
|
|
19
|
-
) {
|
|
20
|
-
let name = str_to_cstring(name);
|
|
21
|
-
|
|
22
|
-
unsafe {
|
|
23
|
-
class::rb_define_singleton_method(klass, name.as_ptr(), callback as CallbackPtr, -1);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// ruru doesn't support splat arguments yet
|
|
28
|
-
pub extern fn pub_join(argc: Argc, argv: *const Value, _: AnyObject) -> AnyObject {
|
|
29
|
-
let args = Value::from(0);
|
|
30
|
-
|
|
31
|
-
unsafe {
|
|
32
|
-
util::rb_scan_args(
|
|
33
|
-
argc,
|
|
34
|
-
argv,
|
|
35
|
-
str_to_cstring("*").as_ptr(),
|
|
36
|
-
&args
|
|
37
|
-
)
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
pathname::pn_join(Ok(Array::from(args)))
|
|
41
|
-
}
|