diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2019-12-26 12:46:15 +0100 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2019-12-26 12:46:15 +0100 |
commit | 5f592f5a55232e3f5667fa6cdd62d9ec8e91a1ca (patch) | |
tree | dcb22f2894f2437194cff009805b682635af4f74 | |
parent | eb3c61811fda288237ec6824da41da099b1d5131 (diff) |
Rewrite functions to return Result<_>
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r-- | parser/src/parser.rs | 39 |
1 files changed, 21 insertions, 18 deletions
diff --git a/parser/src/parser.rs b/parser/src/parser.rs index 41cca95..f7ceefa 100644 --- a/parser/src/parser.rs +++ b/parser/src/parser.rs @@ -75,8 +75,8 @@ impl Default for ParsedContentType { /// assert_eq!(ctype.params.get("boundary"), None); /// assert_eq!(ctype.params.get("name"), Some(&"迎娶白富美".to_string())); /// ``` -pub fn parse_content_type(header: &str) -> ParsedContentType { - let params = parse_param_content(header); +pub fn parse_content_type(header: &str) -> Result<ParsedContentType> { + let params = parse_param_content(header)?; let mimetype = params.value.to_lowercase(); let charset = params .params @@ -84,11 +84,11 @@ pub fn parse_content_type(header: &str) -> ParsedContentType { .cloned() .unwrap_or_else(|| "us-ascii".to_string()); - ParsedContentType { + Ok(ParsedContentType { mimetype, charset, params: params.params, - } + }) } /// Convert the string represented disposition type to enum. @@ -131,13 +131,14 @@ pub struct ParsedContentDisposition { /// assert_eq!(dis.params.get("name"), None); /// assert_eq!(dis.params.get("filename"), Some(&"yummy dummy".to_string())); /// ``` -pub fn parse_content_disposition(header: &str) -> ParsedContentDisposition { - let params = parse_param_content(header); +pub fn parse_content_disposition(header: &str) -> Result<ParsedContentDisposition> { + let params = parse_param_content(header)?; let disposition = parse_disposition_type(¶ms.value); - ParsedContentDisposition { + + Ok(ParsedContentDisposition { disposition, params: params.params, - } + }) } /// Struct that holds the structured representation of the message. Note that @@ -257,12 +258,11 @@ impl<'a> ParsedMail<'a> { /// method documentation for more details on the semantics of the /// returned object. pub fn get_content_disposition(&self) -> Result<ParsedContentDisposition> { - let disposition = self - .headers + Ok(self.headers .get_first_value("Content-Disposition")? .map(|s| parse_content_disposition(&s)) - .unwrap_or_default(); - Ok(disposition) + .transpose()? + .unwrap_or_default()) } } @@ -308,6 +308,7 @@ pub fn parse_mail(raw_data: &[u8]) -> Result<ParsedMail> { let ctype = headers .get_first_value("Content-Type")? .map(|s| parse_content_type(&s)) + .transpose()? .unwrap_or_default(); let mut result = ParsedMail { @@ -361,10 +362,15 @@ struct ParamContent { /// which implicitly does not support multiple parameters with /// the same key. The format for parameterized header values /// doesn't appear to be strongly specified anywhere. -fn parse_param_content(content: &str) -> ParamContent { +fn parse_param_content(content: &str) -> Result<ParamContent> { let mut tokens = content.split(';'); + // There must be at least one token produced by split, even if it's empty. - let value = tokens.next().unwrap().trim(); + let value = tokens + .next() + .ok_or_else(|| format_err!("There should be at least one ';' in '{}'", content))? + .trim(); + let map = tokens .filter_map(|kv| { kv.find('=').map(|idx| { @@ -378,10 +384,7 @@ fn parse_param_content(content: &str) -> ParamContent { }) .collect(); - ParamContent { - value: value.into(), - params: map, - } + Ok(ParamContent { value: value.into(), params: map }) } #[cfg(test)] |