M src/entry.rs => src/entry.rs +22 -23
@@ 34,25 34,20 @@ impl MailEntry {
.as_bytes(),
)?;
- let mut split = filename.split(SEP).peekable();
- let mut id = split.next().unwrap().to_string();
- while let Some(s) = split.next() {
- if split.peek().is_some() {
- id.push_str(s);
- }
- }
-
- let flags = filename
- .split(&format!("{SEP}2,")) // We are ignoring any experimental info (marked `:1,`)
- .last() // Allow the occurence of `:2,` in the filename
- .unwrap_or("")
- .chars()
- .map(TryFrom::try_from)
- .filter_map(Result::ok)
- .collect();
+ let (id, flags) = match filename.rsplit_once(SEP) {
+ Some((id, flags)) => (
+ id,
+ flags
+ .chars()
+ .map(TryFrom::try_from)
+ .filter_map(Result::ok)
+ .collect(),
+ ),
+ None => (filename, HashSet::new()),
+ };
Ok(MailEntry {
- id,
+ id: id.to_string(),
flags,
path: path.to_path_buf(),
})
@@ 74,7 69,7 @@ impl MailEntry {
fn update(&mut self) -> Result<(), Error> {
let new_file_name = format!(
- "{id}{SEP}2,{flags}",
+ "{id}{SEP}{flags}",
id = self.id,
flags = self.flags_to_string()
);
@@ 82,12 77,16 @@ impl MailEntry {
let prev_path = self.path.clone();
let new_path = self.path.with_file_name(new_file_name);
- if new_path.exists() {
- return Err(Error::AlreadyExistsError(new_path));
+ match fs::rename(prev_path, &self.path) {
+ Ok(_) => {
+ self.path = new_path;
+ Ok(())
+ }
+ Err(e) if e.kind() == io::ErrorKind::AlreadyExists => {
+ Err(Error::AlreadyExistsError(new_path))
+ }
+ Err(e) => Err(e.into()),
}
-
- self.path = new_path;
- Ok(fs::rename(prev_path, &self.path)?)
}
/// Get the unique identifier of the email message.
M src/lib.rs => src/lib.rs +9 -12
@@ 25,9 25,9 @@ const CUR: &str = "cur";
const NEW: &str = "new";
const TMP: &str = "tmp";
#[cfg(unix)]
-const SEP: &str = ":";
+const SEP: &str = ":2,";
#[cfg(windows)]
-const SEP: &str = ";";
+const SEP: &str = ";2,";
static COUNTER: AtomicUsize = AtomicUsize::new(0);
@@ 66,9 66,7 @@ impl Maildir {
/// Ensures that the necessary subfolders exist.
fn ensure_dirs(&self) -> Result<(), Error> {
for dir in &[&self.cur, &self.new, &self.tmp] {
- if !dir.exists() {
- fs::create_dir_all(dir)?;
- }
+ fs::create_dir_all(dir)?;
}
Ok(())
}
@@ 77,8 75,9 @@ impl Maildir {
pub fn clean_tmp(&self) -> Result<(), Error> {
for entry in fs::read_dir(&self.tmp)? {
let path = entry?.path();
+ let metadata = path.metadata()?;
// If the file is older than 36 hours, delete it
- if path.is_file() && path.metadata()?.modified()?.elapsed()?.as_secs() > 36 * 60 * 60 {
+ if metadata.is_file() && metadata.modified()?.elapsed()?.as_secs() > 36 * 60 * 60 {
fs::remove_file(path)?;
}
}
@@ 289,12 288,10 @@ impl Maildir {
}
}
- /// At this point, `file` is our new file at `tmppath`. If we
- /// leave the scope of this function prior to
- /// successfully writing the file to its final
- /// location, we need to ensure that we remove
- /// the temporary file. This struct takes care
- /// of that detail.
+ /// At this point, `file` is our new file at `tmppath`. If we leave the
+ /// scope of this function prior to successfully writing the file to its
+ /// final location, we need to ensure that we remove the temporary file.
+ /// This struct takes care of that detail.
struct RemoveOnDrop {
path_to_remove: PathBuf,
}