Flipping an Option<Result<T, E>>
to a Result<Option<T>, E>
I was writing a command line application which took a regex from a flag, the details aren't important. I knew that the valid states for this parameter were:
- Flag was not used, the output should be
Ok(None)
- Flag was used but the regex was invalid, the output should be
Err(E)
- Flag was used and the regex was valid, the output should be
Ok(T)
let pattern: Option<String> = Some("[a-z]".into());
let pattern: Result<Option<Regex>, regex::Error> = pattern
.as_ref()
.map_or(
Ok(None),
// The following line turns Result<T, E> into a Result<Option<T>, E>
|pattern| Regex::new(&pattern).map(Some)
);
Converting a std::time::SystemTime to a chrono::DateTime
fn system_time_to_chrono_time(st: SystemTime) -> Option<DateTime<Utc>> {
st.duration_since(SystemTime::UNIX_EPOCH)
.ok()
.map(|dur| DateTime::<Utc>::from_timestamp_secs(dur.as_secs() as i64))
.flatten()
}
Recursively search for files
Ignores symlinks
pub fn recurse_directories_for_files<P>(path: P) -> io::Result<Vec<std::fs::DirEntry>>
where
P: AsRef<std::path::Path>,
{
let mut ret = Vec::<_>::new();
let entries = fs::read_dir(path)?
.into_iter()
.collect::<io::Result<Vec<_>>>()?;
for entry in entries {
let metadata = entry.metadata()?;
if metadata.is_symlink() {
continue;
}
if metadata.is_dir() {
ret.append(&mut recurse_directories_for_files(entry.path())?);
} else if metadata.is_file() {
ret.push(entry);
}
}
Ok(ret)
}