From b327bee3e4511bbf2d50d61a7070b39d3395de44 Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Sat, 23 Nov 2019 17:54:45 +0200 Subject: [PATCH] text_processing: add GlobMatch trait Move GlobMatch trait from ui::mailcap to text_processing in order to use it for glob matching folder paths in subscribed_folders field of account configuration. See next commit. --- text_processing/src/lib.rs | 54 ++++++++++++++++++++++++++++++++++++++ ui/src/mailcap.rs | 54 +++++++++++++++----------------------- 2 files changed, 75 insertions(+), 33 deletions(-) diff --git a/text_processing/src/lib.rs b/text_processing/src/lib.rs index dc8be708..0e900288 100644 --- a/text_processing/src/lib.rs +++ b/text_processing/src/lib.rs @@ -20,3 +20,57 @@ impl Truncate for &mut String { String::truncate(self, new_len); } } + +pub trait GlobMatch { + fn matches_glob(&self, s: &str) -> bool; + fn is_glob(&self) -> bool; +} + +impl GlobMatch for str { + fn matches_glob(&self, s: &str) -> bool { + let parts = s.split("*"); + + let mut ptr = 0; + let mut part_no = 0; + + for p in parts { + if p.is_empty() { + /* asterisk is at beginning and/or end of glob */ + /* eg "*".split("*") gives ["", ""] */ + part_no += 1; + continue; + } + + if ptr >= self.len() { + return false; + } + if part_no > 0 { + while !&self[ptr..].starts_with(p) { + ptr += 1; + if ptr >= self.len() { + return false; + } + } + } + if !&self[ptr..].starts_with(p) { + return false; + } + ptr += p.len(); + part_no += 1; + } + true + } + + fn is_glob(&self) -> bool { + self.contains('*') + } +} + +#[test] +fn test_globmatch() { + assert!("INBOX".matches_glob("INBOX")); + assert!("INBOX/Sent".matches_glob("INBOX/*")); + assert!(!"INBOX/Sent".matches_glob("*/Drafts")); + assert!("INBOX/Sent".matches_glob("*/Sent")); + assert!("INBOX/Archives/2047".matches_glob("*")); +} diff --git a/ui/src/mailcap.rs b/ui/src/mailcap.rs index dc559b99..7bf30474 100644 --- a/ui/src/mailcap.rs +++ b/ui/src/mailcap.rs @@ -1,3 +1,23 @@ +/* + * meli + * + * Copyright 2019 Manos Pitsidianakis + * + * This file is part of meli. + * + * meli is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * meli is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with meli. If not, see . + */ use crate::split_command; use crate::state::Context; use crate::types::{create_temp_file, ForkType, UIEvent}; @@ -8,6 +28,7 @@ use std::io::Read; use std::io::Write; use std::path::PathBuf; use std::process::{Command, Stdio}; +use text_processing::GlobMatch; pub struct MailcapEntry { command: String, @@ -15,39 +36,6 @@ pub struct MailcapEntry { copiousoutput: bool, } -trait GlobMatch { - fn matches_glob(&self, s: &str) -> bool; -} - -impl GlobMatch for str { - fn matches_glob(&self, s: &str) -> bool { - let parts = self.split("*"); - - let mut ptr = 0; - let mut part_no = 0; - - for p in parts { - if ptr >= s.len() { - return false; - } - if part_no > 0 { - while !&s[ptr..].starts_with(p) { - ptr += 1; - if ptr >= s.len() { - return false; - } - } - } - if !&s[ptr..].starts_with(p) { - return false; - } - ptr += p.len(); - part_no += 1; - } - true - } -} - impl MailcapEntry { pub fn execute(a: &Attachment, context: &mut Context) -> Result<()> { /* lookup order: