Module parser

Source
Expand description

SML parsers.

This module contains parsers for the SML protocol. The complete module contains an easy to use allocating parser. The streaming module contains a flexible non-allocating parser. See the discussion below for a comparison of the two parsers:

§Which parser should I choose?

The SML protocol defines two data structures that can hold multiple elements. An SML File can contain multiple SML Messages and the “SML_GetList.Res” message contains a list of values. Because of these two elements, the size of an SML File cannot be known at compile time.

The parser in the complete module uses dynamic memory allocations alloc::vec::Vec for SML Messages and SML Values. This makes the usage straight-forward and if you’re using sml-rs on a hosted platform, this is most likely the parser you’ll want to use.

The parser in the streaming module works differently and therefore doesn’t require dynamic memory allocations. Instead of returning a single data structure representing the whole SML File, this parser produces a stream of events that each have a size known at compile time. Depending on the input, the parser will produce a different number of events, which is how different numbers of SML Messages / Values can be handled. If you’re using sml-rs on a microcontroller and don’t want to use an allocator, this is the parser you’ll want to use.

§Examples

§Using complete::parse

let bytes: &[u8] = &[ /*...*/ ];

println!("{:#?}", complete::parse(&bytes).expect("error while parsing"));

Output (stripped-down to the relevant parts):

File {
    messages: [
        Message {
            message_body: OpenResponse {
                ref_time: SecIndex(23876784),
                ...
            },
            ...
        },
        Message {
            message_body: GetListResponse {
                val_list: [
                    ListEntry { ... },
                    ListEntry { ... },
                    ListEntry { ... },
                ],
            },
            ...
        },
        Message {
            message_body: CloseResponse,
            ...
        },
    ],
}

§Using streaming::Parser

let bytes: &[u8] = &[ /*...*/ ];

let parser = streaming::Parser::new(bytes);
for item in parser {
    println!("- {:#?}", item.expect("error while parsing"));
}

Output (stripped-down to the relevant parts):

- MessageStart(MessageStart {
    message_body: OpenResponse {
        ref_time: SecIndex(23876784),
        ...
    },
    ...
})
- MessageStart(MessageStart {
    message_body: GetListResponseStart {
        num_values: 3,
        ...
    },
    ...
})
- ListEntry(ListEntry { ... })
- ListEntry(ListEntry { ... })
- ListEntry(ListEntry { ... })
- GetListResponseEnd(GetListResponseEnd)
- MessageStart(MessageStart {
    message_body: CloseResponse,
    ...
})

Modules§

common
Types used by both parsers.
completealloc
Simple to use SML parser that uses dynamic memory allocations (requires alloc feature)
streaming
Flexible parser that doesn’t require dynamic memory allocations.

Enums§

ParseError
Error type used by the parser
TlfParseError
Error type used when parsing a TypeLengthField

Type Aliases§

OctetStr
OctetStr is the borrowed version of a sequence of bytes.