From 9c08e145239bbb19d95a02d247740a4f1978784a Mon Sep 17 00:00:00 2001 From: Edward Rudd Date: Mon, 26 Sep 2022 14:21:34 -0400 Subject: [PATCH] adjust parse_until_done to return an Option so it is more versatile --- src/parse.rs | 15 ++++++++++++--- src/types/acls.rs | 9 ++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/parse.rs b/src/parse.rs index 2ad08a8..69e80d5 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -58,12 +58,14 @@ where /// Parse and return an expected single `T` Response with `F`. /// Responses other than `T` go into the `unsolicited` channel. /// -/// If zero or more than one `T` is found then [`Error::Parse`] is returned +/// If more than one `T` are found then [`Error::Parse`] is returned +/// If zero `T` are found and optional is false then [`Error::Parse`] is returned, otherwise None is pub(crate) fn parse_until_done<'input, T, F>( input: &'input [u8], + optional: bool, unsolicited: &mut mpsc::Sender, map: F, -) -> Result +) -> Result> where F: FnMut(Response<'input>) -> Result>, { @@ -72,7 +74,14 @@ where parse_many_into(input, &mut temp_output, unsolicited, map)?; match temp_output.len() { - 1 => Ok(temp_output.remove(0)), + 1 => Ok(Some(temp_output.remove(0))), + 0 => { + if optional { + Ok(None) + } else { + Err(Error::Parse(ParseError::Invalid(input.to_vec()))) + } + } _ => Err(Error::Parse(ParseError::Invalid(input.to_vec()))), } } diff --git a/src/types/acls.rs b/src/types/acls.rs index b67076b..182f780 100644 --- a/src/types/acls.rs +++ b/src/types/acls.rs @@ -123,7 +123,7 @@ impl AclResponse { data: owned, acl_builder: |input| { // There should only be ONE single ACL response - parse_until_done(input, unsolicited, |response| match response { + parse_until_done(input, false, unsolicited, |response| match response { Response::Acl(a) => Ok(MapOrNot::Map(Acl { mailbox: a.mailbox, acls: a @@ -137,6 +137,7 @@ impl AclResponse { })), resp => Ok(MapOrNot::Not(resp)), }) + .map(|o| o.unwrap()) }, } .try_build() @@ -206,7 +207,7 @@ impl ListRightsResponse { data: owned, rights_builder: |input| { // There should only be ONE single LISTRIGHTS response - parse_until_done(input, unsolicited, |response| match response { + parse_until_done(input, false, unsolicited, |response| match response { Response::ListRights(a) => Ok(MapOrNot::Map(ListRights { mailbox: a.mailbox, identifier: a.identifier, @@ -215,6 +216,7 @@ impl ListRightsResponse { })), resp => Ok(MapOrNot::Not(resp)), }) + .map(|o| o.unwrap()) }, } .try_build() @@ -286,13 +288,14 @@ impl MyRightsResponse { data: owned, rights_builder: |input| { // There should only be ONE single MYRIGHTS response - parse_until_done(input, unsolicited, |response| match response { + parse_until_done(input, false, unsolicited, |response| match response { Response::MyRights(a) => Ok(MapOrNot::Map(MyRights { mailbox: a.mailbox, rights: a.rights.into(), })), resp => Ok(MapOrNot::Not(resp)), }) + .map(|o| o.unwrap()) }, } .try_build()