summaryrefslogtreecommitdiffstats
path: root/internals/src/encoder
diff options
context:
space:
mode:
Diffstat (limited to 'internals/src/encoder')
-rw-r--r--internals/src/encoder/encodable.rs59
-rw-r--r--internals/src/encoder/mod.rs751
-rw-r--r--internals/src/encoder/trace.rs30
3 files changed, 428 insertions, 412 deletions
diff --git a/internals/src/encoder/encodable.rs b/internals/src/encoder/encodable.rs
index ff1e29a..154fb0f 100644
--- a/internals/src/encoder/encodable.rs
+++ b/internals/src/encoder/encodable.rs
@@ -1,10 +1,10 @@
use std::any::{Any, TypeId};
use std::fmt::{self, Debug};
-use std::result::{ Result as StdResult };
+use std::result::Result as StdResult;
use std::sync::Arc;
-use ::error::EncodingError;
-use super::{EncodingWriter};
+use super::EncodingWriter;
+use error::EncodingError;
// can not be moved to `super::traits` as it depends on the
// EncodingWriter defined here
@@ -13,7 +13,7 @@ use super::{EncodingWriter};
/// This trait can be turned into a trait object allowing runtime
/// genericallity over the "components" if needed.
pub trait EncodableInHeader: Send + Sync + Any + Debug {
- fn encode(&self, encoder: &mut EncodingWriter) -> Result<(), EncodingError>;
+ fn encode(&self, encoder: &mut EncodingWriter) -> Result<(), EncodingError>;
fn boxed_clone(&self) -> Box<EncodableInHeader>;
@@ -25,17 +25,15 @@ pub trait EncodableInHeader: Send + Sync + Any + Debug {
//TODO we now could use MOPA or similar crates
impl EncodableInHeader {
-
#[inline(always)]
pub fn is<T: EncodableInHeader>(&self) -> bool {
EncodableInHeader::type_id(self) == TypeId::of::<T>()
}
-
#[inline]
pub fn downcast_ref<T: EncodableInHeader>(&self) -> Option<&T> {
if self.is::<T>() {
- Some( unsafe { &*( self as *const EncodableInHeader as *const T) } )
+ Some(unsafe { &*(self as *const EncodableInHeader as *const T) })
} else {
None
}
@@ -44,7 +42,7 @@ impl EncodableInHeader {
#[inline]
pub fn downcast_mut<T: EncodableInHeader>(&mut self) -> Option<&mut T> {
if self.is::<T>() {
- Some( unsafe { &mut *( self as *mut EncodableInHeader as *mut T) } )
+ Some(unsafe { &mut *(self as *mut EncodableInHeader as *mut T) })
} else {
None
}
@@ -52,37 +50,33 @@ impl EncodableInHeader {
}
impl Clone for Box<EncodableInHeader> {
-
fn clone(&self) -> Self {
self.boxed_clone()
}
}
-
pub trait EncodableInHeaderBoxExt: Sized {
fn downcast<T: EncodableInHeader>(self) -> StdResult<Box<T>, Self>;
}
impl EncodableInHeaderBoxExt for Box<EncodableInHeader> {
-
fn downcast<T: EncodableInHeader>(self) -> StdResult<Box<T>, Self> {
if EncodableInHeader::is::<T>(&*self) {
let ptr: *mut EncodableInHeader = Box::into_raw(self);
- Ok( unsafe { Box::from_raw(ptr as *mut T) } )
+ Ok(unsafe { Box::from_raw(ptr as *mut T) })
} else {
- Err( self )
+ Err(self)
}
}
}
-impl EncodableInHeaderBoxExt for Box<EncodableInHeader+Send> {
-
+impl EncodableInHeaderBoxExt for Box<EncodableInHeader + Send> {
fn downcast<T: EncodableInHeader>(self) -> StdResult<Box<T>, Self> {
if EncodableInHeader::is::<T>(&*self) {
let ptr: *mut EncodableInHeader = Box::into_raw(self);
- Ok( unsafe { Box::from_raw(ptr as *mut T) } )
+ Ok(unsafe { Box::from_raw(ptr as *mut T) })
} else {
- Err( self )
+ Err(self)
}
}
}
@@ -92,14 +86,14 @@ impl EncodableInHeaderBoxExt for Box<EncodableInHeader+Send> {
/// (Mainly used in the inside of tests.)
#[macro_export]
macro_rules! enc_func {
- (|$enc:ident : &mut EncodingWriter| $block:block) => ({
+ (|$enc:ident : &mut EncodingWriter| $block:block) => {{
use $crate::error::EncodingError;
fn _anonym($enc: &mut EncodingWriter) -> Result<(), EncodingError> {
$block
}
let fn_pointer = _anonym as fn(&mut EncodingWriter) -> Result<(), EncodingError>;
$crate::encoder::EncodeFn::new(fn_pointer)
- });
+ }};
}
type _EncodeFn = for<'a, 'b> fn(&'a mut EncodingWriter<'b>) -> Result<(), EncodingError>;
@@ -115,7 +109,7 @@ impl EncodeFn {
}
impl EncodableInHeader for EncodeFn {
- fn encode(&self, encoder: &mut EncodingWriter) -> Result<(), EncodingError> {
+ fn encode(&self, encoder: &mut EncodingWriter) -> Result<(), EncodingError> {
(self.0)(encoder)
}
@@ -142,12 +136,12 @@ macro_rules! enc_closure {
/// A wrapper for an closure making it implement `EncodableInHeader`.
pub struct EncodeClosure<FN: 'static>(Arc<FN>)
- where FN: Send + Sync +
- for<'a, 'b> Fn(&'a mut EncodingWriter<'b>) -> Result<(), EncodingError>;
+where
+ FN: Send + Sync + for<'a, 'b> Fn(&'a mut EncodingWriter<'b>) -> Result<(), EncodingError>;
impl<FN: 'static> EncodeClosure<FN>
- where FN: Send + Sync +
- for<'a, 'b> Fn(&'a mut EncodingWriter<'b>) -> Result<(), EncodingError>
+where
+ FN: Send + Sync + for<'a, 'b> Fn(&'a mut EncodingWriter<'b>) -> Result<(), EncodingError>,
{
pub fn new(closure: FN) -> Self {
EncodeClosure(Arc::new(closure))
@@ -155,10 +149,10 @@ impl<FN: 'static> EncodeClosure<FN>
}
impl<FN: 'static> EncodableInHeader for EncodeClosure<FN>
- where FN: Send + Sync +
- for<'a, 'b> Fn(&'a mut EncodingWriter<'b>) -> Result<(), EncodingError>
+where
+ FN: Send + Sync + for<'a, 'b> Fn(&'a mut EncodingWriter<'b>) -> Result<(), EncodingError>,
{
- fn encode(&self, encoder: &mut EncodingWriter) -> Result<(), EncodingError> {
+ fn encode(&self, encoder: &mut EncodingWriter) -> Result<(), EncodingError> {
(self.0)(encoder)
}
@@ -168,20 +162,19 @@ impl<FN: 'static> EncodableInHeader for EncodeClosure<FN>
}
impl<FN: 'static> Clone for EncodeClosure<FN>
- where FN: Send + Sync +
- for<'a, 'b> Fn(&'a mut EncodingWriter<'b>) -> Result<(), EncodingError>
+where
+ FN: Send + Sync + for<'a, 'b> Fn(&'a mut EncodingWriter<'b>) -> Result<(), EncodingError>,
{
fn clone(&self) -> Self {
EncodeClosure(self.0.clone())
}
}
-
impl<FN: 'static> Debug for EncodeClosure<FN>
- where FN: Send + Sync +
- for<'a, 'b> Fn(&'a mut EncodingWriter<'b>) -> Result<(), EncodingError>
+where
+ FN: Send + Sync + for<'a, 'b> Fn(&'a mut EncodingWriter<'b>) -> Result<(), EncodingError>,
{
fn fmt(&self, fter: &mut fmt::Formatter) -> fmt::Result {
write!(fter, "EncodeClosure(..)")
}
-} \ No newline at end of file
+}
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