pub fn parse_header(raw_data: &[u8]) -> Result<(MailHeader, usize), MailParseError> {
    let mut it = raw_data.iter();
    let mut ix = 0;
    let mut c = match it.next() {
        None => return Err(MailParseError::Generic("Empty string provided")),
        Some(v) => *v,
    };

    let mut ix_key_end = None;
    let mut ix_value_start = 0;
    let mut ix_value_end = 0;

    let mut state = HeaderParseState::Initial;
    loop {
        match state {
            HeaderParseState::Initial => {
                if c == b' ' {
                    return Err(MailParseError::Generic(
                        "Header cannot start with a space; it is \
                         likely an overhanging line from a \
                         previous header",
                    ));
                };
                state = HeaderParseState::Key;
                continue;
            }
            HeaderParseState::Key => {
                if c == b':' {
                    ix_key_end = Some(ix);
                    state = HeaderParseState::PreValue;
                } else if c == b'\n' {
                    // Technically this is invalid. We'll handle it gracefully
                    // since it does appear to happen in the wild and other
                    // MTAs deal with it. Our handling is to just treat everything
                    // encountered so far on this line as the header key, and
                    // leave the value empty.
                    ix_key_end = Some(ix);
                    ix_value_start = ix;
                    ix_value_end = ix;
                    ix += 1;
                    break;
                }
            }
            HeaderParseState::PreValue => {
                if c != b' ' {
                    ix_value_start = ix;
                    ix_value_end = ix;
                    state = HeaderParseState::Value;
                    continue;
                }
            }
            HeaderParseState::Value => {
                if c == b'\n' {
                    state = HeaderParseState::ValueNewline;
                } else if c != b'\r' {
                    ix_value_end = ix + 1;
                }
            }
            HeaderParseState::ValueNewline => {
                if c == b' ' || c == b'\t' {
                    state = HeaderParseState::Value;
                    continue;
                } else {
                    break;
                }
            }
        }
        ix += 1;
        c = match it.next() {
            None => break,
            Some(v) => *v,
        };
    }
    match ix_key_end {
        Some(v) => Ok((
            MailHeader {
                key: &raw_data[0..v],
                value: &raw_data[ix_value_start..ix_value_end],
            },
            ix,
        )),

        None => Ok((
            // Technically this is invalid. We'll handle it gracefully
            // since we handle the analogous situation above. Our handling
            // is to just treat everything encountered on this line as
            // the header key, and leave the value empty.
            MailHeader {
                key: &raw_data[0..ix],
                value: &raw_data[ix..ix],
            },
            ix,
        )),
    }
}
/// Parse a single header from the raw data given.
/// This function takes raw byte data, and starts parsing it, expecting there
/// to be a MIME header key-value pair right at the beginning. It parses that
/// header and returns it, along with the index at which the next header is
/// expected to start. If you just want to parse a single header, you can ignore
/// the second component of the tuple, which is the index of the next header.
/// Error values are returned if the data could not be successfully interpreted
/// as a MIME key-value pair.
///
/// # Examples
/// ```
///     use mailparse::parse_header;
///     let (parsed, _) = parse_header(concat!(
///             "Subject: Hello, sir,\n",
///             "   I am multiline\n",
///             "Next:Header").as_bytes())
///         .unwrap();
///     assert_eq!(parsed.get_key(), "Subject");
///     assert_eq!(parsed.get_value(), "Hello, sir, I am multiline");
/// ```
Parse a single header from the raw data given.
This function takes raw byte data, and starts parsing it, expecting there
to be a MIME header key-value pair right at the beginning. It parses that
header and returns it, along with the index at which the next header is
expected to start. If you just want to parse a single header, you can ignore
the second component of the tuple, which is the index of the next header.
Error values are returned if the data could not be successfully interpreted
as a MIME key-value pair.
Parse a single header from the raw data given . This function takes raw byte data and starts parsing it expecting there to be a MIME header key - value pair right at the beginning . It parses that header and returns it along with the index at which the next header is expected to start . If you just want to parse a single header you can ignore the second component of the tuple which is the index of the next header . Error values are returned if the data could not be successfully interpreted as a MIME key - value pair .
pub fn parse_header(raw_data: &[u8]) -> Result<(MailHeader, usize), MailParseError> {
    let mut it = raw_data.iter();
    let mut ix = 0;
    let mut c = match it.next() {
        None => return Err(MailParseError::Generic("Empty string provided")),
        Some(v) => *v,
    };
    let mut ix_key_end = None;
    let mut ix_value_start = 0;
    let mut ix_value_end = 0;
    let mut state = HeaderParseState::Initial;
    loop {
        match state {
            HeaderParseState::Initial => {
                if c == b' ' {
                    return Err(MailParseError::Generic(
                        "Header cannot start with a space; it is \
                         likely an overhanging line from a \
                         previous header",
                    ));
                };
                state = HeaderParseState::Key;
                continue;
            }
            HeaderParseState::Key => {
                if c == b':' {
                    ix_key_end = Some(ix);
                    state = HeaderParseState::PreValue;
                } else if c == b'\n' {
                    // Technically this is invalid. We'll handle it gracefully
                    // since it does appear to happen in the wild and other
                    // MTAs deal with it. Our handling is to just treat everything
                    // encountered so far on this line as the header key, and
                    // leave the value empty.
                    ix_key_end = Some(ix);
                    ix_value_start = ix;
                    ix_value_end = ix;
                    ix += 1;
                    break;
                }
            }
            HeaderParseState::PreValue => {
                if c != b' ' {
                    ix_value_start = ix;
                    ix_value_end = ix;
                    state = HeaderParseState::Value;
                    continue;
                }
            }
            HeaderParseState::Value => {
                if c == b'\n' {
                    state = HeaderParseState::ValueNewline;
                } else if c != b'\r' {
                    ix_value_end = ix + 1;
                }
            }
            HeaderParseState::ValueNewline => {
                if c == b' ' || c == b'\t' {
                    state = HeaderParseState::Value;
                    continue;
                } else {
                    break;
                }
            }
        }
        ix += 1;
        c = match it.next() {
            None => break,
            Some(v) => *v,
        };
    }
    match ix_key_end {
        Some(v) => Ok((
            MailHeader {
                key: &raw_data[0..v],
                value: &raw_data[ix_value_start..ix_value_end],
            },
            ix,
        )),
        None => Ok((
            // Technically this is invalid. We'll handle it gracefully
            // since we handle the analogous situation above. Our handling
            // is to just treat everything encountered on this line as
            // the header key, and leave the value empty.
            MailHeader {
                key: &raw_data[0..ix],
                value: &raw_data[ix..ix],
            },
            ix,
        )),
    }
}
pub fn parse_header ( raw_data : & [ u8 ] ) -> Result < ( MailHeader , usize ) , MailParseError > { let mut it = raw_data . iter ( ) ; let mut ix = 0 ; let mut c = match it . next ( ) { None => return Err ( MailParseError :: Generic ( " " ) ) , Some ( v ) => * v , } ; let mut ix_key_end = None ; let mut ix_value_start = 0 ; let mut ix_value_end = 0 ; let mut state = HeaderParseState :: Initial ; loop { match state { HeaderParseState :: Initial => { if c == b' ' { return Err ( MailParseError :: Generic ( " \
 \
 " , ) ) ; } ; state = HeaderParseState :: Key ; continue ; } HeaderParseState :: Key => { if c == b':' { ix_key_end = Some ( ix ) ; state = HeaderParseState :: PreValue ; } else if c == b'\n' { // Technically this is invalid. We'll handle it gracefully // since it does appear to happen in the wild and other // MTAs deal with it. Our handling is to just treat everything // encountered so far on this line as the header key, and // leave the value empty. ix_key_end = Some ( ix ) ; ix_value_start = ix ; ix_value_end = ix ; ix += 1 ; break ; } } HeaderParseState :: PreValue => { if c != b' ' { ix_value_start = ix ; ix_value_end = ix ; state = HeaderParseState :: Value ; continue ; } } HeaderParseState :: Value => { if c == b'\n' { state = HeaderParseState :: ValueNewline ; } else if c != b'\r' { ix_value_end = ix + 1 ; } } HeaderParseState :: ValueNewline => { if c == b' ' || c == b'\t' { state = HeaderParseState :: Value ; continue ; } else { break ; } } } ix += 1 ; c = match it . next ( ) { None => break , Some ( v ) => * v , } ; } match ix_key_end { Some ( v ) => Ok ( ( MailHeader { key : & raw_data [ 0 .. v ] , value : & raw_data [ ix_value_start .. ix_value_end ] , } , ix , ) ) , None => Ok ( ( // Technically this is invalid. We'll handle it gracefully // since we handle the analogous situation above. Our handling // is to just treat everything encountered on this line as // the header key, and leave the value empty. MailHeader { key : & raw_data [ 0 .. ix ] , value : & raw_data [ ix .. ix ] , } , ix , ) ) , } }
Parse a single header from the raw data given.
Parse a single header from the raw data given .
raw_data
&[u8]
raw_data
&[u8]
examples
```
use mailparse::parse_header;
let (parsed, _) = parse_header(concat!(
"Subject: Hello, sir,\n",
"   I am multiline\n",
"Next:Header").as_bytes())
.unwrap();
assert_eq!(parsed.get_key(), "Subject");
assert_eq!(parsed.get_value(), "Hello, sir, I am multiline");
```
` ` ` use mailparse :: parse_header ; let ( parsed _ ) = parse_header ( concat! ( " Subject : Hello sir \ n " " I am multiline \ n " " Next : Header " ) . as_bytes () ) . unwrap () ; assert_eq! ( parsed . get_key () " Subject " ) ; assert_eq! ( parsed . get_value () " Hello sir I am multiline " ) ; ` ` `