summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2019-12-26 12:46:15 +0100
committerMatthias Beyer <mail@beyermatthias.de>2019-12-26 12:46:15 +0100
commit5f592f5a55232e3f5667fa6cdd62d9ec8e91a1ca (patch)
treedcb22f2894f2437194cff009805b682635af4f74
parenteb3c61811fda288237ec6824da41da099b1d5131 (diff)
Rewrite functions to return Result<_>
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r--parser/src/parser.rs39
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(&params.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)]