Skip to content
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

Improve doc + bugfix (v1.0.1) #35

Merged
merged 5 commits into from
Sep 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.0.1] - 2023-09-17
- extending docs about some structs
- fixing `Display` implementation of `TooLongEncodedWord`

## [1.0.0] - 2023-09-16

### Changed
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "rfc2047-decoder"
description = "Rust library for decoding RFC 2047 MIME Message Headers."
version = "1.0.0" # do not forget html_root_url
version = "1.0.1" # do not forget html_root_url
authors = ["soywod <[email protected]>", "TornaxO7 <[email protected]>"]
edition = "2018"
repository = "https://github.com/soywod/rfc2047-decoder"
Expand Down
6 changes: 4 additions & 2 deletions src/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ type Result<T> = result::Result<T, Error>;
///
/// let decoder = Decoder::new()
/// .too_long_encoded_word_strategy(RecoverStrategy::Skip);
/// let decoded_str = decoder.decode("=?UTF-8?B?c3Ry?=");
/// let decoded_str = decoder.decode("=?UTF-8?B?c3Ry?=").unwrap();
///
/// assert_eq!(decoded_str, "str");
/// ```
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Decoder {
Expand Down Expand Up @@ -126,7 +128,7 @@ impl Decoder {
///
/// let parsed = decoder.decode(message);
///
/// assert_eq!(parsed, Err(Lexer(ParseEncodedWordTooLongError(TooLongEncodedWords(vec!["=?utf-8?TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4gVXQgaW50ZXJkdW0gcXVhbSBldSBmYWNpbGlzaXMgb3JuYXJlLg==?B?=".to_string()])))));
/// assert_eq!(parsed, Err(Lexer(ParseEncodedWordTooLongError(TooLongEncodedWords(vec!["=?utf-8?B?TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4gVXQgaW50ZXJkdW0gcXVhbSBldSBmYWNpbGlzaXMgb3JuYXJlLg==?=".to_string()])))));
/// ```
pub fn too_long_encoded_word_strategy(mut self, strategy: RecoverStrategy) -> Self {
self.too_long_encoded_word = strategy;
Expand Down
3 changes: 2 additions & 1 deletion src/evaluator.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use base64::{
alphabet,
engine::{GeneralPurpose, GeneralPurposeConfig}, Engine,
engine::{GeneralPurpose, GeneralPurposeConfig},
Engine,
};
use charset::Charset;
use std::{result, string};
Expand Down
4 changes: 2 additions & 2 deletions src/lexer/encoded_word.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ impl EncodedWord {
impl Display for EncodedWord {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let charset = String::from_utf8(self.charset.clone()).unwrap();
let encoding = String::from_utf8(self.encoded_text.clone()).unwrap();
let encoded_text = String::from_utf8(self.encoding.clone()).unwrap();
let encoding = String::from_utf8(self.encoding.clone()).unwrap();
let encoded_text = String::from_utf8(self.encoded_text.clone()).unwrap();

write!(f, "=?{}?{}?{}?=", charset, encoding, encoded_text)
}
Expand Down
23 changes: 22 additions & 1 deletion src/lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,27 @@ const SPACE: u8 = b' ';

/// A helper struct which implements [std::fmt::Display] for `Vec<String>` and
/// which contains the encoded words which are too long as a `String`.
///
/// # Example
/// ```
/// use rfc2047_decoder::{self, decode, RecoverStrategy, LexerError};
///
/// // the first string and the third string are more than 75 characters, hence
/// // they are actually invalid encoded words
/// let message = concat![
/// "=?utf-8?B?bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb==?=",
/// "among us",
/// "=?utf-8?B?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa==?=",
/// ];

/// let result = decode(message).unwrap_err();
/// if let rfc2047_decoder::Error::Lexer(LexerError::ParseEncodedWordTooLongError(invalid_encoded_words)) = result {
/// assert_eq!(invalid_encoded_words.0[0], "=?utf-8?B?bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb==?=");
/// assert_eq!(invalid_encoded_words.0[1], "=?utf-8?B?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa==?=");
/// } else {
/// assert!(false);
/// }
/// ```
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct TooLongEncodedWords(pub Vec<String>);

Expand Down Expand Up @@ -178,7 +199,7 @@ fn get_too_long_encoded_words(tokens: &Tokens, decoder: &Decoder) -> Option<TooL
#[cfg(test)]
mod tests {
use crate::{
lexer::{encoded_word::EncodedWord, Token, run},
lexer::{encoded_word::EncodedWord, run, Token},
Decoder,
};

Expand Down
33 changes: 29 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,43 @@
#![doc(html_root_url = "https://docs.rs/rfc2047-decoder/1.0.0")]
#![doc(html_root_url = "https://docs.rs/rfc2047-decoder/1.0.1")]
//! # Introduction
//! This crate provides a [Decoder] and the function [decode], in order to
//! encoded words as described in the [RFC 2047].
//!
//! [RFC 2047]: https://datatracker.ietf.org/doc/html/rfc2047
//!
//! # Where to look
//! You will likely want to start looking into [Decoder] and/or the [decode]
//! to use this crate.

mod decoder;
pub use decoder::{Decoder, RecoverStrategy, Error};
pub use decoder::{Decoder, Error, RecoverStrategy};

mod evaluator;
mod lexer;
mod parser;

pub use lexer::{TooLongEncodedWords, Error as LexerError};
pub use parser::Error as ParserError;
pub use evaluator::Error as EvaluatorError;
pub use lexer::{Error as LexerError, TooLongEncodedWords};
pub use parser::Error as ParserError;

/// Decodes the given RFC 2047 MIME Message Header encoded string
/// using a default decoder.
///
/// This function equals doing `Decoder::new().decode`.
///
/// # Example
/// ```
/// use rfc2047_decoder::{decode, Decoder};
///
/// let encoded_message = "=?ISO-8859-1?Q?hello_there?=".as_bytes();
/// let decoded_message = "hello there";
///
/// // This ...
/// assert_eq!(decode(encoded_message).unwrap(), decoded_message);
///
/// // ... equals this:
/// assert_eq!(Decoder::new().decode(encoded_message).unwrap(), decoded_message);
/// ```
pub fn decode<T: AsRef<[u8]>>(encoded_str: T) -> Result<String, Error> {
Decoder::new().decode(encoded_str)
}
6 changes: 4 additions & 2 deletions src/parser.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use charset::Charset;
use std::{convert::TryFrom, result};

use crate::lexer::{Token, Tokens, encoded_word};
use crate::lexer::{encoded_word, Token, Tokens};

/// All errors which the parser can throw.
#[derive(thiserror::Error, Debug, Clone, PartialEq)]
Expand Down Expand Up @@ -83,7 +83,9 @@ fn convert_tokens_to_encoded_words(tokens: Tokens) -> Result<ParsedEncodedWords>
.into_iter()
.map(|token: Token| match token {
Token::ClearText(clear_text) => Ok(ParsedEncodedWord::ClearText(clear_text)),
Token::EncodedWord(encoded_word) => ParsedEncodedWord::convert_encoded_word(encoded_word),
Token::EncodedWord(encoded_word) => {
ParsedEncodedWord::convert_encoded_word(encoded_word)
}
})
.collect()
}
Expand Down
Loading