src/pathname.rs in faster_path-0.2.4 vs src/pathname.rs in faster_path-0.2.5
- old
+ new
@@ -1,21 +1,65 @@
-use helpers::new_pathname_instance;
+use helpers::*;
use basename;
use chop_basename;
use cleanpath_aggressive;
+use cleanpath_conservative;
use dirname;
use extname;
use plus;
use ruru;
-use ruru::{RString, Boolean, Array, AnyObject, NilClass, Object};
+use ruru::{RString, Boolean, Array, AnyObject, NilClass, Object, Class, VerifiedObject};
+use ruru::types::{Value, ValueType};
use std::path::{MAIN_SEPARATOR,Path};
use std::fs;
+type MaybeArray = Result<ruru::Array, ruru::result::Error>;
type MaybeString = Result<ruru::RString, ruru::result::Error>;
type MaybeBoolean = Result<ruru::Boolean, ruru::result::Error>;
+pub struct Pathname {
+ value: Value
+}
+
+impl Pathname {
+ pub fn new(path: &str) -> Pathname {
+ let mut instance = Class::from_existing("Pathname").allocate();
+ instance.instance_variable_set("@path", RString::new(path).to_any_object());
+
+ Pathname { value: instance.value() }
+ }
+
+ pub fn to_any_object(&self) -> AnyObject {
+ AnyObject::from(self.value())
+ }
+}
+
+impl From<Value> for Pathname {
+ fn from(value: Value) -> Self {
+ Pathname { value: value }
+ }
+}
+
+impl Object for Pathname {
+ #[inline]
+ fn value(&self) -> Value {
+ self.value
+ }
+}
+
+impl VerifiedObject for Pathname {
+ fn is_correct_type<T: Object>(object: &T) -> bool {
+ object.value().ty() == ValueType::Class &&
+ Class::from_existing("Pathname").case_equals(object)
+ }
+
+ fn error_message() -> &'static str {
+ "Error converting to Pathname"
+ }
+}
+
pub fn pn_add_trailing_separator(pth: MaybeString) -> RString {
let p = pth.ok().unwrap();
let x = format!("{}{}", p.to_str(), "a");
match x.rsplit_terminator(MAIN_SEPARATOR).next() {
Some("a") => p,
@@ -40,20 +84,20 @@
)
)
}
pub fn pn_children(pth: MaybeString, with_dir: MaybeBoolean) -> AnyObject {
- let mut arr = Array::new();
let val = pth.ok().unwrap_or(RString::new("."));
let val = val.to_str();
if let Ok(entries) = fs::read_dir(val) {
let mut with_directory = with_dir.ok().unwrap_or(Boolean::new(true)).to_bool();
if val == "." {
with_directory = false;
}
+ let mut arr = Array::new();
for entry in entries {
if with_directory {
match entry {
Ok(v) => { arr.push(RString::new(v.path().to_str().unwrap())); },
_ => {}
@@ -73,28 +117,28 @@
NilClass::new().to_any_object()
}
}
pub fn pn_children_compat(pth: MaybeString, with_dir: MaybeBoolean) -> AnyObject {
- let mut arr = Array::new();
let val = pth.ok().unwrap_or(RString::new("."));
let val = val.to_str();
if let Ok(entries) = fs::read_dir(val) {
let mut with_directory = with_dir.ok().unwrap_or(Boolean::new(true)).to_bool();
if val == "." {
with_directory = false;
}
+ let mut arr = Array::new();
for entry in entries {
if with_directory {
if let Ok(v) = entry {
- arr.push(new_pathname_instance(v.path().to_str().unwrap()));
+ arr.push(Pathname::new(v.path().to_str().unwrap()));
};
} else {
if let Ok(v) = entry {
- arr.push(new_pathname_instance(v.file_name().to_str().unwrap()));
+ arr.push(Pathname::new(v.file_name().to_str().unwrap()));
};
}
}
arr.to_any_object()
@@ -126,14 +170,38 @@
);
RString::new(&path)
}
-// pub fn pn_cleanpath_conservative(pth: MaybeString){}
+pub fn pn_cleanpath_conservative(pth: MaybeString) -> RString {
+ let path = cleanpath_conservative::cleanpath_conservative(
+ pth.ok().unwrap_or(RString::new("")).to_str()
+ );
-// pub fn pn_del_trailing_separator(pth: MaybeString){}
+ RString::new(&path)
+}
+pub fn pn_del_trailing_separator(pth: MaybeString) -> RString {
+ if let &Ok(ref path) = &pth {
+ let path = path.to_str();
+
+ if !path.is_empty() {
+ let path = path.trim_right_matches('/');
+
+ if path.is_empty() {
+ return RString::new("/");
+ } else {
+ return RString::new(path);
+ }
+ }
+ } else {
+ return RString::new("");
+ }
+
+ pth.unwrap()
+}
+
// pub fn pn_descend(){}
pub fn pn_is_directory(pth: MaybeString) -> Boolean {
Boolean::new(
Path::new(
@@ -155,13 +223,13 @@
// pub fn pn_each_filename(pth: MaybeString) -> NilClass {
// NilClass::new()
// }
pub fn pn_entries(pth: MaybeString) -> AnyObject {
- let mut arr = Array::new();
-
if let Ok(files) = fs::read_dir(pth.ok().unwrap_or(RString::new("")).to_str()) {
+ let mut arr = Array::new();
+
arr.push(RString::new("."));
arr.push(RString::new(".."));
for file in files {
let file_name_str = file.unwrap().file_name().into_string().unwrap();
@@ -175,19 +243,19 @@
NilClass::new().to_any_object()
}
}
pub fn pn_entries_compat(pth: MaybeString) -> AnyObject {
- let mut arr = Array::new();
-
if let Ok(files) = fs::read_dir(pth.ok().unwrap_or(RString::new("")).to_str()) {
- arr.push(new_pathname_instance("."));
- arr.push(new_pathname_instance(".."));
+ let mut arr = Array::new();
+ arr.push(Pathname::new("."));
+ arr.push(Pathname::new(".."));
+
for file in files {
let file_name_str = file.unwrap().file_name().into_string().unwrap();
- arr.push(new_pathname_instance(&file_name_str));
+ arr.push(Pathname::new(&file_name_str));
}
arr.to_any_object()
} else {
// TODO: When ruru exceptions are available switch the exception logic
@@ -200,11 +268,11 @@
RString::new(
extname::extname(pth.ok().unwrap_or(RString::new("")).to_str())
)
}
-// pub fn pn_find(pth: MaybeString ,ignore_error: Boolean){}
+// pub fn pn_find(pth: MaybeString, ignore_error: Boolean){}
pub fn pn_has_trailing_separator(pth: MaybeString) -> Boolean {
let v = pth.ok().unwrap_or(RString::new(""));
match chop_basename::chop_basename(v.to_str()) {
Some((a,b)) => {
@@ -212,20 +280,44 @@
},
_ => Boolean::new(false)
}
}
-// pub fn pn_join(args: Array){}
+pub fn pn_join(args: MaybeArray) -> AnyObject {
+ let mut args = args.unwrap();
+ let path_self = anyobject_to_string(args.shift()).unwrap();
+ let mut qty = args.length();
+ if qty <= 0 {
+ return Pathname::new(&path_self).to_any_object();
+ }
+ let mut result = String::new();
+
+ loop {
+ if qty == 0 { break; }
+
+ let item = args.pop();
+ result = plus::plus_paths(&anyobject_to_string(item).unwrap(), &result);
+ if result.chars().next() == Some(MAIN_SEPARATOR) {
+ return Pathname::new(&result).to_any_object()
+ }
+
+ qty -= 1;
+ }
+
+ let result = plus::plus_paths(&path_self, &result);
+
+ Pathname::new(&result).to_any_object()
+}
+
// pub fn pn_mkpath(pth: MaybeString) -> NilClass {
// NilClass::new()
// }
// pub fn pn_is_mountpoint(pth: MaybeString){}
// pub fn pn_parent(pth: MaybeString){}
-// also need impl +
pub fn pn_plus(pth1: MaybeString, pth2: MaybeString) -> RString {
RString::new(
&plus::plus_paths(
pth1.ok().unwrap_or(RString::new("")).to_str(),
pth2.ok().unwrap_or(RString::new("")).to_str()