Skip to content

Commit 15d3f48

Browse files
committed
Implement changes & suggestions by @jonhoo
1 parent 36d0c05 commit 15d3f48

File tree

2 files changed

+13
-21
lines changed

2 files changed

+13
-21
lines changed

src/client.rs

+11-20
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ fn validate_sequence_set(
139139
pub struct Session<T: Read + Write> {
140140
conn: Connection<T>,
141141

142-
// Capabilities are almost guaranteed to chance if encryption state or authentication state
142+
// Capabilities are almost guaranteed to change if encryption state or authentication state
143143
// changes, so caching them in `Connection` is inappropiate.
144144
capability_cache: Option<Capabilities>,
145145

@@ -159,7 +159,7 @@ pub struct Session<T: Read + Write> {
159159
pub struct Client<T: Read + Write> {
160160
conn: Connection<T>,
161161

162-
// Capabilities are almost guaranteed to chance if encryption state or authentication state
162+
// Capabilities are almost guaranteed to change if encryption state or authentication state
163163
// changes, so caching them in `Connection` is inappropiate.
164164
capability_cache: Option<Capabilities>,
165165
}
@@ -362,16 +362,16 @@ impl<T: Read + Write> Client<T> {
362362
/// This method will always bypass the local capabilities cache and send a `CAPABILITY` command
363363
/// to the server. The [`Self::capabilities()`] method can be used when returning a cached
364364
/// response is acceptable.
365-
pub fn capabilities_refresh(&mut self) -> Result<&Capabilities> {
365+
pub fn current_capabilities(&mut self) -> Result<&Capabilities> {
366366
let (mut tx, _rx) = mpsc::channel();
367367
let caps = self.run_command_and_read_response("CAPABILITY")
368368
.and_then(|lines| Capabilities::parse(lines, &mut tx))?;
369369
self.capability_cache = Some(caps);
370370

371-
self.capability_cache.as_ref()
371+
Ok(self.capability_cache.as_ref()
372372
// This path will not be hit; if the cache is not populated the above calls will either
373373
// populate it or return with an early error.
374-
.ok_or_else(|| panic!("CAPABILITY call did not populate capability cache!"))
374+
.expect("CAPABILITY call did not populate capability cache!"))
375375
}
376376

377377
/// The [`CAPABILITY` command](https://tools.ietf.org/html/rfc3501#section-6.1.1) requests a
@@ -381,7 +381,7 @@ impl<T: Read + Write> Client<T> {
381381
/// This function will not query the server if a set of capabilities was cached, but request
382382
/// and cache capabilities from the server otherwise. The [`Self::capabilities_refresh`] method
383383
/// can be used to refresh the cache by forcing a `CAPABILITY` command to be send.
384-
pub fn capabilities_ref(&mut self) -> Result<&Capabilities> {
384+
pub fn capabilities(&mut self) -> Result<&Capabilities> {
385385
let (mut tx, _rx) = mpsc::channel();
386386
if self.capability_cache.is_none() {
387387
let caps = self.run_command_and_read_response("CAPABILITY")
@@ -390,10 +390,10 @@ impl<T: Read + Write> Client<T> {
390390
self.capability_cache = Some(caps);
391391
}
392392

393-
self.capability_cache.as_ref()
393+
Ok(self.capability_cache.as_ref()
394394
// This path will not be hit; if the cache is not populated the above `if` will either
395395
// populate it or return with an early error.
396-
.ok_or_else(|| panic!("CAPABILITY call did not populate capability cache!"))
396+
.expect("CAPABILITY call did not populate capability cache!"))
397397
}
398398

399399
/// Log in to the IMAP server. Upon success a [`Session`](struct.Session.html) instance is
@@ -830,7 +830,7 @@ impl<T: Read + Write> Session<T> {
830830
/// This method will always bypass the local capabilities cache and send a `CAPABILITY` command
831831
/// to the server. The [`Self::capabilities()`] method can be used when returning a cached
832832
/// response is acceptable.
833-
pub fn capabilities_refresh(&mut self) -> Result<&Capabilities> {
833+
pub fn current_capabilities(&mut self) -> Result<&Capabilities> {
834834
let caps = self.run_command_and_read_response("CAPABILITY")
835835
.and_then(|lines| Capabilities::parse(lines, &mut self.unsolicited_responses_tx))?;
836836
self.capability_cache = Some(caps);
@@ -848,7 +848,7 @@ impl<T: Read + Write> Session<T> {
848848
/// This function will not query the server if a set of capabilities was cached, but request
849849
/// and cache capabilities from the server otherwise. The [`Self::capabilities_refresh`] method
850850
/// can be used to refresh the cache by forcing a `CAPABILITY` command to be send.
851-
pub fn capabilities_ref(&mut self) -> Result<&Capabilities> {
851+
pub fn capabilities(&mut self) -> Result<&Capabilities> {
852852
if self.capability_cache.is_none() {
853853
let caps = self.run_command_and_read_response("CAPABILITY")
854854
.and_then(|lines| Capabilities::parse(lines, &mut self.unsolicited_responses_tx))?;
@@ -862,15 +862,6 @@ impl<T: Read + Write> Session<T> {
862862
.ok_or_else(|| panic!("CAPABILITY call did not populate capability cache!"))
863863
}
864864

865-
/// The [`CAPABILITY` command](https://tools.ietf.org/html/rfc3501#section-6.1.1) requests a
866-
/// listing of capabilities that the server supports. The server will include "IMAP4rev1" as
867-
/// one of the listed capabilities. See [`Capabilities`] for further details.
868-
pub fn capabilities(&mut self) -> Result<Capabilities> {
869-
// TODO: This emulated the same behaviour as before, with each call issuing a command.
870-
// It may be sensible to allow hitting the cache here.
871-
self.capabilities_refresh().map(|caps| caps.clone())
872-
}
873-
874865
/// The [`EXPUNGE` command](https://tools.ietf.org/html/rfc3501#section-6.4.3) permanently
875866
/// removes all messages that have [`Flag::Deleted`] set from the currently selected mailbox.
876867
/// The message sequence number of each message that is removed is returned.
@@ -2826,7 +2817,7 @@ a1 OK completed\r
28262817
];
28272818
let mock_stream = MockStream::new(response);
28282819
let mut session = mock_session!(mock_stream);
2829-
let capabilities = session.capabilities().unwrap();
2820+
let capabilities = session.capabilities().cloned().unwrap();
28302821
assert!(
28312822
session.stream.get_ref().written_buf == b"a1 CAPABILITY\r\n".to_vec(),
28322823
"Invalid capability command"

src/types/capabilities.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ impl Clone for Capabilities {
4848
fn clone(&self) -> Self {
4949
// Give _rx a name so it's not immediately dropped. Otherwise any unsolicited responses
5050
// that would be send there will return a SendError instead of the parsed response simply
51-
// being dropped later.
51+
// being dropped later. Those responses being dropped is safe as they were already parsed
52+
// and sent to a consumer when this capabilities response was parsed the first time.
5253
let (mut tx, _rx) = mpsc::channel();
5354
Self::parse(self.borrow_data().clone(), &mut tx)
5455
.expect("failed to parse capabilities from data which was already successfully parse before")

0 commit comments

Comments
 (0)