summaryrefslogtreecommitdiffstats
path: root/internals/src/bind/encoded_word/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'internals/src/bind/encoded_word/mod.rs')
-rw-r--r--internals/src/bind/encoded_word/mod.rs92
1 files changed, 92 insertions, 0 deletions
diff --git a/internals/src/bind/encoded_word/mod.rs b/internals/src/bind/encoded_word/mod.rs
new file mode 100644
index 0000000..ef61fc6
--- /dev/null
+++ b/internals/src/bind/encoded_word/mod.rs
@@ -0,0 +1,92 @@
+use soft_ascii_string::{ SoftAsciiStr, SoftAsciiChar };
+
+use super::{base64, quoted_printable};
+
+mod impls;
+pub use self::impls::*;
+
+#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
+pub enum EncodedWordEncoding {
+ Base64, QuotedPrintable
+}
+
+impl EncodedWordEncoding {
+
+ /// returns the acronym for the given encoding
+ /// used in a encoded word
+ pub fn acronym(&self) -> &'static SoftAsciiStr {
+ use self::EncodedWordEncoding::*;
+ match *self {
+ Base64 => SoftAsciiStr::from_unchecked("B"),
+ QuotedPrintable => SoftAsciiStr::from_unchecked("Q")
+ }
+ }
+
+ /// encodes a given utf8 string
+ ///
+ /// either `self::quoted_printable::encoded_word_encode`
+ /// or `self::base64::encoded_word_encode_utf8` is used
+ /// depending on which value `self` is.
+ ///
+ /// As both algorithm need to know about code point boundaries
+ /// only encoding utf8 is supported for now
+ ///
+ pub fn encode<R, O>(&self, input: R, out: &mut O)
+ where R: AsRef<str>, O: EncodedWordWriter
+ {
+ use self::EncodedWordEncoding::*;
+ let input: &str = input.as_ref();
+ match *self {
+ Base64 => {
+ base64::encoded_word_encode(input, out)
+ },
+ QuotedPrintable => {
+ quoted_printable::encoded_word_encode_utf8(input, out)
+ }
+ }
+ }
+}
+
+pub trait EncodedWordWriter {
+ fn write_char( &mut self, ch: SoftAsciiChar );
+ fn write_charset( &mut self );
+ fn encoding( &self ) -> EncodedWordEncoding;
+ fn write_ecw_seperator( &mut self );
+
+ /// Returns the maximal length of the paylod/encoded data
+ ///
+ /// Any number of calls to methods on in trait in any way
+ /// should never be able to change the returned value.
+ /// Only changing e.g. the charset or encoding should be
+ /// able to change what `max_paylod_len` returns.
+ fn max_payload_len( &self ) -> usize;
+
+ fn write_ecw_start( &mut self ) {
+ let qm = SoftAsciiChar::from_unchecked('?');
+ self.write_char(SoftAsciiChar::from_unchecked('='));
+ self.write_char(qm);
+ self.write_charset();
+ self.write_char(qm);
+ let acronym = self.encoding().acronym();
+ self.write_str( acronym );
+ self.write_char(qm);
+ }
+
+ fn write_ecw_end( &mut self ) {
+ self.write_char( SoftAsciiChar::from_unchecked('?') );
+ self.write_char( SoftAsciiChar::from_unchecked('=') );
+ }
+
+
+ fn start_next_encoded_word( &mut self ) {
+ self.write_ecw_end();
+ self.write_ecw_seperator();
+ self.write_ecw_start();
+ }
+
+ fn write_str( &mut self, s: &SoftAsciiStr ) {
+ for ch in s.chars() {
+ self.write_char(ch)
+ }
+ }
+} \ No newline at end of file