1use std::io::{BufReader, Read};
2use std::fs::{File, metadata};
3use std::path::PathBuf;
4use chrono::{DateTime, Utc};
5
6use crate::errors::CommotError;
7
8#[derive(Clone, Debug)]
11pub struct Reader {
12 pub path: PathBuf,
13}
14
15#[derive(Clone, Debug)]
18pub enum FileSizeType {
19 Bytes(u64),
20 KiloBytes(u64),
21 MegaBytes(u64),
22 GigaBytes(u64)
23}
24
25
26#[derive(Clone, Debug)]
27pub struct FileMetadata {
28 pub size: FileSize,
29 pub created: DateTime<Utc>,
30 pub modified: DateTime<Utc>,
31 pub accessed: DateTime<Utc>,
32}
33impl FileMetadata {
34 pub fn new(
35 size: FileSize,
36 created: DateTime<Utc>,
37 modified: DateTime<Utc>,
38 accessed: DateTime<Utc>
39
40
41 ) -> Self {
42 Self {
43 size,
44 created,
45 modified,
46 accessed
47 }
48 }
49}
50
51impl FileSizeType {
52 pub fn new(bytes: u64) -> Self {
53 let kb = bytes / 1000;
54 let mb = kb / 1000;
55 let gb = mb / 1000;
56 if bytes < 1000 {
57 FileSizeType::Bytes(bytes)
58 } else if bytes >= 1000 {
59 FileSizeType::KiloBytes(kb)
60 } else if kb >= 1000 {
61 FileSizeType::MegaBytes(mb)
62 } else {
63 FileSizeType::GigaBytes(gb)
64 }
65 }
66 pub fn to_string(&self) -> String {
67 match self {
68 Self::Bytes(v) => format!("{} byte(s)", v),
69 Self::KiloBytes(v) => format!("{} kilobyte(s)", v),
70 Self::MegaBytes(v) => format!("{} megabyte(s)", v),
71 Self::GigaBytes(v) => format!("{} gigabyte(s)", v)
72 }
73
74 }
75
76 pub fn into_inner(&self) -> u64 {
77 match &self {
78 FileSizeType::Bytes(v) => v.to_owned(),
79 FileSizeType::KiloBytes(v) => v.to_owned(),
80 FileSizeType::MegaBytes(v) => v.to_owned(),
81 FileSizeType::GigaBytes(v) => v.to_owned(),
82 }
83 }
84
85
86
87}
88#[derive(Clone, Debug)]
89pub struct FileSize(FileSizeType);
90
91impl FileSize {
92 pub fn new(size: FileSizeType) -> Self {
93 Self(size)
94 }
95
96 pub fn into_inner(&self) -> FileSizeType {
97 self.0.clone()
98 }
99}
100
101pub struct FileData(String);
102impl FileData {
103 pub fn new(data: String) -> Self {
104 Self(data)
105 }
106
107 pub fn into_inner(&self) -> String {
108 self.0.to_owned()
109 }
110}
111impl Reader {
113 pub fn new(path: String) -> Self{
114 Self {path: path.into()}
115 }
116 pub fn read(&self) -> Result<FileData, CommotError> {
117 let file = File::open(&self.path)?;
118 let mut reader = BufReader::new(file);
119 let mut buffer = String::new();
120 reader.read_to_string(&mut buffer)?;
121 Ok(FileData::new(buffer))
122 }
123
124
125 pub fn size(&self) -> Result<FileSize, CommotError> {
126 let file_metadata = metadata(&self.path)?;
127 let file_size = FileSize::new(FileSizeType::new(file_metadata.len()));
128 Ok(file_size)
129
130 }
131
132
133 pub fn created(&self) -> Result<DateTime<Utc>, CommotError> {
134 let file_metadata = metadata(&self.path)?;
135 Ok(file_metadata.created()?.into())
136 }
137
138 pub fn accessed(&self) -> Result<DateTime<Utc>, CommotError> {
139 let file_metadata = metadata(&self.path)?;
140 Ok(file_metadata.accessed()?.into())
141 }
142 pub fn modified(&self) -> Result<DateTime<Utc>, CommotError> {
143 let file_metadata = metadata(&self.path)?;
144 Ok(file_metadata.modified()?.into())
145 }
146
147 pub fn metadata(&self) -> Result<FileMetadata, CommotError> {
148 Ok(
149 FileMetadata::new(self.size()?, self.created()?, self.modified()?, self.accessed()?)
150 )
151 }
152}