Move time related code to 'time' module
This commit is contained in:
parent
1f8f8365d6
commit
ecef2627a7
125
src/dir_entry.rs
125
src/dir_entry.rs
@ -9,14 +9,11 @@ use io::Cursor;
|
|||||||
|
|
||||||
use byteorder::LittleEndian;
|
use byteorder::LittleEndian;
|
||||||
use byteorder_ext::{ReadBytesExt, WriteBytesExt};
|
use byteorder_ext::{ReadBytesExt, WriteBytesExt};
|
||||||
#[cfg(feature = "chrono")]
|
|
||||||
use chrono;
|
|
||||||
#[cfg(feature = "chrono")]
|
|
||||||
use chrono::{Datelike, Local, TimeZone, Timelike};
|
|
||||||
|
|
||||||
use dir::{Dir, DirRawStream};
|
use dir::{Dir, DirRawStream};
|
||||||
use file::File;
|
use file::File;
|
||||||
use fs::{FatType, FileSystem, OemCpConverter, ReadWriteSeek};
|
use fs::{FatType, FileSystem, OemCpConverter, ReadWriteSeek};
|
||||||
|
use time::{Date, DateTime};
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// A FAT file attributes.
|
/// A FAT file attributes.
|
||||||
@ -429,126 +426,6 @@ impl DirEntryData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A DOS compatible date.
|
|
||||||
///
|
|
||||||
/// Used by `DirEntry` time-related methods.
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
|
||||||
pub struct Date {
|
|
||||||
/// Full year - [1980, 2107]
|
|
||||||
pub year: u16,
|
|
||||||
/// Month of the year - [1, 12]
|
|
||||||
pub month: u16,
|
|
||||||
/// Day of the month - [1, 31]
|
|
||||||
pub day: u16,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Date {
|
|
||||||
pub(crate) fn decode(dos_date: u16) -> Self {
|
|
||||||
let (year, month, day) = ((dos_date >> 9) + 1980, (dos_date >> 5) & 0xF, dos_date & 0x1F);
|
|
||||||
Date { year, month, day }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn encode(&self) -> u16 {
|
|
||||||
((self.year - 1980) << 9) | (self.month << 5) | self.day
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A DOS compatible time.
|
|
||||||
///
|
|
||||||
/// Used by `DirEntry` time-related methods.
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
|
||||||
pub struct Time {
|
|
||||||
/// Hours after midnight - [0, 23]
|
|
||||||
pub hour: u16,
|
|
||||||
/// Minutes after the hour - [0, 59]
|
|
||||||
pub min: u16,
|
|
||||||
/// Seconds after the minute - [0, 59]
|
|
||||||
pub sec: u16,
|
|
||||||
/// Milliseconds after the second - [0, 999]
|
|
||||||
pub millis: u16,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Time {
|
|
||||||
pub(crate) fn decode(dos_time: u16, dos_time_hi_res: u8) -> Self {
|
|
||||||
let hour = dos_time >> 11;
|
|
||||||
let min = (dos_time >> 5) & 0x3F;
|
|
||||||
let sec = (dos_time & 0x1F) * 2 + (dos_time_hi_res as u16) / 2;
|
|
||||||
let millis = (dos_time_hi_res as u16 % 100) * 10;
|
|
||||||
Time { hour, min, sec, millis }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn encode(&self) -> (u16, u8) {
|
|
||||||
let dos_time = (self.hour << 11) | (self.min << 5) | (self.sec / 2);
|
|
||||||
let dos_time_hi_res = ((self.millis / 100) + (self.sec % 2) * 100) as u8;
|
|
||||||
(dos_time, dos_time_hi_res)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A DOS compatible date and time.
|
|
||||||
///
|
|
||||||
/// Used by `DirEntry` time-related methods.
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
|
||||||
pub struct DateTime {
|
|
||||||
/// A date part
|
|
||||||
pub date: Date,
|
|
||||||
// A time part
|
|
||||||
pub time: Time,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DateTime {
|
|
||||||
pub(crate) fn decode(dos_date: u16, dos_time: u16, dos_time_hi_res: u8) -> Self {
|
|
||||||
DateTime {
|
|
||||||
date: Date::decode(dos_date),
|
|
||||||
time: Time::decode(dos_time, dos_time_hi_res),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "chrono")]
|
|
||||||
impl From<Date> for chrono::Date<Local> {
|
|
||||||
fn from(date: Date) -> Self {
|
|
||||||
Local.ymd(date.year as i32, date.month as u32, date.day as u32)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "chrono")]
|
|
||||||
impl From<DateTime> for chrono::DateTime<Local> {
|
|
||||||
fn from(date_time: DateTime) -> Self {
|
|
||||||
chrono::Date::<Local>::from(date_time.date).and_hms_milli(
|
|
||||||
date_time.time.hour as u32,
|
|
||||||
date_time.time.min as u32,
|
|
||||||
date_time.time.sec as u32,
|
|
||||||
date_time.time.millis as u32,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "chrono")]
|
|
||||||
impl From<chrono::Date<Local>> for Date {
|
|
||||||
fn from(date: chrono::Date<Local>) -> Self {
|
|
||||||
Date {
|
|
||||||
year: date.year() as u16,
|
|
||||||
month: date.month() as u16,
|
|
||||||
day: date.day() as u16,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "chrono")]
|
|
||||||
impl From<chrono::DateTime<Local>> for DateTime {
|
|
||||||
fn from(date_time: chrono::DateTime<Local>) -> Self {
|
|
||||||
DateTime {
|
|
||||||
date: Date::from(date_time.date()),
|
|
||||||
time: Time {
|
|
||||||
hour: date_time.hour() as u16,
|
|
||||||
min: date_time.minute() as u16,
|
|
||||||
sec: date_time.second() as u16,
|
|
||||||
millis: (date_time.nanosecond() / 1_000_000) as u16,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub(crate) struct DirEntryEditor {
|
pub(crate) struct DirEntryEditor {
|
||||||
data: DirFileEntryData,
|
data: DirFileEntryData,
|
||||||
|
@ -4,8 +4,9 @@ use io;
|
|||||||
use io::prelude::*;
|
use io::prelude::*;
|
||||||
use io::{ErrorKind, SeekFrom};
|
use io::{ErrorKind, SeekFrom};
|
||||||
|
|
||||||
use dir_entry::{Date, DateTime, DirEntryEditor};
|
use dir_entry::DirEntryEditor;
|
||||||
use fs::{FileSystem, ReadWriteSeek};
|
use fs::{FileSystem, ReadWriteSeek};
|
||||||
|
use time::{Date, DateTime};
|
||||||
|
|
||||||
const MAX_FILE_SIZE: u32 = core::u32::MAX;
|
const MAX_FILE_SIZE: u32 = core::u32::MAX;
|
||||||
|
|
||||||
|
37
src/fs.rs
37
src/fs.rs
@ -12,9 +12,10 @@ use byteorder::LittleEndian;
|
|||||||
use byteorder_ext::{ReadBytesExt, WriteBytesExt};
|
use byteorder_ext::{ReadBytesExt, WriteBytesExt};
|
||||||
|
|
||||||
use dir::{Dir, DirRawStream};
|
use dir::{Dir, DirRawStream};
|
||||||
use dir_entry::{self, DIR_ENTRY_SIZE};
|
use dir_entry::DIR_ENTRY_SIZE;
|
||||||
use file::File;
|
use file::File;
|
||||||
use table::{alloc_cluster, count_free_clusters, read_fat_flags, ClusterIterator};
|
use table::{alloc_cluster, count_free_clusters, read_fat_flags, ClusterIterator};
|
||||||
|
use time::{TimeProvider, DEFAULT_TIME_PROVIDER};
|
||||||
|
|
||||||
// FAT implementation based on:
|
// FAT implementation based on:
|
||||||
// http://wiki.osdev.org/FAT
|
// http://wiki.osdev.org/FAT
|
||||||
@ -753,37 +754,3 @@ impl OemCpConverter for LossyOemCpConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) static LOSSY_OEM_CP_CONVERTER: LossyOemCpConverter = LossyOemCpConverter { _dummy: () };
|
pub(crate) static LOSSY_OEM_CP_CONVERTER: LossyOemCpConverter = LossyOemCpConverter { _dummy: () };
|
||||||
|
|
||||||
pub trait TimeProvider {
|
|
||||||
fn get_current_date(&self) -> dir_entry::Date;
|
|
||||||
fn get_current_date_time(&self) -> dir_entry::DateTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub(crate) struct DefaultTimeProvider {
|
|
||||||
_dummy: (),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TimeProvider for DefaultTimeProvider {
|
|
||||||
#[cfg(feature = "chrono")]
|
|
||||||
fn get_current_date(&self) -> dir_entry::Date {
|
|
||||||
use chrono;
|
|
||||||
dir_entry::Date::from(chrono::Local::now().date())
|
|
||||||
}
|
|
||||||
#[cfg(not(feature = "chrono"))]
|
|
||||||
fn get_current_date(&self) -> dir_entry::Date {
|
|
||||||
dir_entry::Date::decode(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "chrono")]
|
|
||||||
fn get_current_date_time(&self) -> dir_entry::DateTime {
|
|
||||||
use chrono;
|
|
||||||
dir_entry::DateTime::from(chrono::Local::now())
|
|
||||||
}
|
|
||||||
#[cfg(not(feature = "chrono"))]
|
|
||||||
fn get_current_date_time(&self) -> dir_entry::DateTime {
|
|
||||||
dir_entry::DateTime::decode(0, 0, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) static DEFAULT_TIME_PROVIDER: DefaultTimeProvider = DefaultTimeProvider { _dummy: () };
|
|
||||||
|
@ -81,6 +81,7 @@ mod dir_entry;
|
|||||||
mod file;
|
mod file;
|
||||||
mod fs;
|
mod fs;
|
||||||
mod table;
|
mod table;
|
||||||
|
mod time;
|
||||||
|
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg(not(feature = "std"))]
|
||||||
mod byteorder_core_io;
|
mod byteorder_core_io;
|
||||||
@ -101,3 +102,4 @@ pub use dir::*;
|
|||||||
pub use dir_entry::*;
|
pub use dir_entry::*;
|
||||||
pub use file::*;
|
pub use file::*;
|
||||||
pub use fs::*;
|
pub use fs::*;
|
||||||
|
pub use time::*;
|
||||||
|
161
src/time.rs
Normal file
161
src/time.rs
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
#[cfg(feature = "chrono")]
|
||||||
|
use chrono;
|
||||||
|
#[cfg(feature = "chrono")]
|
||||||
|
use chrono::{Datelike, Local, TimeZone, Timelike};
|
||||||
|
|
||||||
|
/// A DOS compatible date.
|
||||||
|
///
|
||||||
|
/// Used by `DirEntry` time-related methods.
|
||||||
|
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
||||||
|
pub struct Date {
|
||||||
|
/// Full year - [1980, 2107]
|
||||||
|
pub year: u16,
|
||||||
|
/// Month of the year - [1, 12]
|
||||||
|
pub month: u16,
|
||||||
|
/// Day of the month - [1, 31]
|
||||||
|
pub day: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Date {
|
||||||
|
pub(crate) fn decode(dos_date: u16) -> Self {
|
||||||
|
let (year, month, day) = ((dos_date >> 9) + 1980, (dos_date >> 5) & 0xF, dos_date & 0x1F);
|
||||||
|
Date { year, month, day }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn encode(&self) -> u16 {
|
||||||
|
((self.year - 1980) << 9) | (self.month << 5) | self.day
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A DOS compatible time.
|
||||||
|
///
|
||||||
|
/// Used by `DirEntry` time-related methods.
|
||||||
|
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
||||||
|
pub struct Time {
|
||||||
|
/// Hours after midnight - [0, 23]
|
||||||
|
pub hour: u16,
|
||||||
|
/// Minutes after the hour - [0, 59]
|
||||||
|
pub min: u16,
|
||||||
|
/// Seconds after the minute - [0, 59]
|
||||||
|
pub sec: u16,
|
||||||
|
/// Milliseconds after the second - [0, 999]
|
||||||
|
pub millis: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Time {
|
||||||
|
pub(crate) fn decode(dos_time: u16, dos_time_hi_res: u8) -> Self {
|
||||||
|
let hour = dos_time >> 11;
|
||||||
|
let min = (dos_time >> 5) & 0x3F;
|
||||||
|
let sec = (dos_time & 0x1F) * 2 + (dos_time_hi_res as u16) / 2;
|
||||||
|
let millis = (dos_time_hi_res as u16 % 100) * 10;
|
||||||
|
Time { hour, min, sec, millis }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn encode(&self) -> (u16, u8) {
|
||||||
|
let dos_time = (self.hour << 11) | (self.min << 5) | (self.sec / 2);
|
||||||
|
let dos_time_hi_res = ((self.millis / 100) + (self.sec % 2) * 100) as u8;
|
||||||
|
(dos_time, dos_time_hi_res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A DOS compatible date and time.
|
||||||
|
///
|
||||||
|
/// Used by `DirEntry` time-related methods.
|
||||||
|
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
||||||
|
pub struct DateTime {
|
||||||
|
/// A date part
|
||||||
|
pub date: Date,
|
||||||
|
// A time part
|
||||||
|
pub time: Time,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DateTime {
|
||||||
|
pub(crate) fn decode(dos_date: u16, dos_time: u16, dos_time_hi_res: u8) -> Self {
|
||||||
|
DateTime {
|
||||||
|
date: Date::decode(dos_date),
|
||||||
|
time: Time::decode(dos_time, dos_time_hi_res),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "chrono")]
|
||||||
|
impl From<Date> for chrono::Date<Local> {
|
||||||
|
fn from(date: Date) -> Self {
|
||||||
|
Local.ymd(date.year as i32, date.month as u32, date.day as u32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "chrono")]
|
||||||
|
impl From<DateTime> for chrono::DateTime<Local> {
|
||||||
|
fn from(date_time: DateTime) -> Self {
|
||||||
|
chrono::Date::<Local>::from(date_time.date).and_hms_milli(
|
||||||
|
date_time.time.hour as u32,
|
||||||
|
date_time.time.min as u32,
|
||||||
|
date_time.time.sec as u32,
|
||||||
|
date_time.time.millis as u32,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "chrono")]
|
||||||
|
impl From<chrono::Date<Local>> for Date {
|
||||||
|
fn from(date: chrono::Date<Local>) -> Self {
|
||||||
|
Date {
|
||||||
|
year: date.year() as u16,
|
||||||
|
month: date.month() as u16,
|
||||||
|
day: date.day() as u16,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "chrono")]
|
||||||
|
impl From<chrono::DateTime<Local>> for DateTime {
|
||||||
|
fn from(date_time: chrono::DateTime<Local>) -> Self {
|
||||||
|
DateTime {
|
||||||
|
date: Date::from(date_time.date()),
|
||||||
|
time: Time {
|
||||||
|
hour: date_time.hour() as u16,
|
||||||
|
min: date_time.minute() as u16,
|
||||||
|
sec: date_time.second() as u16,
|
||||||
|
millis: (date_time.nanosecond() / 1_000_000) as u16,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A current time and date provider.
|
||||||
|
///
|
||||||
|
/// Provides a custom implementation for a time resolution used when updating directory entry time fields.
|
||||||
|
/// Default implementation gets time from `chrono` crate if `chrono` feature is enabled.
|
||||||
|
/// Otherwise default implementation returns DOS minimal date-time (1980/1/1 0:00:00).
|
||||||
|
pub trait TimeProvider {
|
||||||
|
fn get_current_date(&self) -> Date;
|
||||||
|
fn get_current_date_time(&self) -> DateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub(crate) struct DefaultTimeProvider {
|
||||||
|
_dummy: (),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TimeProvider for DefaultTimeProvider {
|
||||||
|
#[cfg(feature = "chrono")]
|
||||||
|
fn get_current_date(&self) -> Date {
|
||||||
|
Date::from(chrono::Local::now().date())
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "chrono"))]
|
||||||
|
fn get_current_date(&self) -> Date {
|
||||||
|
Date::decode(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "chrono")]
|
||||||
|
fn get_current_date_time(&self) -> DateTime {
|
||||||
|
DateTime::from(chrono::Local::now())
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "chrono"))]
|
||||||
|
fn get_current_date_time(&self) -> DateTime {
|
||||||
|
DateTime::decode(0, 0, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) static DEFAULT_TIME_PROVIDER: DefaultTimeProvider = DefaultTimeProvider { _dummy: () };
|
Loading…
Reference in New Issue
Block a user