Skip to content

Schema

A Kiwi schema: the definitions (enums, structs and messages) that give meaning to the bytes of a message.

Read one from its binary form with Schema::parse, then decode messages with Schema::decode.

use helpers4::kiwi::Schema;

Cargo feature kiwi (enabled by default). To compile only this module:

cargo add helpers4 --no-default-features --features kiwi

or in Cargo.toml:

[dependencies]
helpers4 = { version = "0.0.11", default-features = false, features = ["kiwi"] }
pub struct Schema { /* private fields */ }
use helpers4::kiwi::Schema;

// A schema with one message, `Ping`, holding a `uint` field `id` (field number 1).
let schema = Schema::parse(b"\x01Ping\0\x02\x01id\0\x07\x00\x01")?;
let ping = schema.decode(&[1, 42, 0], "Ping")?;
assert_eq!(ping.get("id").and_then(|id| id.as_u32()), Some(42));
pub fn parse(bytes: &[u8]) -> Result<Self, KiwiError>

Reads a binary Kiwi schema (what Kiwi’s compileSchema / encodeBinarySchema write; in a .fig file, the first decompressed chunk).

Parameters

ParameterTypeDescription
bytes&[u8]The binary schema. Bytes after the last definition are ignored.

Returns

Result<Self, KiwiError> — The schema.

Errors

A KiwiError on truncated data, an invalid string, an unknown definition kind, or a field whose type is not a built-in type nor a definition of the schema.

Examples

use helpers4::kiwi::{Kind, Schema};

let schema = Schema::parse(b"\x01Ping\0\x02\x01id\0\x07\x00\x01")?;
assert_eq!(&*schema.definitions[0].name, "Ping");
assert_eq!(schema.definitions[0].kind, Kind::Message);
pub fn find(&self, name: &str) -> Option<usize>

The index of the definition with this name.

Parameters

ParameterTypeDescription
name&strThe definition name.

Returns

Option<usize> — The index in definitions, or None.

Examples

use helpers4::kiwi::Schema;

let schema = Schema::parse(b"\x01Ping\0\x02\x00")?;
assert_eq!(schema.find("Ping"), Some(0));
assert_eq!(schema.find("Pong"), None);
pub fn decode(&self, bytes: &[u8], root: &str) -> Result<Value, KiwiError>

Decodes a message as an instance of one definition (usually a message, the root of the file). Bytes after the value are left alone.

Parameters

ParameterTypeDescription
bytes&[u8]The encoded value.
root&strThe name of the definition it is an instance of.

Returns

Result<Value, KiwiError> — The value: an Value::Object for a message or a struct, with enums by name and a byte[] as Value::Bytes.

Errors

A KiwiError when root is unknown, the data is truncated or invalid (a message with a field id its definition lacks, a bad string), or it nests deeper than 64 levels.

Examples

use helpers4::kiwi::{KiwiError, Schema};

let schema = Schema::parse(b"\x01Ping\0\x02\x01id\0\x07\x00\x01")?;
assert_eq!(schema.decode(&[1], "Ping"), Err(KiwiError::UnexpectedEof { index: 1 }));
assert!(schema.decode(&[0], "Pong").is_err());

Why a Kiwi schema or message could not be decoded.

use helpers4::kiwi::KiwiError;

#[non_exhaustive]
pub enum KiwiError {
    /// The data ends in the middle of a value.
    UnexpectedEof {
        /// Byte offset where the read that fell short started.
        index: usize,
    },
    /// A string that is not valid UTF-8, or has no terminating `0`.
    InvalidString {
        /// Byte offset where the string starts.
        index: usize,
    },
    /// A definition whose kind byte is not enum, struct or message.
    UnknownKind {
        /// The kind byte.
        kind: u8,
    },
    /// A field whose type is neither a built-in type nor a definition of the schema.
    UnknownType {
        /// The raw type number.
        type_id: i32,
    },
    /// No definition has the requested name.
    UnknownDefinition {
        /// The name that was asked for.
        name: String,
    },
    /// A message holds a field id its definition does not list.
    UnknownField {
        /// The message definition.
        message: String,
        /// The field id.
        id: u32,
    },
    /// The data nests deeper than the decoder allows (a malformed or hostile schema can recurse
    /// forever).
    TooDeep,
}

src/kiwi/schema.rs