diff --git a/Cargo.toml b/Cargo.toml index a9eb02e..76150d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,10 @@ name = "rfat" version = "0.1.0" authors = ["Rafał Harabień "] +[features] +default = ["chrono"] + [dependencies] byteorder = "1" bitflags = "1.0" -chrono = "0.4" +chrono = { version = "0.4", optional = true } diff --git a/examples/ls.rs b/examples/ls.rs index 0d95307..f5f2ede 100644 --- a/examples/ls.rs +++ b/examples/ls.rs @@ -1,9 +1,11 @@ extern crate rfat; +extern crate chrono; use std::env; use std::fs::File; use std::io::BufReader; use std::str; +use chrono::{DateTime, Local}; use rfat::FatFileSystem; @@ -34,7 +36,7 @@ fn main() { }; for r in dir.iter() { let e = r.unwrap(); - let modified = e.modified().format("%Y-%m-%d %H:%M:%S").to_string(); + let modified = DateTime::::from(e.modified()).format("%Y-%m-%d %H:%M:%S").to_string(); println!("{:4} {} {}", format_file_size(e.len()), modified, e.file_name()); } } diff --git a/src/dir.rs b/src/dir.rs index 25f4c9a..1d9d21e 100644 --- a/src/dir.rs +++ b/src/dir.rs @@ -4,6 +4,8 @@ use std::io::prelude::*; use std::io; use std::io::{Cursor, ErrorKind, SeekFrom}; use byteorder::{LittleEndian, ReadBytesExt}; + +#[cfg(feature = "chrono")] use chrono::{DateTime, Date, TimeZone, Local}; use fs::{FatFileSystemRef, FatSlice}; @@ -90,6 +92,61 @@ pub struct FatDirEntry<'a, 'b: 'a> { fs: FatFileSystemRef<'a, 'b>, } +pub struct DosDate { + pub year: u16, + pub month: u16, + pub day: u16, +} + +pub struct DosTime { + pub hour: u16, + pub min: u16, + pub sec: u16, +} + +pub struct DosDateTime { + pub date: DosDate, + pub time: DosTime, +} + +impl DosDate { + pub(crate) fn from_word(dos_date: u16) -> Self { + let (year, month, day) = ((dos_date >> 9) + 1980, (dos_date >> 5) & 0xF, dos_date & 0x1F); + DosDate { year, month, day } + } +} + +impl DosTime { + pub(crate) fn from_word(dos_time: u16) -> Self { + let (hour, min, sec) = (dos_time >> 11, (dos_time >> 5) & 0x3F, (dos_time & 0x1F) * 2); + DosTime { hour, min, sec } + } +} + +impl DosDateTime { + pub(crate) fn from_words(dos_date: u16, dos_time: u16) -> Self { + DosDateTime { + date: DosDate::from_word(dos_date), + time: DosTime::from_word(dos_time), + } + } +} + +#[cfg(feature = "chrono")] +impl From for Date { + fn from(date: DosDate) -> Self { + Local.ymd(date.year as i32, date.month as u32, date.day as u32) + } +} + +#[cfg(feature = "chrono")] +impl From for DateTime { + fn from(date_time: DosDateTime) -> Self { + Date::::from(date_time.date) + .and_hms(date_time.time.hour as u32, date_time.time.min as u32, date_time.time.sec as u32) + } +} + impl <'a, 'b> FatDirEntry<'a, 'b> { pub fn short_file_name(&self) -> String { let name_str = String::from_utf8_lossy(&self.data.name[0..8]); @@ -146,26 +203,16 @@ impl <'a, 'b> FatDirEntry<'a, 'b> { self.data.size as u64 } - pub fn created(&self) -> DateTime { - Self::convert_date_time(self.data.create_date, self.data.create_time_1) + pub fn created(&self) -> DosDateTime { + DosDateTime::from_words(self.data.create_date, self.data.create_time_1) } - pub fn accessed(&self) -> Date { - Self::convert_date(self.data.access_date) + pub fn accessed(&self) -> DosDate { + DosDate::from_word(self.data.access_date) } - pub fn modified(&self) -> DateTime { - Self::convert_date_time(self.data.modify_date, self.data.modify_time) - } - - fn convert_date(dos_date: u16) -> Date { - let (year, month, day) = ((dos_date >> 9) + 1980, (dos_date >> 5) & 0xF, dos_date & 0x1F); - Local.ymd(year as i32, month as u32, day as u32) - } - - fn convert_date_time(dos_date: u16, dos_time: u16) -> DateTime { - let (hour, min, sec) = (dos_time >> 11, (dos_time >> 5) & 0x3F, (dos_time & 0x1F) * 2); - FatDirEntry::convert_date(dos_date).and_hms(hour as u32, min as u32, sec as u32) + pub fn modified(&self) -> DosDateTime { + DosDateTime::from_words(self.data.modify_date, self.data.modify_time) } } diff --git a/src/lib.rs b/src/lib.rs index 9a7b656..fea32e1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,12 +2,14 @@ #![crate_name = "rfat"] extern crate byteorder; -extern crate chrono; extern crate core; #[macro_use] extern crate bitflags; +#[cfg(feature = "chrono")] +extern crate chrono; + mod fs; mod dir; mod file;