brdb 0.5.0

A library for reading and writing Brickadia's World files.
Documentation
use crate::{
    schema::{BrdbStructPropRaw, PlaintextEnumBody as EnumBody, PlaintextStructBody as StructBody},
    helpers::*
};

grammar;

/* A simple text parser for the following format (to be used for BRDB schemas):
enum MyEnum {
    Variant1 = 0,
    Variant2 = 1,
}
struct MyStruct {
    field1: str,
    field2: i32,
    field3: OtherStruct[],
    field4: u8[flat],
}
*/

match {
    r"\s*" => { }, // The default whitespace skipping is disabled if an `ignore pattern` is specified
    r"//[^\n\r]*[\n\r]*" => { }, // Skip `// comments`
    r"#[^\n\r]*[\n\r]*" => { }, // Skip `# comments`
    r"/\*[^*]*\*+(?:[^/*][^*]*\*+)*/" => { },  // Skip `/* comments */`
} else {
    _
}

pub Meta: (
    Vec<(String, EnumBody)>,
    Vec<(String, StructBody)>
)
 = StructOrEnum+ => {
    let mut enums = Vec::new();
    let mut structs = Vec::new();
    for (e, s) in <> {
        if let Some(e) = e {
            enums.push(e);
        }
        if let Some(s) = s {
            structs.push(s);
        }
    }
    (enums, structs)
};

StructOrEnum: (
    Option<(String, EnumBody)>,
    Option<(String, StructBody)>
) = {
    Enum => (Some(<>), None),
    Struct => (None, Some(<>)),
};

Enum: (String, EnumBody) = "enum" <name:Ident> "{" <variants:Comma<EnumVariant>> "}" => {
    (name, variants)
};
EnumVariant: (String, i32) = <name:Ident> "=" <value:Integer> => {
    (name, value)
};

Integer: i32 = { I32, Binary, Hex };
I32: i32 =
    r"-?\d+(_\d+)*" => remove_underscores(<>).parse::<i32>().unwrap();
Binary: i32 =
    r"0b[01]+(_[01]+)*" => i32::from_str_radix(&(&remove_underscores(&<>[2..])), 2).unwrap();
Hex: i32 =
    r"0x[0-9a-fA-F]+(_[0-9a-fA-F]+)*" => i32::from_str_radix(&remove_underscores(&<>[2..]), 16).unwrap();


Struct: (String, StructBody) = "struct" <name:Ident> "{" <fields:Comma<StructField>> "}" => (name, fields);

StructField: (String, BrdbStructPropRaw) = <name:Ident> ":" <ty:StructProp> => (name, ty);

StructProp: BrdbStructPropRaw = {
  <Ident> => BrdbStructPropRaw::Type(<>),
  <ty:Ident> "[]" => BrdbStructPropRaw::Array(ty),
  <ty:Ident> "[" "flat" "]" => BrdbStructPropRaw::FlatArray(ty),
  "{" <k_ty:Ident> ":" <v_ty:Ident> "}" => BrdbStructPropRaw::Map(
    k_ty,
    v_ty,
  ),
};

Ident: String = r"[a-zA-Z_](\w|\w::\w)*" => <>.to_string();
Comma<T>: Vec<T> = {
    () => vec![],
    <mut v:(<T> ",")*> <e:T> ","? => {
        v.push(e);
        v
    }
};