summaryrefslogtreecommitdiffstats
path: root/internals/src/encoder/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'internals/src/encoder/mod.rs')
-rw-r--r--internals/src/encoder/mod.rs751
1 files changed, 392 insertions, 359 deletions
diff --git a/internals/src/encoder/mod.rs b/internals/src/encoder/mod.rs
index 760da2f..61a710d 100644
--- a/internals/src/encoder/mod.rs
+++ b/internals/src/encoder/mod.rs
@@ -18,29 +18,22 @@ use std::borrow::Cow;
use std::str;
use failure::Fail;
-use soft_ascii_string::{SoftAsciiStr, SoftAsciiChar};
+use soft_ascii_string::{SoftAsciiChar, SoftAsciiStr};
+use error::{EncodingError, EncodingErrorKind, UNKNOWN, US_ASCII, UTF_8};
use grammar::is_atext;
-use ::utils::{
- is_utf8_continuation_byte,
- vec_insert_bytes
-};
-use ::MailType;
-use ::error::{
- EncodingError, EncodingErrorKind,
- UNKNOWN, UTF_8, US_ASCII
-};
-
-#[cfg(feature="traceing")]
-#[cfg_attr(test, macro_use)]
-mod trace;
+use utils::{is_utf8_continuation_byte, vec_insert_bytes};
+use MailType;
+
#[cfg_attr(test, macro_use)]
mod encodable;
+#[cfg(feature = "traceing")]
+#[cfg_attr(test, macro_use)]
+mod trace;
-
-#[cfg(feature="traceing")]
-pub use self::trace::*;
pub use self::encodable::*;
+#[cfg(feature = "traceing")]
+pub use self::trace::*;
/// as specified in RFC 5322 not including CRLF
pub const LINE_LEN_SOFT_LIMIT: usize = 78;
@@ -50,29 +43,27 @@ pub const LINE_LEN_HARD_LIMIT: usize = 998;
pub const NEWLINE: &str = "\r\n";
pub const NEWLINE_WITH_SPACE: &str = "\r\n ";
-
/// EncodingBuffer for a Mail providing a buffer for encodable traits.
pub struct EncodingBuffer {
mail_type: MailType,
buffer: Vec<u8>,
- #[cfg(feature="traceing")]
- pub trace: Vec<TraceToken>
+ #[cfg(feature = "traceing")]
+ pub trace: Vec<TraceToken>,
}
impl EncodingBuffer {
-
/// Create a new buffer only allowing input compatible with a the specified mail type.
pub fn new(mail_type: MailType) -> Self {
EncodingBuffer {
mail_type,
buffer: Vec::new(),
- #[cfg(feature="traceing")]
- trace: Vec::new()
+ #[cfg(feature = "traceing")]
+ trace: Vec::new(),
}
}
/// Returns the mail type for which the buffer was created.
- pub fn mail_type( &self ) -> MailType {
+ pub fn mail_type(&self) -> MailType {
self.mail_type
}
@@ -80,11 +71,11 @@ impl EncodingBuffer {
/// a mutable reference to the current string buffer
///
pub fn writer(&mut self) -> EncodingWriter {
- #[cfg(not(feature="traceing"))]
+ #[cfg(not(feature = "traceing"))]
{
EncodingWriter::new(self.mail_type, &mut self.buffer)
}
- #[cfg(feature="traceing")]
+ #[cfg(feature = "traceing")]
{
EncodingWriter::new(self.mail_type, &mut self.buffer, &mut self.trace)
}
@@ -98,27 +89,29 @@ impl EncodingBuffer {
/// writes
/// - if `func` succeeded `handle.finish_header()` is called
pub fn write_header_line<FN>(&mut self, func: FN) -> Result<(), EncodingError>
- where FN: FnOnce(&mut EncodingWriter) -> Result<(), EncodingError>
+ where
+ FN: FnOnce(&mut EncodingWriter) -> Result<(), EncodingError>,
{
- let mut handle = self.writer();
+ let mut handle = self.writer();
match func(&mut handle) {
Ok(()) => {
handle.finish_header();
Ok(())
- },
+ }
Err(e) => {
handle.undo_header();
Err(e)
}
}
-
}
pub fn write_blank_line(&mut self) {
//TODO/BENCH push_str vs. extends(&[u8])
self.buffer.extend(NEWLINE.as_bytes());
- #[cfg(feature="traceing")]
- { self.trace.push(TraceToken::BlankLine); }
+ #[cfg(feature = "traceing")]
+ {
+ self.trace.push(TraceToken::BlankLine);
+ }
}
/// writes a body to the internal buffer, without verifying it's correctness
@@ -142,16 +135,15 @@ impl EncodingBuffer {
///
/// This can fail if a body does not contain valid utf8.
pub fn as_str(&self) -> Result<&str, EncodingError> {
- str::from_utf8(self.buffer.as_slice())
- .map_err(|err| {
- EncodingError::from((
- err.context(EncodingErrorKind::InvalidTextEncoding {
- expected_encoding: UTF_8,
- got_encoding: UNKNOWN
- }),
- self.mail_type()
- ))
- })
+ str::from_utf8(self.buffer.as_slice()).map_err(|err| {
+ EncodingError::from((
+ err.context(EncodingErrorKind::InvalidTextEncoding {
+ expected_encoding: UTF_8,
+ got_encoding: UNKNOWN,
+ }),
+ self.mail_type(),
+ ))
+ })
}
/// Converts the internal buffer into an utf-8 string if possible.
@@ -168,10 +160,8 @@ impl EncodingBuffer {
pub fn as_slice(&self) -> &[u8] {
&self.buffer
}
-
}
-
impl Into<Vec<u8>> for EncodingBuffer {
fn into(self) -> Vec<u8> {
self.buffer
@@ -184,10 +174,14 @@ impl Into<(MailType, Vec<u8>)> for EncodingBuffer {
}
}
-#[cfg(feature="traceing")]
+#[cfg(feature = "traceing")]
impl Into<(MailType, Vec<u8>, Vec<TraceToken>)> for EncodingBuffer {
fn into(self) -> (MailType, Vec<u8>, Vec<TraceToken>) {
- let EncodingBuffer { mail_type, buffer, trace } = self;
+ let EncodingBuffer {
+ mail_type,
+ buffer,
+ trace,
+ } = self;
(mail_type, buffer, trace)
}
}
@@ -211,7 +205,7 @@ impl Into<(MailType, Vec<u8>, Vec<TraceToken>)> for EncodingBuffer {
///
pub struct EncodingWriter<'a> {
buffer: &'a mut Vec<u8>,
- #[cfg(feature="traceing")]
+ #[cfg(feature = "traceing")]
trace: &'a mut Vec<TraceToken>,
mail_type: MailType,
line_start_idx: usize,
@@ -228,16 +222,15 @@ pub struct EncodingWriter<'a> {
/// represents if if a FWS was just marked (opt-FWS) or was written out
last_fws_has_char: bool,
header_start_idx: usize,
- #[cfg(feature="traceing")]
- trace_start_idx: usize
+ #[cfg(feature = "traceing")]
+ trace_start_idx: usize,
}
-#[cfg(feature="traceing")]
+#[cfg(feature = "traceing")]
impl<'a> Drop for EncodingWriter<'a> {
-
fn drop(&mut self) {
use std::thread;
- if !thread::panicking() && self.has_unfinished_parts() {
+ if !thread::panicking() && self.has_unfinished_parts() {
// we really should panic as the back buffer i.e. the mail will contain
// some partially written header which definitely is a bug
panic!("dropped Handle which partially wrote header to back buffer (use `finish_header` or `discard`)")
@@ -246,12 +239,8 @@ impl<'a> Drop for EncodingWriter<'a> {
}
impl<'inner> EncodingWriter<'inner> {
-
- #[cfg(not(feature="traceing"))]
- fn new(
- mail_type: MailType,
- buffer: &'inner mut Vec<u8>,
- ) -> Self {
+ #[cfg(not(feature = "traceing"))]
+ fn new(mail_type: MailType, buffer: &'inner mut Vec<u8>) -> Self {
let start_idx = buffer.len();
EncodingWriter {
buffer,
@@ -266,11 +255,11 @@ impl<'inner> EncodingWriter<'inner> {
}
}
- #[cfg(feature="traceing")]
+ #[cfg(feature = "traceing")]
fn new(
mail_type: MailType,
buffer: &'inner mut Vec<u8>,
- trace: &'inner mut Vec<TraceToken>
+ trace: &'inner mut Vec<TraceToken>,
) -> Self {
let start_idx = buffer.len();
let trace_start_idx = trace.len();
@@ -285,7 +274,7 @@ impl<'inner> EncodingWriter<'inner> {
content_before_fws: false,
header_start_idx: start_idx,
last_fws_has_char: false,
- trace_start_idx
+ trace_start_idx,
}
}
@@ -297,8 +286,10 @@ impl<'inner> EncodingWriter<'inner> {
self.content_since_fws = false;
self.content_before_fws = false;
self.header_start_idx = start_idx;
- #[cfg(feature="traceing")]
- { self.trace_start_idx = self.trace.len(); }
+ #[cfg(feature = "traceing")]
+ {
+ self.trace_start_idx = self.trace.len();
+ }
}
/// Returns true if this type thinks we are in the process of writing a header.
@@ -331,8 +322,10 @@ impl<'inner> EncodingWriter<'inner> {
/// # Trace (test build only)
/// does push a `MarkFWS` Token
pub fn mark_fws_pos(&mut self) {
- #[cfg(feature="traceing")]
- { self.trace.push(TraceToken::MarkFWS) }
+ #[cfg(feature = "traceing")]
+ {
+ self.trace.push(TraceToken::MarkFWS)
+ }
self.content_before_fws |= self.content_since_fws;
self.content_since_fws = false;
self.last_fws_idx = self.buffer.len();
@@ -348,9 +341,11 @@ impl<'inner> EncodingWriter<'inner> {
///
/// # Trace (test build only)
/// does push `NowChar` and then can push `Text`,`CRLF`
- pub fn write_char(&mut self, ch: SoftAsciiChar) -> Result<(), EncodingError> {
- #[cfg(feature="traceing")]
- { self.trace.push(TraceToken::NowChar) }
+ pub fn write_char(&mut self, ch: SoftAsciiChar) -> Result<(), EncodingError> {
+ #[cfg(feature = "traceing")]
+ {
+ self.trace.push(TraceToken::NowChar)
+ }
let mut buffer = [0xff_u8; 4];
let ch: char = ch.into();
let slice = ch.encode_utf8(&mut buffer);
@@ -372,13 +367,14 @@ impl<'inner> EncodingWriter<'inner> {
/// # Trace (test build only)
/// does push `NowStr` and then can push `Text`,`CRLF`
///
- pub fn write_str(&mut self, s: &SoftAsciiStr) -> Result<(), EncodingError> {
- #[cfg(feature="traceing")]
- { self.trace.push(TraceToken::NowStr) }
+ pub fn write_str(&mut self, s: &SoftAsciiStr) -> Result<(), EncodingError> {
+ #[cfg(feature = "traceing")]
+ {
+ self.trace.push(TraceToken::NowStr)
+ }
self.internal_write_str(s.as_str())
}
-
/// writes a utf8 str into a buffer for an internationalized mail
///
/// # Error (ConditionalWriteResult)
@@ -394,12 +390,15 @@ impl<'inner> EncodingWriter<'inner> {
///
/// # Trace (test build only)
/// does push `NowUtf8` and then can push `Text`,`CRLF`
- pub fn write_if_utf8<'short>(&'short mut self, s: &str)
- -> ConditionalWriteResult<'short, 'inner>
- {
+ pub fn write_if_utf8<'short>(
+ &'short mut self,
+ s: &str,
+ ) -> ConditionalWriteResult<'short, 'inner> {
if self.mail_type().is_internationalized() {
- #[cfg(feature="traceing")]
- { self.trace.push(TraceToken::NowUtf8) }
+ #[cfg(feature = "traceing")]
+ {
+ self.trace.push(TraceToken::NowUtf8)
+ }
self.internal_write_str(s).into()
} else {
ConditionalWriteResult::ConditionFailure(self)
@@ -408,16 +407,18 @@ impl<'inner> EncodingWriter<'inner> {
pub fn write_utf8(&mut self, s: &str) -> Result<(), EncodingError> {
if self.mail_type().is_internationalized() {
- #[cfg(feature="traceing")]
- { self.trace.push(TraceToken::NowUtf8) }
+ #[cfg(feature = "traceing")]
+ {
+ self.trace.push(TraceToken::NowUtf8)
+ }
self.internal_write_str(s)
} else {
let mut err = EncodingError::from((
EncodingErrorKind::InvalidTextEncoding {
expected_encoding: US_ASCII,
- got_encoding: UTF_8
+ got_encoding: UTF_8,
},
- self.mail_type()
+ self.mail_type(),
));
let raw_line = &self.buffer[self.line_start_idx..];
let mut line = String::from_utf8_lossy(raw_line).into_owned();
@@ -454,12 +455,15 @@ impl<'inner> EncodingWriter<'inner> {
/// # Trace (test build only)
/// does push `NowAText` and then can push `Text`
///
- pub fn write_if_atext<'short>(&'short mut self, s: &str)
- -> ConditionalWriteResult<'short, 'inner>
- {
- if s.chars().all( |ch| is_atext( ch, self.mail_type() ) ) {
- #[cfg(feature="traceing")]
- { self.trace.push(TraceToken::NowAText) }
+ pub fn write_if_atext<'short>(
+ &'short mut self,
+ s: &str,
+ ) -> ConditionalWriteResult<'short, 'inner> {
+ if s.chars().all(|ch| is_atext(ch, self.mail_type())) {
+ #[cfg(feature = "traceing")]
+ {
+ self.trace.push(TraceToken::NowAText)
+ }
// the ascii or not aspect is already converted by `is_atext`
self.internal_write_str(s).into()
} else {
@@ -471,13 +475,19 @@ impl<'inner> EncodingWriter<'inner> {
/// then writes it _without additional checks_ to the buffer if `cond` returned
/// true
///
- pub fn write_if<'short, FN>(&'short mut self, s: &str, cond: FN)
- -> ConditionalWriteResult<'short, 'inner>
- where FN: FnOnce(&str) -> bool
+ pub fn write_if<'short, FN>(
+ &'short mut self,
+ s: &str,
+ cond: FN,
+ ) -> ConditionalWriteResult<'short, 'inner>
+ where
+ FN: FnOnce(&str) -> bool,
{
if cond(s) {
- #[cfg(feature="traceing")]
- { self.trace.push(TraceToken::NowCondText) }
+ #[cfg(feature = "traceing")]
+ {
+ self.trace.push(TraceToken::NowCondText)
+ }
// the ascii or not aspect is already converted by `is_atext`
self.internal_write_str(s).into()
} else {
@@ -509,9 +519,11 @@ impl<'inner> EncodingWriter<'inner> {
///
/// through is gives a different tracing its roughly equivalent.
///
- pub fn write_str_unchecked( &mut self, s: &str) -> Result<(), EncodingError> {
- #[cfg(feature="traceing")]
- { self.trace.push(TraceToken::NowUnchecked) }
+ pub fn write_str_unchecked(&mut self, s: &str) -> Result<(), EncodingError> {
+ #[cfg(feature = "traceing")]
+ {
+ self.trace.push(TraceToken::NowUnchecked)
+ }
self.internal_write_str(s)
}
@@ -523,9 +535,13 @@ impl<'inner> EncodingWriter<'inner> {
/// is written correctly. So you _normally_ should
/// not use it.
pub fn commit_partial_header(&mut self) {
- #[cfg(feature="traceing")]
- { if let Some(&TraceToken::End) = self.trace.last() {}
- else { self.trace.push(TraceToken::End) } }
+ #[cfg(feature = "traceing")]
+ {
+ if let Some(&TraceToken::End) = self.trace.last() {
+ } else {
+ self.trace.push(TraceToken::End)
+ }
+ }
self.reinit();
}
@@ -548,9 +564,13 @@ impl<'inner> EncodingWriter<'inner> {
/// will not generate multiple `End` tokens, just one
pub fn finish_header(&mut self) {
self.start_new_line();
- #[cfg(feature="traceing")]
- { if let Some(&TraceToken::End) = self.trace.last() {}
- else { self.trace.push(TraceToken::End) } }
+ #[cfg(feature = "traceing")]
+ {
+ if let Some(&TraceToken::End) = self.trace.last() {
+ } else {
+ self.trace.push(TraceToken::End)
+ }
+ }
self.reinit();
}
@@ -565,13 +585,13 @@ impl<'inner> EncodingWriter<'inner> {
///
pub fn undo_header(&mut self) {
self.buffer.truncate(self.header_start_idx);
- #[cfg(feature="traceing")]
- { self.trace.truncate(self.trace_start_idx); }
+ #[cfg(feature = "traceing")]
+ {
+ self.trace.truncate(self.trace_start_idx);
+ }
self.reinit();
}
-
-
//---------------------------------------------------------------------------------------------/
//-/////////////////////////// methods only using the public iface /////////////////////////-/
@@ -594,8 +614,6 @@ impl<'inner> EncodingWriter<'inner> {
let _ = self.write_char(SoftAsciiChar::from_unchecked(' '));
}
-
-
//---------------------------------------------------------------------------------------------/
//-/////////////////////////// private methods ////////////////////////-/
@@ -603,7 +621,7 @@ impl<'inner> EncodingWriter<'inner> {
/// while we could implement a undo option it makes
/// little sense for the use case the generally available
/// `undo_header` is enough.
- fn internal_write_str(&mut self, s: &str) -> Result<(), EncodingError> {
+ fn internal_write_str(&mut self, s: &str) -> Result<(), EncodingError> {
if s.is_empty() {
return Ok(());
}
@@ -631,13 +649,15 @@ impl<'inner> EncodingWriter<'inner> {
/// removing the blank line (not that WS are only ' ' and '\r')
fn start_new_line(&mut self) {
if self.line_has_content() {
- #[cfg(feature="traceing")]
- { self.trace.push(TraceToken::CRLF) }
+ #[cfg(feature = "traceing")]
+ {
+ self.trace.push(TraceToken::CRLF)
+ }
self.buffer.push(b'\r');
self.buffer.push(b'\n');
} else {
- #[cfg(feature="traceing")]
+ #[cfg(feature = "traceing")]
{
if self.buffer.len() > self.line_start_idx {
self.trace.push(TraceToken::TruncateToCRLF);
@@ -653,18 +673,16 @@ impl<'inner> EncodingWriter<'inner> {
self.content_since_fws = false;
self.content_before_fws = false;
self.last_fws_idx = self.line_start_idx;
-
}
fn break_line_on_fws(&mut self) -> bool {
if self.content_before_fws && self.last_fws_idx > self.line_start_idx {
- let newline =
- if self.last_fws_has_char {
- debug_assert!([b' ', b'\t'].contains(&self.buffer[self.last_fws_idx]));
- NEWLINE
- } else {
- NEWLINE_WITH_SPACE
- };
+ let newline = if self.last_fws_has_char {
+ debug_assert!([b' ', b'\t'].contains(&self.buffer[self.last_fws_idx]));
+ NEWLINE
+ } else {
+ NEWLINE_WITH_SPACE
+ };
vec_insert_bytes(&mut self.buffer, self.last_fws_idx, newline.as_bytes());
self.line_start_idx = self.last_fws_idx + 2;
@@ -732,7 +750,7 @@ impl<'inner> EncodingWriter<'inner> {
}
self.buffer.extend(unchecked_utf8_char.as_bytes());
- #[cfg(feature="traceing")]
+ #[cfg(feature = "traceing")]
{
//FIXME[rust/nll]: just use a `if let`-`else` with NLL's
let need_new =
@@ -747,7 +765,6 @@ impl<'inner> EncodingWriter<'inner> {
string.push_str(unchecked_utf8_char);
self.trace.push(TraceToken::Text(string))
}
-
}
// we can't allow "blank" lines
@@ -763,53 +780,47 @@ impl<'inner> EncodingWriter<'inner> {
pub enum ConditionalWriteResult<'a, 'b: 'a> {
Ok,
ConditionFailure(&'a mut EncodingWriter<'b>),
- GeneralFailure(EncodingError)
+ GeneralFailure(EncodingError),
}
impl<'a, 'b: 'a> From<Result<(), EncodingError>> for ConditionalWriteResult<'a, 'b> {
fn from(v: Result<(), EncodingError>) -> Self {
match v {
Ok(()) => ConditionalWriteResult::Ok,
- Err(e) => ConditionalWriteResult::GeneralFailure(e)
+ Err(e) => ConditionalWriteResult::GeneralFailure(e),
}
}
}
impl<'a, 'b: 'a> ConditionalWriteResult<'a, 'b> {
-
#[inline]
pub fn handle_condition_failure<FN>(self, func: FN) -> Result<(), EncodingError>
- where FN: FnOnce(&mut EncodingWriter) -> Result<(), EncodingError>
+ where
+ FN: FnOnce(&mut EncodingWriter) -> Result<(), EncodingError>,
{
use self::ConditionalWriteResult as CWR;
match self {
CWR::Ok => Ok(()),
- CWR::ConditionFailure(handle) => {
- func(handle)
- },
- CWR::GeneralFailure(err) => Err(err)
+ CWR::ConditionFailure(handle) => func(handle),
+ CWR::GeneralFailure(err) => Err(err),
}
}
}
-
-
-
-
#[cfg(test)]
mod test {
- use soft_ascii_string::{ SoftAsciiChar, SoftAsciiStr};
- use ::MailType;
- use ::error::EncodingErrorKind;
+ use error::EncodingErrorKind;
+ use soft_ascii_string::{SoftAsciiChar, SoftAsciiStr};
+ use MailType;
+ use super::EncodingBuffer as _Encoder;
use super::TraceToken::*;
- use super::{EncodingBuffer as _Encoder};
mod test_test_utilities {
- use encoder::TraceToken::*;
use super::super::simplify_trace_tokens;
+ use encoder::TraceToken::*;
#[test]
fn does_simplify_tokens_strip_nows() {
@@ -827,21 +838,23 @@ mod test {
Text("up!".into()),
CRLF,
NowAText,
- Text("abc".into())
+ Text("abc".into()),
];
let out = simplify_trace_tokens(inp);
- assert_eq!(out, vec![
- Text("h".into()),
- CRLF,
- Text("y yo".into()),
- CRLF,
- Text(", what's".into()),
- CRLF,
- Text("up!".into()),
- CRLF,
- Text("abc".into())
- ])
-
+ assert_eq!(
+ out,
+ vec![
+ Text("h".into()),
+ CRLF,
+ Text("y yo".into()),
+ CRLF,
+ Text(", what's".into()),
+ CRLF,
+ Text("up!".into()),
+ CRLF,
+ Text("abc".into())
+ ]
+ )
}
#[test]
@@ -856,53 +869,36 @@ mod test {
NowUnchecked,
Text(" up! ".into()),
NowAText,
- Text("abc".into())
+ Text("abc".into()),
];
let out = simplify_trace_tokens(inp);
- assert_eq!(out, vec![
- Text("hy yo, what's up! abc".into())
- ]);
+ assert_eq!(out, vec![Text("hy yo, what's up! abc".into())]);
}
#[test]
fn simplify_works_with_empty_text() {
- let inp = vec![
- NowStr,
- Text("".into()),
- CRLF,
- ];
- assert_eq!(simplify_trace_tokens(inp), vec![
- Text("".into()),
- CRLF
- ])
+ let inp = vec![NowStr, Text("".into()), CRLF];
+ assert_eq!(simplify_trace_tokens(inp), vec![Text("".into()), CRLF])
}
#[test]
fn simplify_works_with_trailing_empty_text() {
- let inp = vec![
- Text("a".into()),
- CRLF,
- Text("".into()),
- ];
- assert_eq!(simplify_trace_tokens(inp), vec![
- Text("a".into()),
- CRLF,
- Text("".into())
- ])
+ let inp = vec![Text("a".into()), CRLF, Text("".into())];
+ assert_eq!(
+ simplify_trace_tokens(inp),
+ vec![Text("a".into()), CRLF, Text("".into())]
+ )
}
-
}
mod EncodableInHeader {
#![allow(non_snake_case)]
- use super::super::*;
use self::TraceToken::*;
+ use super::super::*;
#[test]
fn is_implemented_for_closures() {
- let closure = enc_func!(|handle: &mut EncodingWriter| {
- handle.write_utf8("hy ho")
- });
+ let closure = enc_func!(|handle: &mut EncodingWriter| { handle.write_utf8("hy ho") });
let mut encoder = EncodingBuffer::new(MailType::Internationalized);
{
@@ -910,20 +906,17 @@ mod test {
assert_ok!(closure.encode(&mut handle));
handle.finish_header();
}
- assert_eq!(encoder.trace.as_slice(), &[
- NowUtf8,
- Text("hy ho".into()),
- CRLF,
- End
- ])
+ assert_eq!(
+ encoder.trace.as_slice(),
+ &[NowUtf8, Text("hy ho".into()), CRLF, End]
+ )
}
}
-
mod EncodingBuffer {
#![allow(non_snake_case)]
+ use super::_Encoder as EncodingBuffer;
use super::*;
- use super::{ _Encoder as EncodingBuffer };
#[test]
fn new_encoder() {
@@ -943,23 +936,18 @@ mod test {
assert_eq!(
encoder.as_slice(),
- concat!(
- "una body\r\n",
- "\r\n",
- "another body\r\n"
- ).as_bytes()
+ concat!("una body\r\n", "\r\n", "another body\r\n").as_bytes()
)
}
}
-
mod EncodingWriter {
#![allow(non_snake_case)]
use std::mem;
use std::str;
+ use super::_Encoder as EncodingBuffer;
use super::*;
- use super::{ _Encoder as EncodingBuffer };
#[test]
fn commit_partial_and_drop_does_not_panic() {
@@ -977,8 +965,7 @@ mod test {
let mut encoder = EncodingBuffer::new(MailType::Ascii);
{
let mut handle = encoder.writer();
- assert_ok!(
- handle.write_str(SoftAsciiStr::from_unchecked("Header-One: 12")));
+ assert_ok!(handle.write_str(SoftAsciiStr::from_unchecked("Header-One: 12")));
handle.undo_header();
}
assert_eq!(encoder.as_slice(), b"");
@@ -1024,19 +1011,22 @@ mod test {
let mut encoder = EncodingBuffer::new(MailType::Ascii);
{
let mut handle = encoder.writer();
- assert_ok!(handle.write_str(SoftAsciiStr::from_str("Header-One: 12\r\n ").unwrap()));
+ assert_ok!(
+ handle.write_str(SoftAsciiStr::from_str("Header-One: 12\r\n ").unwrap())
+ );
handle.finish_header();
}
assert_eq!(encoder.as_slice(), b"Header-One: 12\r\n");
}
-
#[test]
fn finish_can_handle_fws() {
let mut encoder = EncodingBuffer::new(MailType::Ascii);
{
let mut handle = encoder.writer();
- assert_ok!(handle.write_str(SoftAsciiStr::from_str("Header-One: 12 +\r\n 4").unwrap()));
+ assert_ok!(
+ handle.write_str(SoftAsciiStr::from_str("Header-One: 12 +\r\n 4").unwrap())
+ );
handle.finish_header();
}
assert_eq!(encoder.as_slice(), b"Header-One: 12 +\r\n 4\r\n");
@@ -1047,14 +1037,14 @@ mod test {
let mut encoder = EncodingBuffer::new(MailType::Ascii);
{
let mut handle = encoder.writer();
- assert_ok!(handle.write_str(
- SoftAsciiStr::from_str("Header-One: 12 +\r\n 4 ").unwrap()));
+ assert_ok!(
+ handle.write_str(SoftAsciiStr::from_str("Header-One: 12 +\r\n 4 ").unwrap())
+ );
handle.finish_header();
}
assert_eq!(encoder.as_slice(), b"Header-One: 12 +\r\n 4 \r\n");
}
-
#[test]
fn orphan_lf_error() {
let mut encoder = EncodingBuffer::new(MailType::Ascii);
@@ -1097,7 +1087,7 @@ mod test {
assert_eq!(encoder.as_slice(), b"H: a\r\n");
}
- #[test]
+ #[test]
fn soft_line_limit_can_be_breached() {
let mut encoder = EncodingBuffer::new(MailType::Ascii);
{
@@ -1130,15 +1120,18 @@ mod test {
let mut handle = encoder.writer();
assert_ok!(handle.write_str(SoftAsciiStr::from_str("A23456789:").unwrap()));
handle.mark_fws_pos();
- assert_ok!(handle.write_str(SoftAsciiStr::from_str(concat!(
- "20_3456789",
- "30_3456789",
- "40_3456789",
- "50_3456789",
- "60_3456789",
- "70_3456789",
- "12345678XX"
- )).unwrap()));
+ assert_ok!(handle.write_str(
+ SoftAsciiStr::from_str(concat!(
+ "20_3456789",
+ "30_3456789",
+ "40_3456789",
+ "50_3456789",
+ "60_3456789",
+ "70_3456789",
+ "12345678XX"
+ ))
+ .unwrap()
+ ));
handle.finish_header();
}
assert_eq!(
@@ -1163,15 +1156,18 @@ mod test {
let mut handle = encoder.writer();
assert_ok!(handle.write_str(SoftAsciiStr::from_str("A23456789:").unwrap()));
handle.write_fws();
- assert_ok!(handle.write_str(SoftAsciiStr::from_str(concat!(
- "20_3456789",
- "30_3456789",
- "40_3456789",
- "50_3456789",
- "60_3456789",
- "70_3456789",
- "12345678XX"
- )).unwrap()));
+ assert_ok!(handle.write_str(
+ SoftAsciiStr::from_str(concat!(
+ "20_3456789",
+ "30_3456789",
+ "40_3456789",
+ "50_3456789",
+ "60_3456789",
+ "70_3456789",
+ "12345678XX"
+ ))
+ .unwrap()
+ ));
handle.finish_header();
}
@@ -1190,7 +1186,6 @@ mod test {
);
}
-
#[test]
fn to_long_unbreakable_line() {
let mut encoder = EncodingBuffer::new(MailType::Ascii);
@@ -1198,18 +1193,21 @@ mod test {
let mut handle = encoder.writer();
assert_ok!(handle.write_str(SoftAsciiStr::from_str("A23456789:").unwrap()));
handle.mark_fws_pos();
- assert_ok!(handle.write_str(SoftAsciiStr::from_str(concat!(
- "10_3456789",
- "20_3456789",
- "30_3456789",
- "40_3456789",
- "50_3456789",
- "60_3456789",
- "70_3456789",
- "80_3456789",
- "90_3456789",
- "00_3456789",
- )).unwrap()));
+ assert_ok!(handle.write_str(
+ SoftAsciiStr::from_str(concat!(
+ "10_3456789",
+ "20_3456789",
+ "30_3456789",
+ "40_3456789",
+ "50_3456789",
+ "60_3456789",
+ "70_3456789",
+ "80_3456789",
+ "90_3456789",
+ "00_3456789",
+ ))
+ .unwrap()
+ ));
handle.finish_header();
}
assert_eq!(
@@ -1237,22 +1235,28 @@ mod test {
let mut handle = encoder.writer();
assert_ok!(handle.write_str(SoftAsciiStr::from_str("A23456789:").unwrap()));
handle.mark_fws_pos();
- assert_ok!(handle.write_str(SoftAsciiStr::from_str(concat!(
- "10_3456789",
- "20_3456789",
- "30_3456789",
- "40_3456789",
- "50_3456789",
- "60_3456789",
- "70_3456789",
- )).unwrap()));
+ assert_ok!(handle.write_str(
+ SoftAsciiStr::from_str(concat!(
+ "10_3456789",
+ "20_3456789",
+ "30_3456789",
+ "40_3456789",
+ "50_3456789",
+ "60_3456789",
+ "70_3456789",
+ ))
+ .unwrap()
+ ));
handle.mark_fws_pos();
- assert_ok!(handle.write_str(SoftAsciiStr::from_str(concat!(
- "10_3456789",
- "20_3456789",
- "30_3456789",
- "40_3456789",
- )).unwrap()));
+ assert_ok!(handle.write_str(
+ SoftAsciiStr::from_str(concat!(
+ "10_3456789",
+ "20_3456789",
+ "30_3456789",
+ "40_3456789",
+ ))
+ .unwrap()
+ ));
handle.finish_header();
}
assert_eq!(
@@ -1281,18 +1285,24 @@ mod test {
let mut handle = encoder.writer();
for x in 0..998 {
if let Err(_) = handle.write_char(SoftAsciiChar::from_unchecked('X')) {
- panic!("error when writing char nr.: {:?}", x+1)
+ panic!("error when writing char nr.: {:?}", x + 1)
}
}
let res = &[
- handle.write_char(SoftAsciiChar::from_unchecked('X')).is_err(),
- handle.write_char(SoftAsciiChar::from_unchecked('X')).is_err(),
- handle.write_char(SoftAsciiChar::from_unchecked('X')).is_err(),
- handle.write_char(SoftAsciiChar::from_unchecked('X')).is_err(),
+ handle
+ .write_char(SoftAsciiChar::from_unchecked('X'))
+ .is_err(),
+ handle
+ .write_char(SoftAsciiChar::from_unchecked('X'))
+ .is_err(),
+ handle
+ .write_char(SoftAsciiChar::from_unchecked('X'))
+ .is_err(),
+ handle
+ .write_char(SoftAsciiChar::from_unchecked('X'))
+ .is_err(),
];
- assert_eq!(
- res, &[true, true, true, true]
- );
+ assert_eq!(res, &[true, true, true, true]);
handle.undo_header();
}
}
@@ -1333,14 +1343,18 @@ mod test {
let mut encoder = EncodingBuffer::new(MailType::Ascii);
{
let mut handle = encoder.writer();
- assert_ok!(handle.write_if_atext("hoho")
- .handle_condition_failure(|_|panic!("no condition failur expected")));
+ assert_ok!(handle
+ .write_if_atext("hoho")
+ .handle_condition_failure(|_| panic!("no condition failur expected")));
let mut had_cond_failure = false;
- assert_ok!(handle.write_if_atext("a(b")
- .handle_condition_failure(|_| {had_cond_failure=true; Ok(())}));
+ assert_ok!(handle.write_if_atext("a(b").handle_condition_failure(|_| {
+ had_cond_failure = true;
+ Ok(())
+ }));
assert!(had_cond_failure);
- assert_ok!(handle.write_if_atext("")
-