specmc-protocol 0.1.1

A library for parsing Minecraft protocol specification.
Documentation
# SpecMC Protocol

A library for parsing Minecraft protocol specification.

## Default types

Primitives:

-   `bool`: Boolean.
-   `u8`, `u16`, `u32`, `u64`: Unsigned integers of size 8, 16, 32 and 64 bits respectively.
-   `i8`, `i16`, `i32`, `i64`: Signed integers of size 8, 16, 32 and 64 bits respectively.
-   `VarInt`, `VarLong`: Regular signed integers of size 32 and 64 bits respectively, but encoded in the LEB128 format.
-   `f32`, `f64`: Floating point numbers of size 32 and 64 bits respectively.

Other types:

-   `String`: UTF-8 encoded string prefixed with its size in bytes as VarInt. The maximum length is 32767. Use `String[n]` to explicitly specify the length.
-   `List[type; n]`: A list, where `type` is the type of the elements and `n` is the number of elements. `n` can also be an identifier, in which case the number of elements is to be determined at runtime.
-   `Nbt`: NBT encoded data. Note that in some versions NBT is gzip compressed.

## Enums

An enum definition consists of an enum name, followed by its representation type, and a list of variants.
Variants will be implicitly assigned a value of the previous variant plus one.
The first variant will be implicitly assigned the value 0.
You can explicitly assign a value to an enum variant.
An enum `State` is necessary and is used for packet definitions.

Example:

```
enum ABC(i32) {
    A = 1
    B // implicitly assigned 2
    C // implicitly assigned 3
}
```

## Packets

A packet definition consists of a packet name, followed by its direction, state and id, and a list of fields.
Enums will be represented as the type specified in the enum definition.
`if` statements can be used to define conditional fields.
Fields of primitive types can be set to equal a literal or a constant. They are still present, but the value is used for validation.

Example:

```
packet SomePacket(serverbound, Play, 0x42) {
    u32 length
    List[u8, length] data
    if (length > 0) {
        String message
    }
}
```

## Types

A custom type can be defined using the `type` keyword.
Fields are equivalent to fields in a packet.

## Constants

Constants can be defined using the `const` keyword.
A constant `PVN` is automatically defined.

## Examples

```rust
use specmc_base::{parse::Parse, tokenize::tokenize};
use specmc_protocol::Protocol;

const INPUT: &str = "
enum TestEnum(i32) {}
type TestType {
    String message
}
packet TestPacket(serverbound, Play, 0x42) {
    u32 length
    List[u8; length] data
    if (length > 0) {
        TestType message
    }
}";

let mut tokens: Vec<String> = tokenize(INPUT);
tokens.reverse();
println!("{:#?}", Protocol::parse(&mut tokens));
```