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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 95885428dc6e619ea1069fd3473cd68ffd762eca29d09f1185ebfafc7cbcbebf
4
- data.tar.gz: 4ad3a157841d4003e7314295fb955a01565c903c05942b112527a95818664f7c
3
+ metadata.gz: 1f459170e11712e3d18dc8937e433ea724dd7dd016b3e5cbf5a7e6da722b4dfe
4
+ data.tar.gz: a3c27c26aee46ca61237635c42add31fb307a787706af74b87eb62eb74c17dda
5
5
  SHA512:
6
- metadata.gz: 881379d959fcadeaf9e23236327b9b2da8315a3e95307718cc4ff763002eb1ea11134b7607518f98a6b20a9d5b9db3b38d31174d85b8c5bbc3fdca6a3f8c8aac
7
- data.tar.gz: 961dd0da7cff5e3ac96aa3745dfe803464d748784fabe51a49988afb254e6995d168e640abc25b7cae64379b1c1b53b6faa5f299ee74adcc2d01ad11cf05153a
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.8"
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.30"
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.30 (registry+https://github.com/rust-lang/crates.io-index)",
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#08c96179e46ce8a5fec25e1b4aeb5d9c63a2245e"
43
+ source = "git+https://github.com/danielpclark/ruby-sys?branch=playground#a71d5783e92d9dfd3602f81adc96f640ff377f21"
43
44
  dependencies = [
44
- "libc 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)",
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#aa4a08c48374bb13983cf6de5df7125a18ea1169"
51
+ source = "git+https://github.com/danielpclark/ruru?branch=playground#e35b9dd88d86f3b8bb9cede7a74b04781bd4da89"
51
52
  dependencies = [
52
- "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
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.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf"
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.30 (registry+https://github.com/rust-lang/crates.io-index)" = "2370ca07ec338939e356443dac2296f581453c35fe1e3a3ed06023c49435f915"
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-2017 Daniel P. Clark & FasterPath Contributors
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.3.svg)](https://github.com/danielpclark/faster_path/pulse)
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.3.4 Implementation|Time Shaved Off|
139
+ |FasterPath Rust Implementation|Ruby 2.5.0 Implementation|Time Shaved Off|
140
140
  |---|---|:---:|
141
- | `FasterPath.absolute?` | `Pathname#absolute?` | 88.5% |
142
- | `FasterPath.add_trailing_separator` | `Pathname#add_trailing_separator` | 31.1% |
143
- | `FasterPath.children` | `Pathname#children` | 14.6% |
144
- | `FasterPath.chop_basename` | `Pathname#chop_basename` | 56.7% |
145
- | `FasterPath.cleanpath_aggressive` | `Pathname#cleanpath_aggressive` | 69.8% |
146
- | `FasterPath.directory?` | `Pathname#directory?` | 12.7% |
147
- | `FasterPath.entries` | `Pathname#entries` | 7.7% |
148
- | `FasterPath.has_trailing_separator?` | `Pathname#has_trailing_separator` | 59.2% |
149
- | `FasterPath.plus` | `Pathname#plus` | 77.9% |
150
- | `FasterPath.relative?` | `Pathname#relative?` | 83.1% |
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
@@ -1,3 +1,3 @@
1
1
  module FasterPath
2
- VERSION = "0.2.4"
2
+ VERSION = "0.2.5"
3
3
  end
data/lib/faster_path.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  require "faster_path/version"
2
2
  require 'pathname'
3
3
  require 'faster_path/platform'
4
- require 'faster_path/asset_resolution'
5
4
  require 'fiddle'
6
5
  require 'fiddle/import'
7
6
 
@@ -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
- pub fn new_pathname_instance(path: &str) -> Class {
4
- let mut path_instance = Class::from(
5
- Class::from_existing("Pathname").send("allocate", None).value()
6
- );
7
- path_instance.instance_variable_set(
8
- "@path",
9
- RString::new(path).to_any_object()
10
- );
11
-
12
- path_instance
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
- // r_ methods are on the core class and may evaluate instance variables or self
30
- // pub_ methods must take all values as parameters
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
- // fn r_cleanpath_conservative(pth: RString){}
70
+ fn pub_cleanpath_conservative(pth: RString) -> RString {
71
+ pathname::pn_cleanpath_conservative(pth)
72
+ }
69
73
 
70
- // fn r_del_trailing_separator(pth: RString){}
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::new_pathname_instance;
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(new_pathname_instance(v.path().to_str().unwrap()));
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(new_pathname_instance(v.file_name().to_str().unwrap()));
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
- // pub fn pn_cleanpath_conservative(pth: MaybeString){}
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
- // pub fn pn_del_trailing_separator(pth: MaybeString){}
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.push(new_pathname_instance("."));
184
- arr.push(new_pathname_instance(".."));
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(new_pathname_instance(&file_name_str));
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 ,ignore_error: Boolean){}
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
- // pub fn pn_join(args: Array){}
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(
@@ -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
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-20 00:00:00.000000000 Z
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']