Skip to content

Commit

Permalink
Create traits and implementations for std structs
Browse files Browse the repository at this point in the history
  • Loading branch information
dhruvkb committed Oct 23, 2023
1 parent c678099 commit 80dfe67
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 22 deletions.
12 changes: 12 additions & 0 deletions src/ext.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//! This module contains extensions to the standard library.
//!
//! The public interface of this module consists of the following traits:
//!
//! * [`Abs`]
//! * [`Ctime`]
mod abs;
mod ctime;

pub use abs::Abs;
pub use ctime::Ctime;
53 changes: 53 additions & 0 deletions src/ext/abs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//! This module provides a trait [`Abs`], that can be used to extend `Path` and
//! `PathBuf` with a method `abs` that converts a path to an absolute path.
use std::env::current_dir;
use std::path::{Path, PathBuf};

// =====
// Trait
// =====

/// This trait provides a method `abs` that can be used to convert a path
/// to an absolute path.
pub trait Abs {
/// Convert the given path to an absolute path.
///
/// This function is appends the path to the current working directory if it
/// is not already absolute and if the current working directory can be
/// determined. In all other cases, the path will be returned as-is.
fn abs(&self) -> PathBuf;
}

// ===============
// Implementations
// ===============

impl Abs for Path {
fn abs(&self) -> PathBuf {
abs(self)
}
}

impl Abs for PathBuf {
fn abs(&self) -> PathBuf {
abs(self)
}
}

// =======
// Private
// =======

fn abs<P>(path: P) -> PathBuf
where
P: AsRef<Path>,
{
let path = path.as_ref();
if !path.is_absolute() {
if let Ok(cwd) = current_dir() {
return cwd.join(path);
}
}
path.to_path_buf()
}
44 changes: 44 additions & 0 deletions src/ext/ctime.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//! This module provides a trait [`Ctime`], that can be used to extend
//! `Metadata` with a method `c_time` that provides the `st_ctime` of a node
//! with an API that matches the other timestamp fields.
use std::fs::Metadata;
use std::io::Result as IoResult;
#[cfg(unix)]
use std::os::unix::fs::MetadataExt;
use std::time::{Duration, SystemTime, UNIX_EPOCH};

// =====
// Trait
// =====

/// This trait provides a method `ctime` that provides the `st_ctime` of a node.
/// What this field represents depends on the operating system.
///
/// > On some systems (like Unix) is the time of the last metadata change, and,
/// > on others (like Windows), is the creation time.
/// >
/// > — [Python documentation](https://docs.python.org/3/library/stat.html#stat.ST_CTIME)
pub trait Ctime {
/// Compute the `st_ctime` of the node.
///
/// This function matches the signature of other timestamp fields:
///
/// * [`accessed`](Metadata::accessed)
/// * [`created`](Metadata::created)
/// * [`modified`](Metadata::modified)
fn c_time(&self) -> IoResult<SystemTime>;
}

// ===============
// Implementations
// ===============

impl Ctime for Metadata {
fn c_time(&self) -> IoResult<SystemTime> {
let sec = self.ctime();
let nanosec = self.ctime_nsec();
let ctime = UNIX_EPOCH + Duration::new(sec as u64, nanosec as u32);
Ok(ctime)
}
}
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mod config;
mod enums;
mod exc;
mod ext;
mod fmt;
mod models;
mod output;
Expand Down
24 changes: 2 additions & 22 deletions src/traits/detail.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
use crate::config::{Args, EntryConst};
use crate::enums::{DetailField, Typ};
use crate::ext::Ctime;
use crate::models::{Node, OwnerMan, Perm};
use std::io::{Error as IoError, Result as IoResult};
#[cfg(unix)]
use std::os::unix::fs::MetadataExt;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use std::time::SystemTime;
use time::{format_description, OffsetDateTime, UtcOffset};

pub trait Detail {
fn ctime(&self) -> IoResult<SystemTime>;

fn size_val(&self) -> Option<u64>;
fn blocks_val(&self) -> Option<u64>;
fn time_val(&self, field: DetailField) -> std::io::Result<SystemTime>;
Expand All @@ -31,24 +29,6 @@ pub trait Detail {
}

impl Detail for Node<'_> {
/// Compute the ctime of the node.
///
/// This function matches the signature of other timestamp fields such as
/// [`accessed`](std::fs::Metadata::accessed),
/// [`created`](std::fs::Metadata::created) and
/// [`modified`](std::fs::Metadata::modified).
fn ctime(&self) -> IoResult<SystemTime> {
match &self.meta {
Ok(meta) => {
let sec = meta.ctime();
let nanosec = meta.ctime_nsec();
let ctime = UNIX_EPOCH + Duration::new(sec as u64, nanosec as u32);
Ok(ctime)
}
Err(e) => Err(IoError::new(e.kind(), e.to_string())),
}
}

// ===========
// Sort fields
// ===========
Expand Down

0 comments on commit 80dfe67

Please sign in to comment.