pub fn parse(data: &[u8]) -> Result<Session, ParserError> {
        // Create an iterator which returns for each line its human-readable
        // (1-based) line number and contents.
        let mut lines =
            LineParser(data.lines().enumerate().map(|(i, bytes)| (i + 1, bytes))).peekable();

        // Parses anything allowed by RFC 8866 Section 9 and more:
        // - be more lax about order. As in the RFC, "v=" must come first and
        //   "m=" starts the media descriptions. Other fields can come in
        //   almost any order. "r=" refers to the most recent "t=", even if it's
        //   not the most recent line.
        // - allow "t=" line to be missing.

        // Check version line, which we expect to come first.
        match lines.next()? {
            Some(Line {
                n,
                key: b'v',
                value,
            }) => {
                if value != b"0" {
                    return Err(ParserError::InvalidVersion(n, value.into()));
                }
            }
            _ => return Err(ParserError::NoVersion),
        }

        let mut origin = None;
        let mut session_name = None;
        let mut session_description = None;
        let mut uri = None;
        let mut emails = vec![];
        let mut phones = vec![];
        let mut connection = None;
        let mut bandwidths = vec![];
        let mut times = vec![];
        let mut time_zones = None;
        let mut attributes = vec![];
        let mut key = None;
        while matches!(lines.peek(), Ok(Some(Line { key, .. })) if *key != b'm') {
            let line = lines.next().unwrap().unwrap();
            match line.key {
                // Parse origin line:
                // - Must only exist exactly once (see check following the loop)
                b'o' => parse_rejecting_duplicates(
                    &mut origin,
                    &line,
                    ParserError::MultipleOrigins,
                    Origin::parse,
                )?,

                // Parse session name line:
                // - Must only exist exactly once (see check following the loop)
                b's' => parse_rejecting_duplicates(
                    &mut session_name,
                    &line,
                    ParserError::MultipleSessionNames,
                    |l| str_from_utf8(l.n, l.value, "Session Name"),
                )?,

                // Parse session information line:
                // - Must only exist once or not at all
                b'i' => parse_rejecting_duplicates(
                    &mut session_description,
                    &line,
                    ParserError::MultipleSessionDescription,
                    |l| str_from_utf8(l.n, l.value, "Session Description"),
                )?,

                // Parse URI line:
                // - Must only exist once or not at all
                b'u' => {
                    parse_rejecting_duplicates(&mut uri, &line, ParserError::MultipleUris, |l| {
                        str_from_utf8(l.n, l.value, "Uri")
                    })?
                }

                // Parse E-Mail lines:
                // - Can exist not at all, once or multiple times
                b'e' => emails.push(str_from_utf8(line.n, line.value, "E-Mail")?),

                // Parse phone number lines:
                // - Can exist not at all, once or multiple times
                b'p' => phones.push(str_from_utf8(line.n, line.value, "Phone")?),

                // Parse connection line:
                // - Can exist not at all or exactly once per session
                b'c' => parse_rejecting_duplicates(
                    &mut connection,
                    &line,
                    ParserError::MultipleConnections,
                    Connection::parse,
                )?,

                // Parse bandwidth lines:
                // - Can exist not at all, once or multiple times
                b'b' => bandwidths.push(Bandwidth::parse(&line)?),

                // Parse time lines
                // - If followed by "r" lines then these are part of the same time field
                b't' => times.push(Time::parse(&line)?),

                // Parse repeat lines
                // - Can exist not at all, once or multiple times
                b'r' => {
                    let t = times
                        .last_mut()
                        .ok_or(ParserError::UnexpectedLine(line.n, b't'))?;
                    t.repeats.push(Repeat::parse(&line)?);
                }

                // Parse zones line:
                // - Can exist not at all or exactly once per session
                b'z' => parse_rejecting_duplicates(
                    &mut time_zones,
                    &line,
                    ParserError::MultipleTimeZones,
                    TimeZone::parse,
                )?,

                // Parse key line
                // - Can exist not at all or exactly once
                b'k' => parse_rejecting_duplicates(
                    &mut key,
                    &line,
                    ParserError::MultipleKeys,
                    Key::parse,
                )?,

                // Parse attribute lines:
                // - Can exist not at all, once or multiple times
                b'a' => attributes.push(Attribute::parse(&line)?),

                o => return Err(ParserError::UnexpectedLine(line.n, o)),
            }
        }

        let origin = origin.ok_or(ParserError::NoOrigin)?;
        let session_name = session_name.ok_or(ParserError::NoSessionName)?;

        let time_zones = time_zones.unwrap_or_default();

        // Parse media lines:
        // - Can exist not at all, once or multiple times
        let mut medias = vec![];
        while let Some(media) = Media::parse(&mut lines)? {
            medias.push(media);
        }

        Ok(Session {
            origin,
            session_name,
            session_description,
            uri,
            emails,
            phones,
            connection,
            bandwidths,
            times,
            time_zones,
            key,
            attributes,
            medias,
        })
    }
/// Parse an SDP session description from a byte slice.
Parse an SDP session description from a byte slice.
Parse an SDP session description from a byte slice .
pub fn parse(data: &[u8]) -> Result<Session, ParserError> {
        // Create an iterator which returns for each line its human-readable
        // (1-based) line number and contents.
        let mut lines =
            LineParser(data.lines().enumerate().map(|(i, bytes)| (i + 1, bytes))).peekable();
        // Parses anything allowed by RFC 8866 Section 9 and more:
        // - be more lax about order. As in the RFC, "v=" must come first and
        //   "m=" starts the media descriptions. Other fields can come in
        //   almost any order. "r=" refers to the most recent "t=", even if it's
        //   not the most recent line.
        // - allow "t=" line to be missing.
        // Check version line, which we expect to come first.
        match lines.next()? {
            Some(Line {
                n,
                key: b'v',
                value,
            }) => {
                if value != b"0" {
                    return Err(ParserError::InvalidVersion(n, value.into()));
                }
            }
            _ => return Err(ParserError::NoVersion),
        }
        let mut origin = None;
        let mut session_name = None;
        let mut session_description = None;
        let mut uri = None;
        let mut emails = vec![];
        let mut phones = vec![];
        let mut connection = None;
        let mut bandwidths = vec![];
        let mut times = vec![];
        let mut time_zones = None;
        let mut attributes = vec![];
        let mut key = None;
        while matches!(lines.peek(), Ok(Some(Line { key, .. })) if *key != b'm') {
            let line = lines.next().unwrap().unwrap();
            match line.key {
                // Parse origin line:
                // - Must only exist exactly once (see check following the loop)
                b'o' => parse_rejecting_duplicates(
                    &mut origin,
                    &line,
                    ParserError::MultipleOrigins,
                    Origin::parse,
                )?,
                // Parse session name line:
                // - Must only exist exactly once (see check following the loop)
                b's' => parse_rejecting_duplicates(
                    &mut session_name,
                    &line,
                    ParserError::MultipleSessionNames,
                    |l| str_from_utf8(l.n, l.value, "Session Name"),
                )?,
                // Parse session information line:
                // - Must only exist once or not at all
                b'i' => parse_rejecting_duplicates(
                    &mut session_description,
                    &line,
                    ParserError::MultipleSessionDescription,
                    |l| str_from_utf8(l.n, l.value, "Session Description"),
                )?,
                // Parse URI line:
                // - Must only exist once or not at all
                b'u' => {
                    parse_rejecting_duplicates(&mut uri, &line, ParserError::MultipleUris, |l| {
                        str_from_utf8(l.n, l.value, "Uri")
                    })?
                }
                // Parse E-Mail lines:
                // - Can exist not at all, once or multiple times
                b'e' => emails.push(str_from_utf8(line.n, line.value, "E-Mail")?),
                // Parse phone number lines:
                // - Can exist not at all, once or multiple times
                b'p' => phones.push(str_from_utf8(line.n, line.value, "Phone")?),
                // Parse connection line:
                // - Can exist not at all or exactly once per session
                b'c' => parse_rejecting_duplicates(
                    &mut connection,
                    &line,
                    ParserError::MultipleConnections,
                    Connection::parse,
                )?,
                // Parse bandwidth lines:
                // - Can exist not at all, once or multiple times
                b'b' => bandwidths.push(Bandwidth::parse(&line)?),
                // Parse time lines
                // - If followed by "r" lines then these are part of the same time field
                b't' => times.push(Time::parse(&line)?),
                // Parse repeat lines
                // - Can exist not at all, once or multiple times
                b'r' => {
                    let t = times
                        .last_mut()
                        .ok_or(ParserError::UnexpectedLine(line.n, b't'))?;
                    t.repeats.push(Repeat::parse(&line)?);
                }
                // Parse zones line:
                // - Can exist not at all or exactly once per session
                b'z' => parse_rejecting_duplicates(
                    &mut time_zones,
                    &line,
                    ParserError::MultipleTimeZones,
                    TimeZone::parse,
                )?,
                // Parse key line
                // - Can exist not at all or exactly once
                b'k' => parse_rejecting_duplicates(
                    &mut key,
                    &line,
                    ParserError::MultipleKeys,
                    Key::parse,
                )?,
                // Parse attribute lines:
                // - Can exist not at all, once or multiple times
                b'a' => attributes.push(Attribute::parse(&line)?),
                o => return Err(ParserError::UnexpectedLine(line.n, o)),
            }
        }
        let origin = origin.ok_or(ParserError::NoOrigin)?;
        let session_name = session_name.ok_or(ParserError::NoSessionName)?;
        let time_zones = time_zones.unwrap_or_default();
        // Parse media lines:
        // - Can exist not at all, once or multiple times
        let mut medias = vec![];
        while let Some(media) = Media::parse(&mut lines)? {
            medias.push(media);
        }
        Ok(Session {
            origin,
            session_name,
            session_description,
            uri,
            emails,
            phones,
            connection,
            bandwidths,
            times,
            time_zones,
            key,
            attributes,
            medias,
        })
    }
pub fn parse ( data : & [ u8 ] ) -> Result < Session , ParserError > { // Create an iterator which returns for each line its human-readable // (1-based) line number and contents. let mut lines = LineParser ( data . lines ( ) . enumerate ( ) . map ( | ( i , bytes ) | ( i + 1 , bytes ) ) ) . peekable ( ) ; // Parses anything allowed by RFC 8866 Section 9 and more: // - be more lax about order. As in the RFC, "v=" must come first and //   "m=" starts the media descriptions. Other fields can come in //   almost any order. "r=" refers to the most recent "t=", even if it's //   not the most recent line. // - allow "t=" line to be missing. // Check version line, which we expect to come first. match lines . next ( ) ? { Some ( Line { n , key : b'v' , value , } ) => { if value != b" " { return Err ( ParserError :: InvalidVersion ( n , value . into ( ) ) ) ; } } _ => return Err ( ParserError :: NoVersion ) , } let mut origin = None ; let mut session_name = None ; let mut session_description = None ; let mut uri = None ; let mut emails = vec ! [ ] ; let mut phones = vec ! [ ] ; let mut connection = None ; let mut bandwidths = vec ! [ ] ; let mut times = vec ! [ ] ; let mut time_zones = None ; let mut attributes = vec ! [ ] ; let mut key = None ; while matches ! ( lines peek ( ) Ok ( Some ( Line { key } ) ) if key b'm' ) { let line = lines . next ( ) . unwrap ( ) . unwrap ( ) ; match line . key { // Parse origin line: // - Must only exist exactly once (see check following the loop) b'o' => parse_rejecting_duplicates ( & mut origin , & line , ParserError :: MultipleOrigins , Origin :: parse , ) ? , // Parse session name line: // - Must only exist exactly once (see check following the loop) b's' => parse_rejecting_duplicates ( & mut session_name , & line , ParserError :: MultipleSessionNames , | l | str_from_utf8 ( l . n , l . value , " " ) , ) ? , // Parse session information line: // - Must only exist once or not at all b'i' => parse_rejecting_duplicates ( & mut session_description , & line , ParserError :: MultipleSessionDescription , | l | str_from_utf8 ( l . n , l . value , " " ) , ) ? , // Parse URI line: // - Must only exist once or not at all b'u' => { parse_rejecting_duplicates ( & mut uri , & line , ParserError :: MultipleUris , | l | { str_from_utf8 ( l . n , l . value , " " ) } ) ? } // Parse E-Mail lines: // - Can exist not at all, once or multiple times b'e' => emails . push ( str_from_utf8 ( line . n , line . value , " " ) ? ) , // Parse phone number lines: // - Can exist not at all, once or multiple times b'p' => phones . push ( str_from_utf8 ( line . n , line . value , " " ) ? ) , // Parse connection line: // - Can exist not at all or exactly once per session b'c' => parse_rejecting_duplicates ( & mut connection , & line , ParserError :: MultipleConnections , Connection :: parse , ) ? , // Parse bandwidth lines: // - Can exist not at all, once or multiple times b'b' => bandwidths . push ( Bandwidth :: parse ( & line ) ? ) , // Parse time lines // - If followed by "r" lines then these are part of the same time field b't' => times . push ( Time :: parse ( & line ) ? ) , // Parse repeat lines // - Can exist not at all, once or multiple times b'r' => { let t = times . last_mut ( ) . ok_or ( ParserError :: UnexpectedLine ( line . n , b't' ) ) ? ; t . repeats . push ( Repeat :: parse ( & line ) ? ) ; } // Parse zones line: // - Can exist not at all or exactly once per session b'z' => parse_rejecting_duplicates ( & mut time_zones , & line , ParserError :: MultipleTimeZones , TimeZone :: parse , ) ? , // Parse key line // - Can exist not at all or exactly once b'k' => parse_rejecting_duplicates ( & mut key , & line , ParserError :: MultipleKeys , Key :: parse , ) ? , // Parse attribute lines: // - Can exist not at all, once or multiple times b'a' => attributes . push ( Attribute :: parse ( & line ) ? ) , o => return Err ( ParserError :: UnexpectedLine ( line . n , o ) ) , } } let origin = origin . ok_or ( ParserError :: NoOrigin ) ? ; let session_name = session_name . ok_or ( ParserError :: NoSessionName ) ? ; let time_zones = time_zones . unwrap_or_default ( ) ; // Parse media lines: // - Can exist not at all, once or multiple times let mut medias = vec ! [ ] ; while let Some ( media ) = Media :: parse ( & mut lines ) ? { medias . push ( media ) ; } Ok ( Session { origin , session_name , session_description , uri , emails , phones , connection , bandwidths , times , time_zones , key , attributes , medias , } ) }
Parse an SDP session description from a byte slice.
Parse an SDP session description from a byte slice .
data
&[u8]
data
&[u8]