-
Notifications
You must be signed in to change notification settings - Fork 90
RFC 5256 - SORT command #180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
07f8f71
add sort extension
soywod 237e349
Merge remote-tracking branch 'upstream/master'
soywod 84fd6dd
replace HashSet by LinkedHashSet to preserve insertion order of sorte…
soywod 72f57ab
add uid_sort test
soywod 8c3aba6
replace LinkedHashSet by Vec
soywod 2d5de94
Merge remote-tracking branch 'upstream/master'
soywod d87af61
update imap-proto version
soywod 2f195ef
Merge remote-tracking branch 'upstream/master'
soywod e9478c5
improve sort criteria system
soywod 606edc8
clean doc, update uid_sort
soywod 8c9dea4
improve sort charset
soywod 95b345c
remove unused hashset import in tests
soywod 7acd3bf
review round 1
soywod 99bc321
add parse_id_seq test
soywod df9ef23
add sort and uid_sort unit tests
soywod cae5eea
review round 2
soywod 8f7befe
Update src/extensions/sort.rs
jonhoo aa30502
Merge branch 'master' into master
jonhoo 5e0eed1
Update src/parse.rs
jonhoo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| //! Implementations of various IMAP extensions. | ||
| pub mod idle; | ||
| pub mod metadata; | ||
| pub mod sort; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,153 @@ | ||
| //! Adds support for the IMAP SORT extension specificed in [RFC | ||
| //! 5464](https://tools.ietf.org/html/rfc5256#section-3). | ||
| //! | ||
| //! The SORT command is a variant of SEARCH with sorting semantics for | ||
| //! the results. There are two arguments before the searching | ||
| //! criteria argument: a parenthesized list of sort criteria, and the | ||
| //! searching charset. | ||
|
|
||
| use std::{borrow::Cow, fmt}; | ||
|
|
||
| pub(crate) struct SortCriteria<'c>(pub(crate) &'c [SortCriterion<'c>]); | ||
|
|
||
| impl<'c> fmt::Display for SortCriteria<'c> { | ||
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
| if self.0.is_empty() { | ||
| write!(f, "") | ||
| } else { | ||
| let criteria: Vec<String> = self.0.iter().map(|c| c.to_string()).collect(); | ||
| write!(f, "({})", criteria.join(" ")) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// Message sorting preferences used for [`Session::sort`] and [`Session::uid_sort`]. | ||
| /// | ||
| /// Any sorting criterion that refers to an address (`From`, `To`, etc.) sorts according to the | ||
| /// "addr-mailbox" of the indicated address. You can find the formal syntax for addr-mailbox [in | ||
| /// the IMAP spec](https://tools.ietf.org/html/rfc3501#section-9), and a more detailed discussion | ||
| /// of the relevant semantics [in RFC 2822](https://tools.ietf.org/html/rfc2822#section-3.4.1). | ||
| /// Essentially, the address refers _either_ to the name of the contact _or_ to its local-part (the | ||
| /// left part of the email address, before the `@`). | ||
| #[non_exhaustive] | ||
| #[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)] | ||
| pub enum SortCriterion<'c> { | ||
soywod marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| /// Internal date and time of the message. This differs from the | ||
| /// ON criteria in SEARCH, which uses just the internal date. | ||
| Arrival, | ||
|
|
||
| /// IMAP addr-mailbox of the first "Cc" address. | ||
| Cc, | ||
|
|
||
| /// Sent date and time, as described in | ||
| /// [section 2.2](https://tools.ietf.org/html/rfc5256#section-2.2). | ||
| Date, | ||
|
|
||
| /// IMAP addr-mailbox of the first "From" address. | ||
| From, | ||
|
|
||
| /// Followed by another sort criterion, has the effect of that | ||
| /// criterion but in reverse (descending) order. | ||
| Reverse(&'c SortCriterion<'c>), | ||
|
|
||
| /// Size of the message in octets. | ||
| Size, | ||
|
|
||
| /// Base subject text. | ||
| Subject, | ||
|
|
||
| /// IMAP addr-mailbox of the first "To" address. | ||
| To, | ||
| } | ||
|
|
||
| impl<'c> fmt::Display for SortCriterion<'c> { | ||
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
| use SortCriterion::*; | ||
|
|
||
| match self { | ||
| Arrival => write!(f, "ARRIVAL"), | ||
| Cc => write!(f, "CC"), | ||
| Date => write!(f, "DATE"), | ||
| From => write!(f, "FROM"), | ||
| Reverse(c) => write!(f, "REVERSE {}", c), | ||
| Size => write!(f, "SIZE"), | ||
| Subject => write!(f, "SUBJECT"), | ||
| To => write!(f, "TO"), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// The character encoding to use for strings that are subject to a [`SortCriterion`]. | ||
| /// | ||
| /// Servers are only required to implement [`SortCharset::UsAscii`] and [`SortCharset::Utf8`]. | ||
| #[non_exhaustive] | ||
| #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
| pub enum SortCharset<'c> { | ||
soywod marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| /// Strings are UTF-8 encoded. | ||
| Utf8, | ||
|
|
||
| /// Strings are encoded with ASCII. | ||
| UsAscii, | ||
|
|
||
| /// Strings are encoded using some other character set. | ||
| /// | ||
| /// Note that this option is subject to server support for the specified character set. | ||
| Custom(Cow<'c, str>), | ||
| } | ||
|
|
||
| impl<'c> fmt::Display for SortCharset<'c> { | ||
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
| use SortCharset::*; | ||
|
|
||
| match self { | ||
| Utf8 => write!(f, "UTF-8"), | ||
| UsAscii => write!(f, "US-ASCII"), | ||
| Custom(c) => write!(f, "{}", c), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; | ||
|
|
||
| #[test] | ||
| fn test_criterion_to_string() { | ||
| use SortCriterion::*; | ||
|
|
||
| assert_eq!("ARRIVAL", Arrival.to_string()); | ||
| assert_eq!("CC", Cc.to_string()); | ||
| assert_eq!("DATE", Date.to_string()); | ||
| assert_eq!("FROM", From.to_string()); | ||
| assert_eq!("SIZE", Size.to_string()); | ||
| assert_eq!("SUBJECT", Subject.to_string()); | ||
| assert_eq!("TO", To.to_string()); | ||
| assert_eq!("REVERSE TO", Reverse(&To).to_string()); | ||
| assert_eq!("REVERSE REVERSE TO", Reverse(&Reverse(&To)).to_string()); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_criteria_to_string() { | ||
| use SortCriterion::*; | ||
|
|
||
| assert_eq!("", SortCriteria(&[]).to_string()); | ||
| assert_eq!("(ARRIVAL)", SortCriteria(&[Arrival]).to_string()); | ||
| assert_eq!( | ||
| "(ARRIVAL REVERSE FROM)", | ||
| SortCriteria(&[Arrival, Reverse(&From)]).to_string() | ||
| ); | ||
| assert_eq!( | ||
| "(ARRIVAL REVERSE REVERSE REVERSE FROM)", | ||
| SortCriteria(&[Arrival, Reverse(&Reverse(&Reverse(&From)))]).to_string() | ||
| ); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_charset_to_string() { | ||
| use SortCharset::*; | ||
|
|
||
| assert_eq!("UTF-8", Utf8.to_string()); | ||
| assert_eq!("US-ASCII", UsAscii.to_string()); | ||
| assert_eq!("CHARSET", Custom("CHARSET".into()).to_string()); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.