[−][src]Macro manger::consume_struct
A macro used for defining the way a struct
should be consumed.
It will implement Consumable
for this struct
.
Examples
use manger::consume_struct; #[derive(PartialEq, Debug)] struct Sum(i32); consume_struct! ( Sum => [ // Now a list of sequential instruction // // Note: We have a comma after every instruction, but we end // with a semicolon. // Saving data looks as such `KEY: TYPE` // // Note: Optionally, we can suffix a type with `{ Fn(data) -> bool }` to add // an extra condition for consuming. Therefore, if we could have suffixed // `{ |data| data >= 5 }`, we would require the `num_of_bananas` to be at // least 5. left_hand: i32, // Consuming arbitrary data from a certain type looks like `: TYPE` // // Here we use the build in Whitespace type of consume anytype // whitespace character. // // Note: Optionally, we can suffix a type with `{ Fn(data) -> bool }` to add // an extra condition for consuming. Therefore, if we would have wrote // `: char { |c| c.is_whitespace() }`, it would create the `Whitespace` type. : Vec<manger::common::Whitespace>, // Consuming expression looks like `> EXPRESSION` > "+", // Consuming arbitrary data from a certain type looks like `: TYPE` // // Here we use the build in Whitespace type of consume anytype // whitespace character. // // Note: Optionally, we can suffix a type with `{ Fn(data) -> bool }` to add // an extra condition for consuming. Therefore, if we would have wrote // `: char { |c| c.is_whitespace() }`, it would create the `Whitespace` type. : Vec<manger::common::Whitespace>, right_hand: i32; // Now we can use all our saved data to define what to do // with that data. // // Since `Sum` takes a (i32) we have to fill such a data structure. (left_hand + right_hand) ] ); // Now we can consume `Sum` as normal. use manger::Consumable; let source = "5 + -10"; let (sum, _) = Sum::consume_from(source)?; assert_eq!(sum, Sum(-5));
Syntax
The syntax for the macro is not very complicated. Much of the intuition on the Rust primitive and std types can we reapplied and only a few new concepts have to be applied.
The ENBF syntax is as follows:
Please note that the syntax ignores interproduction rule.
syntax = struct_name, "=>", "[",
{(instruction, ",")}*,
instruction, ";",
[ "(", RUST_EXPR*, ")" ], # RUST_EXPR is an arbitrary rust expression it can use all
# the RUST_IDENT defined in the previous section.
"]";
instruction = expr_instruction | type_instruction;
expr_instruction = ">", RUST_EXPR; # RUST_EXPR is an arbitrary rust expression. It should
# return a instance of a type that has the `Consumable`
# trait.
type_instruction = [ RUST_IDENT ], ":", RUST_TYPE; # RUST_IDENT is an arbitrary rust identity
# an it will assigned to that property if no
# tuple syntax is defined.
# RUST_TYPE is an arbitrary rust type that
# implements `Consumable`.
Note
-
Although this macro works without importing any manger traits, they will also not be imported afterwards. Importing traits should still be done if methods of the trait are supposed to be used afterwards.
-
This macro assumed that we are in the same module as the
enum
mentioned was defined. Some undefined behaviour might occur if this macro is called outside of the module theenum
was created.