mail_headers/data/
input.rs

1use std::result::{ Result as StdResult };
2use std::fmt::{self, Display};
3
4use soft_ascii_string::SoftAsciiString;
5
6use ::HeaderTryFrom;
7use ::error::ComponentCreationError;
8
9use super::inner_item::{ InnerUtf8, InnerAscii };
10
11/// a Input is similar to Item a container data container used in different
12/// context's with different restrictions, but different to an Item it
13/// might contain characters which require encoding (e.g. encoded words)
14/// to represent them
15#[derive(Debug, Clone, Hash, Eq, PartialEq)]
16pub struct Input( pub InnerUtf8 );
17
18
19impl Input {
20
21    pub fn into_shared( self ) -> Self {
22        Input( self.0.into_shared() )
23    }
24
25
26    pub fn into_ascii_item( self ) -> StdResult<InnerAscii, Input> {
27        match self {
28            Input( InnerUtf8::Owned( string ) ) => {
29                match SoftAsciiString::from_string(string) {
30                    Ok(asciied) => Ok(InnerAscii::Owned(asciied)),
31                    Err(err) => Err(Input(InnerUtf8::Owned(err.into_source())))
32                }
33            }
34            Input( InnerUtf8::Shared( shared ) ) => {
35                if shared.is_ascii() {
36                    Ok(InnerAscii::Owned(SoftAsciiString::from_unchecked(&*shared)))
37                } else {
38                    Err(Input(InnerUtf8::Shared(shared)))
39                }
40            }
41        }
42    }
43
44    pub fn into_ascii_item_unchecked( self ) -> InnerAscii {
45        match self {
46            Input( InnerUtf8::Owned( string ) ) =>
47                InnerAscii::Owned( SoftAsciiString::from_unchecked( string ) ),
48            Input( InnerUtf8::Shared( shared ) ) =>
49                InnerAscii::Owned(
50                    SoftAsciiString::from_unchecked(&*shared) )
51        }
52    }
53
54    pub fn into_utf8_item( self ) -> InnerUtf8 {
55        self.0
56    }
57}
58
59impl<'a> From<&'a str> for Input {
60    fn from( s: &'a str ) -> Self {
61        Input( InnerUtf8::Owned( s.into() ) )
62    }
63}
64
65impl From<String> for Input {
66    fn from( s: String ) -> Self {
67        Input( InnerUtf8::Owned( s ) )
68    }
69}
70
71impl<'a> HeaderTryFrom<&'a str> for Input
72{
73    fn try_from(val: &'a str) -> Result<Self, ComponentCreationError> {
74        Ok(val.into())
75    }
76}
77impl HeaderTryFrom<String> for Input
78{
79    fn try_from(val: String) -> Result<Self, ComponentCreationError> {
80        Ok(val.into())
81    }
82}
83
84impl Into<String> for Input {
85    fn into(self) -> String {
86        self.0.into()
87    }
88}
89
90impl Display for Input {
91    fn fmt(&self, fter: &mut fmt::Formatter) -> fmt::Result {
92        fter.write_str(self.as_str())
93    }
94}
95
96deref0!( +mut Input => InnerUtf8 );
97
98
99
100#[cfg(test)]
101mod test {
102    use std::sync::Arc;
103    use owning_ref::OwningRef;
104
105    use super::*;
106
107    #[test]
108    fn input_eq() {
109        let a = Input( InnerUtf8::Owned( "same".into() ) );
110        let b = Input( InnerUtf8::Shared(
111            OwningRef::new(
112                Arc::new( String::from( "same" ) ) )
113                .map(|v| &**v)
114        ) );
115        assert_eq!( a, b );
116    }
117
118    #[test]
119    fn input_neq() {
120        let a = Input( InnerUtf8::Owned( "not same".into() ) );
121        let b = Input( InnerUtf8::Shared(
122            OwningRef::new(
123                Arc::new( String::from( "not at all same" ) ) )
124                .map(|v| &**v)
125        ) );
126        assert_ne!( a, b );
127    }
128
129
130
131}