accounts: suggest tips on mailbox_by_path error
If Account::mailbox_by_path() fails, suggest matching mailbox paths using aho_corasick case insensitive matching, and also suggest to the user to inspect mailboxes with the manage-mailboxes command. Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
This commit is contained in:
parent
0f09633899
commit
a389772d96
3 changed files with 49 additions and 1 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1266,6 +1266,7 @@ dependencies = [
|
|||
name = "meli"
|
||||
version = "0.8.8"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"assert_cmd",
|
||||
"async-task",
|
||||
"bitflags 2.6.0",
|
||||
|
|
|
@ -23,6 +23,7 @@ name = "meli"
|
|||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
aho-corasick = { version = "1.1.3" }
|
||||
async-task = { version = "^4.2.0" }
|
||||
bitflags = { version = "2.4", features = ["serde"] }
|
||||
crossbeam = { version = "^0.8" }
|
||||
|
|
|
@ -1331,7 +1331,53 @@ impl Account {
|
|||
{
|
||||
Ok(*mailbox_hash)
|
||||
} else {
|
||||
Err(Error::new("Mailbox with that path not found."))
|
||||
use aho_corasick::AhoCorasick;
|
||||
|
||||
let nodes = self
|
||||
.list_mailboxes()
|
||||
.into_iter()
|
||||
.map(|n| (n.hash, n.depth))
|
||||
.collect::<BTreeMap<MailboxHash, usize>>();
|
||||
let mut entries = self
|
||||
.mailbox_entries
|
||||
.iter()
|
||||
.map(|(h, f)| (h, f.ref_mailbox.path()))
|
||||
.collect::<Vec<_>>();
|
||||
entries.sort_by_cached_key(|(h, _)| nodes.get(h).cloned().unwrap_or(usize::MAX));
|
||||
let patterns = &[path.trim_matches('/')];
|
||||
let mut potential_matches = IndexSet::new();
|
||||
for (_, haystack) in entries {
|
||||
let ac = AhoCorasick::builder()
|
||||
.ascii_case_insensitive(true)
|
||||
.build(patterns)
|
||||
.unwrap();
|
||||
if ac.find_iter(haystack).next().is_some() {
|
||||
potential_matches.insert(haystack.to_string());
|
||||
}
|
||||
}
|
||||
const MANAGE_MAILBOXES_TIP: &str = "You can inspect the list of mailbox paths of an \
|
||||
account with the manage-mailboxes command.";
|
||||
let details_msg = if potential_matches.is_empty() {
|
||||
Cow::Borrowed(MANAGE_MAILBOXES_TIP)
|
||||
} else {
|
||||
let mut potential_matches = potential_matches.into_iter().collect::<Vec<_>>();
|
||||
let matches_length = potential_matches.len();
|
||||
potential_matches.truncate(5);
|
||||
Cow::Owned(format!(
|
||||
"Some matching paths that were found: {matches:?}{others}. {tip}",
|
||||
matches = potential_matches,
|
||||
tip = MANAGE_MAILBOXES_TIP,
|
||||
others = if matches_length > 5 {
|
||||
format!(" and {} others", matches_length - 5)
|
||||
} else {
|
||||
String::with_capacity(0)
|
||||
}
|
||||
))
|
||||
};
|
||||
|
||||
Err(Error::new("Mailbox with that path not found.")
|
||||
.set_details(details_msg)
|
||||
.set_kind(ErrorKind::NotFound))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue