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()