src/pathname.rs in faster_path-0.3.7 vs src/pathname.rs in faster_path-0.3.8
- old
+ new
@@ -6,12 +6,13 @@
use dirname;
use extname;
use plus;
use relative_path_from;
use debug;
-use helpers::TryFrom;
+use helpers::{TryFrom, to_str};
use pathname_sys::null_byte_check;
+use path_parsing::{SEP, find_last_non_sep_pos};
use ruru;
use ruru::{
RString,
Boolean,
@@ -38,11 +39,11 @@
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 new_checked(path: AnyObject) -> Result<Pathname, Exception> {
let pth: Value = if Class::from_existing("String").case_equals(&path) {
@@ -56,18 +57,18 @@
Some("The type for the argument provided to Pathname.new was invalid.")
)
)
};
- if null_byte_check(path.value()) {
+ if null_byte_check(path.value()) {
return Err( Exception::new("ArgumentError", Some("pathname contains null byte")) )
}
// if it crashes then dup the path string here before assigning to @path
let mut instance = Class::from_existing("Pathname").allocate();
instance.instance_variable_set("@path", RString::from(pth).to_any_object());
-
+
Ok(Pathname { value: instance.value() })
}
pub fn to_any_object(&self) -> AnyObject {
AnyObject::from(self.value())
@@ -82,15 +83,15 @@
impl TryFrom<AnyObject> for Pathname {
type Error = debug::RubyDebugInfo;
fn try_from(obj: AnyObject) -> Result<Pathname, Self::Error> {
if Class::from_existing("String").case_equals(&obj) {
- Ok(Pathname::new(&RString::from(obj.value()).to_string()))
+ Ok(Pathname::new(&RString::from(obj.value()).to_str()))
} else if Class::from_existing("Pathname").case_equals(&obj) {
Ok(Pathname::from(obj.value()))
} else if obj.respond_to("to_path") {
- Ok(Pathname::from(obj.send("to_path", None).value()))
+ Ok(Pathname::new(&RString::from(obj.send("to_path", None).value()).to_str()))
} else {
Err(Self::Error::from(obj))
}
}
}
@@ -112,47 +113,39 @@
"Error converting to Pathname"
}
}
pub fn pn_add_trailing_separator(pth: MaybeString) -> RString {
- let p = pth.ok().unwrap();
+ let p = pth.unwrap();
let x = format!("{}{}", p.to_str(), "a");
match x.rsplit_terminator(MAIN_SEPARATOR).next() {
Some("a") => p,
_ => RString::new(format!("{}{}", p.to_str(), MAIN_SEPARATOR).as_str())
}
}
pub fn pn_is_absolute(pth: MaybeString) -> Boolean {
- Boolean::new(match pth.ok().unwrap_or(RString::new("")).to_str().chars().next() {
- Some(c) => c == MAIN_SEPARATOR,
- None => false
- })
+ Boolean::new(to_str(&pth).as_bytes().get(0) == Some(&SEP))
}
// pub fn pn_ascend(){}
pub fn pn_basename(pth: MaybeString, ext: MaybeString) -> RString {
- RString::new(
- basename::basename(
- pth.ok().unwrap_or(RString::new("")).to_str(),
- ext.ok().unwrap_or(RString::new("")).to_str()
- )
- )
+ RString::new(basename::basename(to_str(&pth), to_str(&ext)))
}
-pub fn pn_children(pth: MaybeString, with_dir: MaybeBoolean) -> AnyObject {
- let val = pth.ok().unwrap_or(RString::new("."));
- let val = val.to_str();
+pub fn pn_children(pth: MaybeString, with_dir: MaybeBoolean) -> Result<AnyObject, Exception> {
+ let path = pth.unwrap_or(RString::new("."));
+ let path = path.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 == "." {
+ if let Ok(entries) = fs::read_dir(path) {
+ let mut with_directory = with_dir.unwrap_or(Boolean::new(true)).to_bool();
+ if path == "." {
with_directory = false;
}
- let mut arr = Array::new();
+ let mut arr = Array::with_capacity(entries.size_hint().1.unwrap_or(0));
for entry in entries {
if with_directory {
match entry {
Ok(v) => { arr.push(RString::new(v.path().to_str().unwrap())); },
_ => {}
@@ -163,29 +156,27 @@
_ => {}
};
}
}
- arr.to_any_object()
+ Ok(arr.to_any_object())
} else {
- // TODO: When ruru exceptions are available switch the exception logic
- // from the Ruby side to the Rust side
- NilClass::new().to_any_object()
+ let msg = format!("No such file or directory @ dir_initialize - {}", path);
+ Err(Exception::new("Errno::NOENT", Some(&msg)))
}
}
-pub fn pn_children_compat(pth: MaybeString, with_dir: MaybeBoolean) -> AnyObject {
- let val = pth.ok().unwrap_or(RString::new("."));
- let val = val.to_str();
+pub fn pn_children_compat(pth: MaybeString, with_dir: MaybeBoolean) -> Result<AnyObject, Exception> {
+ let path = to_str(&pth);
- if let Ok(entries) = fs::read_dir(val) {
- let mut with_directory = with_dir.ok().unwrap_or(Boolean::new(true)).to_bool();
- if val == "." {
+ if let Ok(entries) = fs::read_dir(path) {
+ let mut with_directory = with_dir.unwrap_or(Boolean::new(true)).to_bool();
+ if path == "." {
with_directory = false;
}
- let mut arr = Array::new();
+ let mut arr = Array::with_capacity(entries.size_hint().1.unwrap_or(0));
for entry in entries {
if with_directory {
if let Ok(v) = entry {
arr.push(Pathname::new(v.path().to_str().unwrap()));
};
@@ -194,148 +185,120 @@
arr.push(Pathname::new(v.file_name().to_str().unwrap()));
};
}
}
- arr.to_any_object()
+ Ok(arr.to_any_object())
} else {
- // TODO: When ruru exceptions are available switch the exception logic
- // from the Ruby side to the Rust side
- NilClass::new().to_any_object()
+ let msg = format!("No such file or directory @ dir_initialize - {}", path);
+ Err(Exception::new("Errno::NOENT", Some(&msg)))
}
}
-pub fn pn_chop_basename(pth: MaybeString) -> Array {
- let mut arr = Array::with_capacity(2);
- let pth = pth.ok().unwrap_or(RString::new(""));
- let results = chop_basename::chop_basename(pth.to_str());
- match results {
+pub fn pn_chop_basename(pth: MaybeString) -> AnyObject {
+ match chop_basename::chop_basename(to_str(&pth)) {
Some((dirname, basename)) => {
- arr.push(RString::new(&dirname[..]));
- arr.push(RString::new(&basename[..]));
- arr
+ let mut arr = Array::with_capacity(2);
+ arr.push(RString::new(&dirname));
+ arr.push(RString::new(&basename));
+ arr.to_any_object()
},
- None => arr
+ None => NilClass::new().to_any_object()
}
}
// pub fn pn_cleanpath(pth: MaybeString){}
pub fn pn_cleanpath_aggressive(pth: MaybeString) -> RString {
- let path = cleanpath_aggressive::cleanpath_aggressive(
- pth.ok().unwrap_or(RString::new("")).to_str()
- );
-
- RString::new(&path)
+ RString::new(&cleanpath_aggressive::cleanpath_aggressive(to_str(&pth)))
}
pub fn pn_cleanpath_conservative(pth: MaybeString) -> RString {
- let path = cleanpath_conservative::cleanpath_conservative(
- pth.ok().unwrap_or(RString::new("")).to_str()
- );
-
- RString::new(&path)
+ RString::new(&cleanpath_conservative::cleanpath_conservative(to_str(&pth)))
}
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);
- }
+ {
+ let path = to_str(&pth);
+ if path.is_empty() {
+ return RString::new("/");
}
- } else {
- return RString::new("");
+ let pos = match find_last_non_sep_pos(path.as_bytes()) {
+ Some(pos) => pos,
+ None => return RString::new("/"),
+ };
+ if pos != path.len() - 1 {
+ return RString::new(&path[..pos + 1]);
+ }
}
-
pth.unwrap()
}
// pub fn pn_descend(){}
pub fn pn_is_directory(pth: MaybeString) -> Boolean {
- Boolean::new(
- Path::new(
- pth.ok().unwrap_or(RString::new("")).to_str()
- ).is_dir()
- )
+ Boolean::new(Path::new(to_str(&pth)).is_dir())
}
pub fn pn_dirname(pth: MaybeString) -> RString {
- RString::new(
- dirname::dirname(
- pth.ok().unwrap_or(RString::new("")).to_str()
- )
- )
+ RString::new(dirname::dirname(to_str(&pth)))
}
// pub fn pn_each_child(){}
// pub fn pn_each_filename(pth: MaybeString) -> NilClass {
// NilClass::new()
// }
-pub fn pn_entries(pth: MaybeString) -> AnyObject {
- if let Ok(files) = fs::read_dir(pth.ok().unwrap_or(RString::new("")).to_str()) {
- let mut arr = Array::new();
+pub fn pn_entries(pth: MaybeString) -> Result<AnyObject, Exception> {
+ let path = to_str(&pth);
+ if let Ok(files) = fs::read_dir(path) {
+ let mut arr = Array::with_capacity(files.size_hint().1.unwrap_or(0) + 2);
arr.push(RString::new("."));
arr.push(RString::new(".."));
for file in files {
- let file_name_str = file.unwrap().file_name().into_string().unwrap();
- arr.push(RString::new(&file_name_str[..]));
+ arr.push(RString::new(file.unwrap().file_name().to_str().unwrap()));
}
- arr.to_any_object()
+ Ok(arr.to_any_object())
} else {
- // TODO: When ruru exceptions are available switch the exception logic
- // from the Ruby side to the Rust side
- NilClass::new().to_any_object()
+ let msg = format!("No such file or directory @ dir_initialize - {}", path);
+ Err(Exception::new("Errno::NOENT", Some(&msg)))
}
}
-pub fn pn_entries_compat(pth: MaybeString) -> AnyObject {
- if let Ok(files) = fs::read_dir(pth.ok().unwrap_or(RString::new("")).to_str()) {
- let mut arr = Array::new();
+pub fn pn_entries_compat(pth: MaybeString) -> Result<AnyObject, Exception> {
+ let path = to_str(&pth);
+ if let Ok(files) = fs::read_dir(path) {
+ let mut arr = Array::with_capacity(files.size_hint().1.unwrap_or(0) + 2);
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(Pathname::new(&file_name_str));
+ arr.push(Pathname::new(file.unwrap().file_name().to_str().unwrap()));
}
- arr.to_any_object()
+ Ok(arr.to_any_object())
} else {
- // TODO: When ruru exceptions are available switch the exception logic
- // from the Ruby side to the Rust side
- NilClass::new().to_any_object()
+ let msg = format!("No such file or directory @ dir_initialize - {}", path);
+ Err(Exception::new("Errno::NOENT", Some(&msg)))
}
}
pub fn pn_extname(pth: MaybeString) -> RString {
- RString::new(
- extname::extname(pth.ok().unwrap_or(RString::new("")).to_str())
- )
+ RString::new(extname::extname(to_str(&pth)))
}
// 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)) => {
- Boolean::new(a.len() + b.len() < v.to_str().len())
- },
+ let v = to_str(&pth);
+ match chop_basename::chop_basename(v) {
+ Some((a,b)) => Boolean::new(a.len() + b.len() < v.len()),
_ => Boolean::new(false)
}
}
pub fn pn_join(args: MaybeArray) -> AnyObject {
@@ -351,17 +314,17 @@
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) {
+ if result.as_bytes().get(0) == Some(&SEP) {
return Pathname::new(&result).to_any_object()
}
qty -= 1;
}
-
+
let result = plus::plus_paths(&path_self, &result);
Pathname::new(&result).to_any_object()
}
@@ -372,26 +335,20 @@
// pub fn pn_is_mountpoint(pth: MaybeString){}
// pub fn pn_parent(pth: MaybeString){}
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()
- )[..]
- )
+ RString::new(&plus::plus_paths(to_str(&pth1), to_str(&pth2)))
}
// pub fn pn_prepend_prefix(prefix: MaybeString, relpath: MaybeString){}
pub fn pn_is_relative(pth: MaybeString) -> Boolean {
- Boolean::new(
- match pth.ok().unwrap_or(RString::new(&MAIN_SEPARATOR.to_string()[..])).to_str().chars().next() {
- Some(c) => c != MAIN_SEPARATOR,
- None => true
- }
- )
+ let path = match &pth {
+ &Ok(ref ruru_string) => ruru_string.to_str(),
+ &Err(_) => return Boolean::new(false),
+ };
+ Boolean::new(path.as_bytes().get(0) != Some(&SEP))
}
// pub fn pn_root(pth: MaybeString){}
// pub fn pn_split_names(pth: MaybeString){}