protospec-build 0.3.0

One binary format language to rule them all, One binary format language to find them, One binary format language to bring them all and in the darkness bind them.
Documentation
use super::*;

pub fn parse_container(t: &mut TokenIter) -> ParseResult<Container> {
    let start = t.expect(Token::Container)?;

    let length = if t.eat(Token::LeftSquare).is_some() {
        let length = parse_expression(t)?;
        t.expect(Token::RightSquare)?;
        Some(Box::new(length))
    } else {
        None
    };

    let flags = parse_flags(t)?;

    t.expect(Token::LeftCurly)?;

    let mut items = vec![];

    while !t.peek_token(Token::RightCurly)? {
        if t.eat(Token::Dot).is_some() {
            let ident = t.expect_ident()?;
            match &*ident.name {
                "pad" => {
                    t.expect(Token::Colon)?;
                    let type_ = parse_expression(t)?;
                    items.push(ContainerItem::Pad(type_));
                    if !t.eat(Token::Comma).is_some() {
                        break;
                    }
                    continue;
                },
                _ => return Err(ParseError::UnknownContainerDirective(ident.name.clone(), ident.span)),
            }
        }

        let ident = t.expect_ident()?;
        t.expect(Token::Colon)?;
        let type_ = parse_field(t)?;
        items.push(ContainerItem::Field(ident, type_));
        if !t.eat(Token::Comma).is_some() {
            break;
        }
    }

    let end = t.expect(Token::RightCurly)?;

    Ok(Container {
        span: start + end,
        length,
        flags,
        items,
    })
}