mirror of
https://github.com/Llewellynvdm/exa.git
synced 2024-11-16 09:17:09 +00:00
Move all optional features into features module
This module provides feature-specific implementations, and also dummy implementations for when they aren't supported by the system or OS. Doing it this way limits all the #[cfg(feature)] annotations, as we can now just include the module or not.
This commit is contained in:
parent
697e1e66e4
commit
2ffa64cff6
105
src/dir.rs
105
src/dir.rs
@ -1,11 +1,9 @@
|
|||||||
use std::old_io::{fs, IoResult};
|
use std::old_io::{fs, IoResult};
|
||||||
use std::old_path::GenericPath;
|
use std::old_path::GenericPath;
|
||||||
use std::old_path::posix::Path;
|
use std::old_path::posix::Path;
|
||||||
use file::{File, GREY};
|
|
||||||
|
|
||||||
#[cfg(feature="git")] use ansi_term::{ANSIString, ANSIStrings};
|
use feature::Git;
|
||||||
#[cfg(feature="git")] use ansi_term::Colour::*;
|
use file::{File, GREY};
|
||||||
#[cfg(feature="git")] use git2;
|
|
||||||
|
|
||||||
/// A **Dir** provides a cached list of the file paths in a directory that's
|
/// A **Dir** provides a cached list of the file paths in a directory that's
|
||||||
/// being listed.
|
/// being listed.
|
||||||
@ -20,6 +18,7 @@ pub struct Dir {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Dir {
|
impl Dir {
|
||||||
|
|
||||||
/// Create a new Dir object filled with all the files in the directory
|
/// Create a new Dir object filled with all the files in the directory
|
||||||
/// pointed to by the given path. Fails if the directory can't be read, or
|
/// pointed to by the given path. Fails if the directory can't be read, or
|
||||||
/// isn't actually a directory.
|
/// isn't actually a directory.
|
||||||
@ -73,101 +72,3 @@ impl Dir {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Container of Git statuses for all the files in this folder's Git repository.
|
|
||||||
#[cfg(feature="git")]
|
|
||||||
struct Git {
|
|
||||||
statuses: Vec<(Path, git2::Status)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature="git")]
|
|
||||||
impl Git {
|
|
||||||
|
|
||||||
/// Discover a Git repository on or above this directory, scanning it for
|
|
||||||
/// the files' statuses if one is found.
|
|
||||||
fn scan(path: &Path) -> Result<Git, git2::Error> {
|
|
||||||
use std::os::unix::ffi::OsStrExt;
|
|
||||||
use std::ffi::AsOsStr;
|
|
||||||
|
|
||||||
// TODO: libgit2-rs uses the new Path module, but exa still uses the
|
|
||||||
// old_path one, and will have to continue to do so until the new IO
|
|
||||||
// module gets a bit more developed. So we have to turn Paths into
|
|
||||||
// old_path::Paths. Yes, this is hacky, but hopefully temporary.
|
|
||||||
let repo = try!(git2::Repository::discover(path));
|
|
||||||
let workdir = match repo.workdir() {
|
|
||||||
Some(w) => Path::new(w.as_os_str().as_bytes()),
|
|
||||||
None => return Ok(Git { statuses: vec![] }), // bare repo
|
|
||||||
};
|
|
||||||
|
|
||||||
let statuses = try!(repo.statuses(None)).iter()
|
|
||||||
.map(|e| (workdir.join(e.path_bytes()), e.status()))
|
|
||||||
.collect();
|
|
||||||
Ok(Git { statuses: statuses })
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the status for the file at the given path, if present.
|
|
||||||
fn status(&self, path: &Path) -> String {
|
|
||||||
let status = self.statuses.iter()
|
|
||||||
.find(|p| &p.0 == path);
|
|
||||||
match status {
|
|
||||||
Some(&(_, s)) => ANSIStrings( &[Git::index_status(s), Git::working_tree_status(s) ]).to_string(),
|
|
||||||
None => GREY.paint("--").to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the combined status for all the files whose paths begin with the
|
|
||||||
/// path that gets passed in. This is used for getting the status of
|
|
||||||
/// directories, which don't really have an 'official' status.
|
|
||||||
fn dir_status(&self, dir: &Path) -> String {
|
|
||||||
let s = self.statuses.iter()
|
|
||||||
.filter(|p| dir.is_ancestor_of(&p.0))
|
|
||||||
.fold(git2::Status::empty(), |a, b| a | b.1);
|
|
||||||
|
|
||||||
ANSIStrings( &[Git::index_status(s), Git::working_tree_status(s)] ).to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The character to display if the file has been modified, but not staged.
|
|
||||||
fn working_tree_status(status: git2::Status) -> ANSIString<'static> {
|
|
||||||
match status {
|
|
||||||
s if s.contains(git2::STATUS_WT_NEW) => Green.paint("A"),
|
|
||||||
s if s.contains(git2::STATUS_WT_MODIFIED) => Blue.paint("M"),
|
|
||||||
s if s.contains(git2::STATUS_WT_DELETED) => Red.paint("D"),
|
|
||||||
s if s.contains(git2::STATUS_WT_RENAMED) => Yellow.paint("R"),
|
|
||||||
s if s.contains(git2::STATUS_WT_TYPECHANGE) => Purple.paint("T"),
|
|
||||||
_ => GREY.paint("-"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The character to display if the file has been modified, and the change
|
|
||||||
/// has been staged.
|
|
||||||
fn index_status(status: git2::Status) -> ANSIString<'static> {
|
|
||||||
match status {
|
|
||||||
s if s.contains(git2::STATUS_INDEX_NEW) => Green.paint("A"),
|
|
||||||
s if s.contains(git2::STATUS_INDEX_MODIFIED) => Blue.paint("M"),
|
|
||||||
s if s.contains(git2::STATUS_INDEX_DELETED) => Red.paint("D"),
|
|
||||||
s if s.contains(git2::STATUS_INDEX_RENAMED) => Yellow.paint("R"),
|
|
||||||
s if s.contains(git2::STATUS_INDEX_TYPECHANGE) => Purple.paint("T"),
|
|
||||||
_ => GREY.paint("-"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature="git"))]
|
|
||||||
struct Git;
|
|
||||||
|
|
||||||
#[cfg(not(feature="git"))]
|
|
||||||
impl Git {
|
|
||||||
fn scan(_: &Path) -> Result<Git, ()> {
|
|
||||||
// Don't do anything without Git support
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn status(&self, _: &Path) -> String {
|
|
||||||
// The Err above means that this should never happen
|
|
||||||
panic!("Tried to access a Git repo without Git support!");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dir_status(&self, path: &Path) -> String {
|
|
||||||
self.status(path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
85
src/feature/git.rs
Normal file
85
src/feature/git.rs
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
use std::old_path::GenericPath;
|
||||||
|
use std::old_path::posix::Path;
|
||||||
|
|
||||||
|
use ansi_term::{ANSIString, ANSIStrings};
|
||||||
|
use ansi_term::Colour::*;
|
||||||
|
use git2;
|
||||||
|
|
||||||
|
use file::GREY;
|
||||||
|
|
||||||
|
/// Container of Git statuses for all the files in this folder's Git repository.
|
||||||
|
pub struct Git {
|
||||||
|
statuses: Vec<(Path, git2::Status)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Git {
|
||||||
|
|
||||||
|
/// Discover a Git repository on or above this directory, scanning it for
|
||||||
|
/// the files' statuses if one is found.
|
||||||
|
pub fn scan(path: &Path) -> Result<Git, git2::Error> {
|
||||||
|
use std::os::unix::ffi::OsStrExt;
|
||||||
|
use std::ffi::AsOsStr;
|
||||||
|
|
||||||
|
// TODO: libgit2-rs uses the new Path module, but exa still uses the
|
||||||
|
// old_path one, and will have to continue to do so until the new IO
|
||||||
|
// module gets a bit more developed. So we have to turn Paths into
|
||||||
|
// old_path::Paths. Yes, this is hacky, but hopefully temporary.
|
||||||
|
let new_path = path.as_os_str();
|
||||||
|
let repo = try!(git2::Repository::discover(new_path));
|
||||||
|
let workdir = match repo.workdir() {
|
||||||
|
Some(w) => Path::new(w.as_os_str().as_bytes()),
|
||||||
|
None => return Ok(Git { statuses: vec![] }), // bare repo
|
||||||
|
};
|
||||||
|
|
||||||
|
let statuses = try!(repo.statuses(None)).iter()
|
||||||
|
.map(|e| (workdir.join(e.path_bytes()), e.status()))
|
||||||
|
.collect();
|
||||||
|
Ok(Git { statuses: statuses })
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the status for the file at the given path, if present.
|
||||||
|
pub fn status(&self, path: &Path) -> String {
|
||||||
|
let status = self.statuses.iter()
|
||||||
|
.find(|p| &p.0 == path);
|
||||||
|
match status {
|
||||||
|
Some(&(_, s)) => ANSIStrings( &[Git::index_status(s), Git::working_tree_status(s) ]).to_string(),
|
||||||
|
None => GREY.paint("--").to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the combined status for all the files whose paths begin with the
|
||||||
|
/// path that gets passed in. This is used for getting the status of
|
||||||
|
/// directories, which don't really have an 'official' status.
|
||||||
|
pub fn dir_status(&self, dir: &Path) -> String {
|
||||||
|
let s = self.statuses.iter()
|
||||||
|
.filter(|p| dir.is_ancestor_of(&p.0))
|
||||||
|
.fold(git2::Status::empty(), |a, b| a | b.1);
|
||||||
|
|
||||||
|
ANSIStrings( &[Git::index_status(s), Git::working_tree_status(s)] ).to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The character to display if the file has been modified, but not staged.
|
||||||
|
fn working_tree_status(status: git2::Status) -> ANSIString<'static> {
|
||||||
|
match status {
|
||||||
|
s if s.contains(git2::STATUS_WT_NEW) => Green.paint("A"),
|
||||||
|
s if s.contains(git2::STATUS_WT_MODIFIED) => Blue.paint("M"),
|
||||||
|
s if s.contains(git2::STATUS_WT_DELETED) => Red.paint("D"),
|
||||||
|
s if s.contains(git2::STATUS_WT_RENAMED) => Yellow.paint("R"),
|
||||||
|
s if s.contains(git2::STATUS_WT_TYPECHANGE) => Purple.paint("T"),
|
||||||
|
_ => GREY.paint("-"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The character to display if the file has been modified, and the change
|
||||||
|
/// has been staged.
|
||||||
|
fn index_status(status: git2::Status) -> ANSIString<'static> {
|
||||||
|
match status {
|
||||||
|
s if s.contains(git2::STATUS_INDEX_NEW) => Green.paint("A"),
|
||||||
|
s if s.contains(git2::STATUS_INDEX_MODIFIED) => Blue.paint("M"),
|
||||||
|
s if s.contains(git2::STATUS_INDEX_DELETED) => Red.paint("D"),
|
||||||
|
s if s.contains(git2::STATUS_INDEX_RENAMED) => Yellow.paint("R"),
|
||||||
|
s if s.contains(git2::STATUS_INDEX_TYPECHANGE) => Purple.paint("T"),
|
||||||
|
_ => GREY.paint("-"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
62
src/feature/mod.rs
Normal file
62
src/feature/mod.rs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
// Extended attribute support
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")] mod xattr_darwin;
|
||||||
|
#[cfg(target_os = "macos")] pub use self::xattr_darwin::Attribute;
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")] mod xattr_linux;
|
||||||
|
#[cfg(target_os = "linux")] pub use self::xattr_linux::Attribute;
|
||||||
|
|
||||||
|
#[cfg(not(any(target_os = "macos", target_os = "linux")))] use std::old_io as io;
|
||||||
|
#[cfg(not(any(target_os = "macos", target_os = "linux")))]
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Attribute;
|
||||||
|
|
||||||
|
#[cfg(not(any(target_os = "macos", target_os = "linux")))]
|
||||||
|
impl Attribute {
|
||||||
|
|
||||||
|
/// Getter for name
|
||||||
|
pub fn name(&self) -> &str {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Getter for size
|
||||||
|
pub fn size(&self) -> usize {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Lists the extended attributes. Follows symlinks like `stat`
|
||||||
|
pub fn list(_: &Path) -> io::IoResult<Vec<Attribute>> {
|
||||||
|
Ok(Vec::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Lists the extended attributes. Does not follow symlinks like `lstat`
|
||||||
|
pub fn llist(_: &Path) -> io::IoResult<Vec<Attribute>> {
|
||||||
|
Ok(Vec::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn feature_implemented() -> bool { false }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Git support
|
||||||
|
|
||||||
|
#[cfg(feature="git")] mod git;
|
||||||
|
#[cfg(feature="git")] pub use self::git::Git;
|
||||||
|
|
||||||
|
#[cfg(not(feature="git"))] pub struct Git;
|
||||||
|
#[cfg(not(feature="git"))] use std::old_path::posix::Path;
|
||||||
|
#[cfg(not(feature="git"))]
|
||||||
|
impl Git {
|
||||||
|
pub fn scan(_: &Path) -> Result<Git, ()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn status(&self, _: &Path) -> String {
|
||||||
|
panic!("Tried to access a Git repo without Git support!");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn dir_status(&self, path: &Path) -> String {
|
||||||
|
self.status(path)
|
||||||
|
}
|
||||||
|
}
|
@ -41,7 +41,7 @@ pub struct Attribute {
|
|||||||
impl Attribute {
|
impl Attribute {
|
||||||
/// Lists the extended attribute of `path`.
|
/// Lists the extended attribute of `path`.
|
||||||
/// Does follow symlinks by default.
|
/// Does follow symlinks by default.
|
||||||
pub fn list(path: &Path, flags: &[ListFlags]) -> io::IoResult<Vec<Attribute>> {
|
pub fn list_attrs(path: &Path, flags: &[ListFlags]) -> io::IoResult<Vec<Attribute>> {
|
||||||
let mut c_flags: c_int = 0;
|
let mut c_flags: c_int = 0;
|
||||||
for &flag in flags.iter() {
|
for &flag in flags.iter() {
|
||||||
c_flags |= flag as c_int
|
c_flags |= flag as c_int
|
||||||
@ -112,19 +112,20 @@ impl Attribute {
|
|||||||
pub fn size(&self) -> usize {
|
pub fn size(&self) -> usize {
|
||||||
self.size
|
self.size
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Lists the extended attributes.
|
/// Lists the extended attributes.
|
||||||
/// Follows symlinks like `stat`
|
/// Follows symlinks like `stat`
|
||||||
pub fn list(path: &Path) -> io::IoResult<Vec<Attribute>> {
|
pub fn list(path: &Path) -> io::IoResult<Vec<Attribute>> {
|
||||||
Attribute::list(path, &[])
|
Attribute::list_attrs(path, &[])
|
||||||
}
|
}
|
||||||
/// Lists the extended attributes.
|
/// Lists the extended attributes.
|
||||||
/// Does not follow symlinks like `lstat`
|
/// Does not follow symlinks like `lstat`
|
||||||
pub fn llist(path: &Path) -> io::IoResult<Vec<Attribute>> {
|
pub fn llist(path: &Path) -> io::IoResult<Vec<Attribute>> {
|
||||||
Attribute::list(path, &[ListFlags::NoFollow])
|
Attribute::list_attrs(path, &[ListFlags::NoFollow])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the extended attribute feature is implemented on this platform.
|
/// Returns true if the extended attribute feature is implemented on this platform.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn feature_implemented() -> bool { true }
|
pub fn feature_implemented() -> bool { true }
|
||||||
|
}
|
||||||
|
|
@ -36,7 +36,7 @@ pub struct Attribute {
|
|||||||
impl Attribute {
|
impl Attribute {
|
||||||
/// Lists the extended attribute of `path`.
|
/// Lists the extended attribute of `path`.
|
||||||
/// Does follow symlinks by default.
|
/// Does follow symlinks by default.
|
||||||
pub fn list(path: &Path, do_follow: FollowSymlinks) -> io::IoResult<Vec<Attribute>> {
|
pub fn list_attrs(path: &Path, do_follow: FollowSymlinks) -> io::IoResult<Vec<Attribute>> {
|
||||||
let (listxattr, getxattr) = match do_follow {
|
let (listxattr, getxattr) = match do_follow {
|
||||||
FollowSymlinks::Yes => (listxattr, getxattr),
|
FollowSymlinks::Yes => (listxattr, getxattr),
|
||||||
FollowSymlinks::No => (llistxattr, lgetxattr),
|
FollowSymlinks::No => (llistxattr, lgetxattr),
|
||||||
@ -103,19 +103,19 @@ impl Attribute {
|
|||||||
pub fn size(&self) -> usize {
|
pub fn size(&self) -> usize {
|
||||||
self.size
|
self.size
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Lists the extended attributes.
|
/// Lists the extended attributes.
|
||||||
/// Follows symlinks like `stat`
|
/// Follows symlinks like `stat`
|
||||||
pub fn list(path: &Path) -> io::IoResult<Vec<Attribute>> {
|
pub fn list(path: &Path) -> io::IoResult<Vec<Attribute>> {
|
||||||
Attribute::list(path, FollowSymlinks::Yes)
|
Attribute::list_attrs(path, FollowSymlinks::Yes)
|
||||||
}
|
}
|
||||||
/// Lists the extended attributes.
|
/// Lists the extended attributes.
|
||||||
/// Does not follow symlinks like `lstat`
|
/// Does not follow symlinks like `lstat`
|
||||||
pub fn llist(path: &Path) -> io::IoResult<Vec<Attribute>> {
|
pub fn llist(path: &Path) -> io::IoResult<Vec<Attribute>> {
|
||||||
Attribute::list(path, FollowSymlinks::No)
|
Attribute::list_attrs(path, FollowSymlinks::No)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the extended attribute feature is implemented on this platform.
|
/// Returns true if the extended attribute feature is implemented on this platform.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn feature_implemented() -> bool { true }
|
pub fn feature_implemented() -> bool { true }
|
||||||
|
}
|
@ -31,11 +31,10 @@ use column::Column::*;
|
|||||||
use dir::Dir;
|
use dir::Dir;
|
||||||
use filetype::HasType;
|
use filetype::HasType;
|
||||||
use options::{SizeFormat, TimeType};
|
use options::{SizeFormat, TimeType};
|
||||||
use xattr;
|
use feature::Attribute;
|
||||||
use xattr::Attribute;
|
|
||||||
|
|
||||||
/// This grey value is directly in between white and black, so it's guaranteed
|
/// This grey value is directly in between white and black, so it's guaranteed
|
||||||
/// to show up on either backgrounded terminal.
|
/// to show up on either backg"#160909"rounded terminal.
|
||||||
pub static GREY: Colour = Fixed(244);
|
pub static GREY: Colour = Fixed(244);
|
||||||
|
|
||||||
/// A **File** is a wrapper around one of Rust's Path objects, along with
|
/// A **File** is a wrapper around one of Rust's Path objects, along with
|
||||||
@ -83,7 +82,7 @@ impl<'a> File<'a> {
|
|||||||
dir: parent,
|
dir: parent,
|
||||||
stat: stat,
|
stat: stat,
|
||||||
ext: ext(&filename),
|
ext: ext(&filename),
|
||||||
xattrs: xattr::llist(path).unwrap_or(Vec::new()),
|
xattrs: Attribute::llist(path).unwrap_or(Vec::new()),
|
||||||
name: filename.to_string(),
|
name: filename.to_string(),
|
||||||
this: this,
|
this: this,
|
||||||
}
|
}
|
||||||
@ -227,7 +226,7 @@ impl<'a> File<'a> {
|
|||||||
dir: self.dir,
|
dir: self.dir,
|
||||||
stat: stat,
|
stat: stat,
|
||||||
ext: ext(&filename),
|
ext: ext(&filename),
|
||||||
xattrs: xattr::list(target_path).unwrap_or(Vec::new()),
|
xattrs: Attribute::list(target_path).unwrap_or(Vec::new()),
|
||||||
name: filename.to_string(),
|
name: filename.to_string(),
|
||||||
this: None,
|
this: None,
|
||||||
})
|
})
|
||||||
|
@ -33,12 +33,12 @@ use output::lines_view;
|
|||||||
|
|
||||||
pub mod column;
|
pub mod column;
|
||||||
pub mod dir;
|
pub mod dir;
|
||||||
|
pub mod feature;
|
||||||
pub mod file;
|
pub mod file;
|
||||||
pub mod filetype;
|
pub mod filetype;
|
||||||
pub mod options;
|
pub mod options;
|
||||||
pub mod output;
|
pub mod output;
|
||||||
pub mod term;
|
pub mod term;
|
||||||
pub mod xattr;
|
|
||||||
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
struct Exa<'a> {
|
struct Exa<'a> {
|
||||||
|
@ -2,9 +2,9 @@ use dir::Dir;
|
|||||||
use file::File;
|
use file::File;
|
||||||
use column::Column;
|
use column::Column;
|
||||||
use column::Column::*;
|
use column::Column::*;
|
||||||
|
use feature::Attribute;
|
||||||
use output::{Grid, Details};
|
use output::{Grid, Details};
|
||||||
use term::dimensions;
|
use term::dimensions;
|
||||||
use xattr;
|
|
||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -76,7 +76,7 @@ impl Options {
|
|||||||
opts.optflag("", "git", "show git status");
|
opts.optflag("", "git", "show git status");
|
||||||
}
|
}
|
||||||
|
|
||||||
if xattr::feature_implemented() {
|
if Attribute::feature_implemented() {
|
||||||
opts.optflag("@", "extended", "display extended attribute keys and sizes in long (-l) output");
|
opts.optflag("@", "extended", "display extended attribute keys and sizes in long (-l) output");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,7 +255,7 @@ impl View {
|
|||||||
columns: try!(Columns::deduce(matches)),
|
columns: try!(Columns::deduce(matches)),
|
||||||
header: matches.opt_present("header"),
|
header: matches.opt_present("header"),
|
||||||
recurse: dir_action.recurse_options().map(|o| (o, filter)),
|
recurse: dir_action.recurse_options().map(|o| (o, filter)),
|
||||||
xattr: xattr::feature_implemented() && matches.opt_present("extended"),
|
xattr: Attribute::feature_implemented() && matches.opt_present("extended"),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(View::Details(details))
|
Ok(View::Details(details))
|
||||||
@ -294,7 +294,7 @@ impl View {
|
|||||||
else if matches.opt_present("level") && !matches.opt_present("recurse") {
|
else if matches.opt_present("level") && !matches.opt_present("recurse") {
|
||||||
Err(Misfire::Useless2("level", "recurse", "tree"))
|
Err(Misfire::Useless2("level", "recurse", "tree"))
|
||||||
}
|
}
|
||||||
else if xattr::feature_implemented() && matches.opt_present("extended") {
|
else if Attribute::feature_implemented() && matches.opt_present("extended") {
|
||||||
Err(Misfire::Useless("extended", false, "long"))
|
Err(Misfire::Useless("extended", false, "long"))
|
||||||
}
|
}
|
||||||
else if matches.opt_present("oneline") {
|
else if matches.opt_present("oneline") {
|
||||||
@ -572,7 +572,7 @@ mod test {
|
|||||||
use super::Options;
|
use super::Options;
|
||||||
use super::Misfire;
|
use super::Misfire;
|
||||||
use super::Misfire::*;
|
use super::Misfire::*;
|
||||||
use xattr;
|
use feature::Attribute;
|
||||||
|
|
||||||
fn is_helpful<T>(misfire: Result<T, Misfire>) -> bool {
|
fn is_helpful<T>(misfire: Result<T, Misfire>) -> bool {
|
||||||
match misfire {
|
match misfire {
|
||||||
@ -674,7 +674,7 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn extended_without_long() {
|
fn extended_without_long() {
|
||||||
if xattr::feature_implemented() {
|
if Attribute::feature_implemented() {
|
||||||
let opts = Options::getopts(&[ "--extended".to_string() ]);
|
let opts = Options::getopts(&[ "--extended".to_string() ]);
|
||||||
assert_eq!(opts.unwrap_err(), Misfire::Useless("extended", false, "long"))
|
assert_eq!(opts.unwrap_err(), Misfire::Useless("extended", false, "long"))
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use column::{Alignment, Column, Cell};
|
use column::{Alignment, Column, Cell};
|
||||||
use xattr::Attribute;
|
use feature::Attribute;
|
||||||
use dir::Dir;
|
use dir::Dir;
|
||||||
use file::{File, GREY};
|
use file::{File, GREY};
|
||||||
use options::{Columns, FileFilter, RecurseOptions};
|
use options::{Columns, FileFilter, RecurseOptions};
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
//! Extended attribute support
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
mod xattr_darwin;
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
pub use self::xattr_darwin::*;
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
mod xattr_linux;
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
pub use self::xattr_linux::*;
|
|
||||||
#[cfg(not(any(target_os = "macos", target_os = "linux")))]
|
|
||||||
mod xattr_other;
|
|
||||||
#[cfg(not(any(target_os = "macos", target_os = "linux")))]
|
|
||||||
pub use self::xattr_other::*;
|
|
@ -1,32 +0,0 @@
|
|||||||
//! Extended attribute support for other os
|
|
||||||
use std::old_io as io;
|
|
||||||
|
|
||||||
/// Extended attribute
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct Attribute;
|
|
||||||
|
|
||||||
impl Attribute {
|
|
||||||
|
|
||||||
/// Getter for name
|
|
||||||
pub fn name(&self) -> &str {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Getter for size
|
|
||||||
pub fn size(&self) -> usize {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Lists the extended attributes. Follows symlinks like `stat`
|
|
||||||
pub fn list(_: &Path) -> io::IoResult<Vec<Attribute>> {
|
|
||||||
Ok(Vec::new())
|
|
||||||
}
|
|
||||||
/// Lists the extended attributes. Does not follow symlinks like `lstat`
|
|
||||||
pub fn llist(_: &Path) -> io::IoResult<Vec<Attribute>> {
|
|
||||||
Ok(Vec::new())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if the extended attribute feature is implemented on this platform.
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn feature_implemented() -> bool { false }
|
|
Loading…
Reference in New Issue
Block a user