# Syntax
File consists from 2 sections:
- how to read the config (`config structure`)
- how to serialize config (`serialization config`)
`config structure` describes the structure of your config file. All definitions, procedures and arguents layout.
`serialization config` describes the structurization of the read data.
## Syntax
```text
[] - array of items
i.e ["test" "test2"] or [1 2 3] or [3u 4u] or [symbol symbol2] or [symbol "symbol_data"]
; - a single line comment.
;/comment between/; - a multiline commnet.
;/comment between
this
/; - a multiline commnet.
234u - (u) unsigned integer
2123 - without (u) signed integer.
0xFFAB - a hex representation of integer
"" - a string
" a text \
continue text" - a text with \n escaped like in Rust which will be read as:
"a text continue text"
"a text
continue text" - a text with \n inline like in Rust which will be read as:
"a text
continue text"
symbol - symbol is a string without quotes with special chars
#t #f - a boolean true and false
i.e (test #t)
() - a procedure
i.e (test (another (test)))
3..6 - a non inclusive range from 3 to 5 incl
3u..6u - a non inclusive range unsigned
rang1..range2 - a non inclusive range as symbols
-3..=6 - an inclusive range from -3 to 6 incl.
```
## Definitions
`<type:title>` - a variable with specific type and title of the variable.
`(arg)` - argument of the procedure, strongly ordered.
`(proc)` - a inner procedure which can be defined in procedure in orbitrary order.
`(rootprocedure)` - a root of the config file i.e first iteration:
```scheme
(abc "123"
; (...)
)
(cde "1")
```
`(rootstruct)` - a root structure of the data i.e common structure:
```Rust
struct MyMainStruct
{
//...
}
```
`(struct)` - a definition of the structure.
`(field)` - a field of the structure.
`(enum)` - a definition of the enumerator.
`(serializator)` - a separator of different serialized namespaces.
`(verion)` - a version of the current script.
## Structure
```txt
(version <integer:version>)
(serializator <string:title>
(use <string:path_to_shmi_file>)
...
(define <string:alias_title> <[string;u64;i64]:data> <array<String>:allowed_in_procs>
(comment "text")
)
...
(define-enum `[string:enum_name]` `[array<String>:def_enum]`
(commnet "text")
(jail-derive [Clone Debug Eq PartialEq])
(jail-repr Rust) ; Rust, C, "other"
(jail-decl "serde(crate = \"self::serde\)") ; can be repeated multiple times
(jail-decl "cfg(...)") ; can be repeated multiple times
)
...
(procedure <string:title>
(arg <"string:path"> <procedure[int, uint, string, vector, boolean, range, range-inc, symbol, variable, entity, auto-type]:datatype>)
...
(proc "string:path" <array<String>:procedues>
(proc-allow <array[symbol:optional, collection]:allowed modifiers>)
)
...
)
...
(struct <string:struct_title> <string:procedure_name>
(jail-derive [Clone "Debug" Eq PartialEq]) ; Copy Clone Debug Eq PartialEq Hash Ord PartialOrd "other"
(jail-repr Rust) ; Rust, C, "other"
(jail-decl "serde(crate = \"self::serde\")") ; can be repeated multiple times
(comment "The comment for the enum which is longer then 80 symbols long and shoule be separated into \
two lines of comments")
(field <string:field_name>
(<procedure:[comment]:field_comment>)
(<procedure:[f/optional, f/struct, f/boolean, f/uint, f/int, f/string, f/enum, f/vecotr]:field data type> (<optional sub data type> <vector[string]:path_to_item>)))
)
)
; empty enum
(enum <string:enum title> <vector[string]:procedures>
(enum-opt-empty <string:procedure_name> <string:enum_alias>
(comment "test")
)
)
; enum with named fields (structs)
(enum <string:enum title> <vector[string]:procedures>
(enum-opt-struct <string:procedure_name> <string:enum_alias>
(enum-opt-fields
(field <string:field_name>
(<procedure:[f/optional, f/struct, f/boolean, f/uint, f/int, f/string, f/enum, f/vecotr]:field data type> (<optional sub data type> <vector[string]:path_to_item>))
)
)
)
)
; enum with anonymous fields
(enum <string:enum title> <vector[string]:procedures>
(enum-opt-tuple <string:procedure_name> <string:enum_alias>
(enum-opt-fields
(field <string:field_name>
(<procedure:[f/optional, f/struct, f/boolean, f/uint, f/int, f/string, f/enum, f/vecotr]:field data type> (<optional sub data type> <vector[string]:path_to_item>))
)
)
)
)
(rootprocedure
(proc <string:path> <array[string]:path_to_object>)
)
(rootstruct <string:struct_name>
(field <string:field_name>
(<procedure:[f/optional, f/struct, f/boolean, f/uint, f/int, f/string, f/enum, f/vecotr]:field data type> (<optional sub data type> <vector[string]:path_to_item>)))
)
)
)
```
### (serializator)
Allowed inner procedures:
- (rootstruct)
- (rootprocedure)
- (enum)
- (struct)
- (define)
- (define-enum)
- (use)
- (procedure)
```scheme
(serializator "test"
(use ...)
(use ...)
(define ...)
(define ...)
(define-enum ...)
(define-enum ...)
(procedure ...)
(procedure ...)
(struct ...)
(enum ...)
(rootstruct ...)
(rootstruct ...)
)
```
### (procedure)
Defines the procedure in config file and its contents.
Structure:
```txt
(procedure [string:title]
)
where
[string:title] - a label of the procedure which later will be used in config file.
```
Example:
```scheme
(procedure "tcp"
(arg "l_host_ip" string)
(arg "l_host_port" uinteger)
)
```
``` scheme
;; In this example, the above code will parse
(tcp "127.0.0.1" 20000)
;; as:
;; "l_host_ip" -> "127.0.0.1"
;; "l_host_port" -> 20000
```
```scheme
(procedure "tcp"
(arg "l_host_ip" string)
(arg "l_host_port" uinteger)
)
(procedure "server"
(arg "l_server_name" string)
(proc "l_server_tcp" '("tcp"))
)
```
```scheme
;; In this example, the above will parse:
(server "local"
(tcp "127.0.0.1" 2500)
)
;; as:
;; "l_server_name" -> local
;; "l_server_tcp" ->
;; "l_host_ip" -> 127.0.0.1
;; "l_host_port" -> 2500
```
```scheme
(procedure "tcp"
(arg "l_host_ip" (string))
(arg "l_host_port" (uint))
)
(procedure "server"
(arg "l_server_name" (string))
(proc "l_server_tcp" '("tcp"))
)
(procedure "servers"
(arg "l_servers_groupname" (string))
;; allow the (server) to be optional and repeat
(proc "l_servers_server" ["server"] (allow-proc [optional collection]))
)
```
```scheme
;; In this example the above will parse:
;; if no (server) is defined then don't throw the error
;; because it is optional
(servers "group1")
;; as:
;; "servers" -> group1
;; "l_servers_server" -> None
;; -- OR --
(servers "group1"
(server "local"
(tcp "127.0.0.1" 2500)
)
)
;; as:
;; "servers" -> group1
;; "l_servers_server" ->
;; "server" ->
;; "l_server_name" -> local
;; "l_server_tcp" ->
;; "l_host_ip" -> 127.0.0.1
;; "l_host_port" -> 2500
;; -- OR --
;; All (server) will be collected into the list
(servers "group1"
(server "local"
(tcp "127.0.0.1" 2500)
)
(server "ipx0"
(tcp "192.168.0.1" 2501)
)
(server "ipx0"
(tcp "192.168.0.1" 2502)
)
)
;; as:
;; "servers" -> group1
;; "l_servers_server" ->
;; "server" ->
;; "l_server_name" -> local
;; "l_server_tcp" ->
;; "l_host_ip" -> 127.0.0.1
;; "l_host_port" -> 2500
;;
;; "l_server_name" -> ipx0
;; "l_server_tcp" ->
;; "l_host_ip" -> 192.168.0.1
;; "l_host_port" -> 2501
;;
;; "l_server_name" -> ipx0
;; "l_server_tcp" ->
;; "l_host_ip" -> 192.168.0.1
;; "l_host_port" -> 2502
```
### (procedure_empty)
Special modificator which tells scheme that the procedure does not carry any data and it is empty.
```scheme
...
(procedure "tcp"
(procedure_empty)
)
...
```
```scheme
(tcp)
```
### (arg)
`arg` defines the argument in the `(procedure)`. The arguments are always collected in a strict order as it is defined in the scheme. It can not be optional or a collection.
Data types:
| string | none | none | "" | none | A basic string. Exit char \ for \ " |
| uint | none | none | 0123456789u| byte, word, dword, qword | An uinteger number u64 |
| int | none | none | +-0123456789| byte, word, dword, qword | An integer number i64 |
| long-int | none | none | +-0123456789l | 128 bit | An integer number 128bit long|
| long-uint | none | none | 0123456789lu | 128 bit | An integer number 128bit long|
| boolean | none | none | 't 'f | none | A boolean |
| entity | none | none | @ent | none | A `extension` - entity |
| variable | none | none | $var | none | A `etension` - variable |
| range | int | none | -2..3 | none | A range non inclusive |
| range | uint | none | -2..3 | none | A range non inclusive |
| range-inc | int | none | -2..=200 | none | A range inclusive |
| range-inc | uint | none | 2u..=200u | none | A range inclusive |
| symbol | none | none | symbol | none | A defined symbol |
| vector | string | none | '("itm1" "itm2") | hashset, array | A list of strings |
| vector | uint | none | '(1u 2u) | hashset, array | A list of uint |
| vector | int | none | '(-1 2) | hashset, array | A list of int |
| vector | long-uint | none | '(1lu 2lu) | hashset, array | A list of uint |
| vector | long-int | none | '(-1l 2l) | hashset, array | A list of int |
| vector | boolean | none | '('t 't 'f) | hashset, array | A list if boolean |
| vector | symbol | none | '(symb1 symb2) | hashset, array | A list of symbols |
| vector | entity | none | '(@ent1 @ent2) | hashset, array | A list of entitites |
| vector | variable | none | '($var $var) | hashset, array | A list of variables |
| vector | range | int | '(0..2 4..6) | array | A list of ranges |
| vector | range | uint | '(0u..2u 4u..6u) | array | A list of ranges |
| vector | range-inc | int | '(0..2 4..6) | array | A list of ranges |
| vector | range-inc | uint | '(0u..2u 4u..6u) | array | A list of ranges |
| vector | enumerator | none | '(EnumName::Item EnumName::Item2) | array | A list of enumerators. Enums must be same type!|
| vector | auto-type | none | '("test" 4u 3 #t @ent) | array | A list of any primitive value
| vector | vector | xxx | xxx | xxx | Not possible!|
| enumerator | none | none | EnumName::Item | none | An enumerator for argument |
| auto-type | none | none | "abc" or 4u or #t...| none | Any primitive lile int, uint, string, bool |
**IMPORTANT!**: `auto-type` for uint or int only 8 bytes (u64, i64) long!
Structure:
> (arg `[label]` `[datatype]` `[modifiers]`)
>> where:
>> `[label]` a mandatory label which will be used during serialization step
>> `[datatype]` a datatype to expect
>> `[modifiers]` an additional modifiers
```scheme
(arg "l_test" (string))
(arg "l_test2" (int))
(arg "l_test3" (vecotr (string)))
(arg "l_test5" (vector (range (int)))
```
### (arg-enum-bind)
A `modifier` which is used in arg with datatype `enumerator`. This modifier allows not to specify namespace of the enumerator, for example, `MyEnum::Item1` which will become just `Item1` symbol.
Structure:
> (arg-enum-bind `[string:namespace_enum_name]`)
>> where:
>> `[string:namespace_enum_name]` - a `string` which sets the namespace label of the enum.
**Example:**
```scheme
(procedure "enumtest"
(arg "enum_data" (enumerator "MyEnum"))
(arg "enum_data_2" (enumerator "OurEnum"))
)
; for the following input
(enumtest item1 item2) ; OurEnum::item2
```
### (proc)
Defines the procedure which canbe used in the config. The order can be `arbitrary` when placed in config.
Subprocs are:
- (allowed) modifies the behaviour.
Structure:
> (proc `[string:label]` `[array:procedure_names]`
> ([`proc-allow`] ...)
> )
>> where:
>> `[string:label]` a mandatory label which will be used during serialization step
>> `[vector:procedure_names]` a `(procedure)` list, can be more than one for enum
### (proc-allow)
Structure:
> (allow [vector:properties]))
>> where:
>> `[vector:properties]` a list of properties to grant
Properties:
- `optional` allows the procedure to be optional i.e to be defined in config only when it is needed
- `collection` allows the procedure to be repeated i.e to be defined multiple tiles in config
```scheme
(procedure "server"
(arg "l_server_name" string)
(proc "l_server_proto" ["tcp" "udp"]
(proc-allow [collection optional])
)
)
```
## (use)
Sets a path to `shmi` file. An `shmi` file an 'include' file which contains `procedures`/`structs`/`defines`. The content is attached to the serializator. See examples.
Structure:
> (use `[string:path_to_shmi_file]`)
>> where:
>> `[string:path_to_shmi_file]` - a full or partial path to the file without extension.
A path depends on how the static scheme parser was initialized. If root path was provided then a relative (partial) path should be set. Else, full path from root dir should be set.
## (define)
Defines a symbol which can be used in config. The `definition` use can be limited to specific `(procedure)`.
Structure:
> (define `[datatype]`[string:alias_title]` `[[string;u64;i64]:data]` `[array<String>:allowed_in_procs]`)
>> where:
>> `[string:alias_title]` an alias title which can be used in scheme
>> `[[string;u64;i64]:data]` a data which is defined by the alias
>> `[array<String>:allowed_in_procs]` a list of `(procedures)` where usage is allowed.
>> If `empty` then allowed anywhere.
```scheme
(define (uint) "sfx" 0 ["audio-channel"])
(define (uint) "music" 1 ["audio-channel"])
(define (uint) "voice" 2 ["audio-channel"])
(define (string) "all" "cfg:all" [])
```
## (define-enum)
Defines a specific symbol (with namespace) which represents an enum item (without payload) which can be used in procedure's arguments.
Structure:
> (define-enum `[string:enum_name]` `[array<String>:def_enum]`)
>> where:
>> `[string:enum_name]` an Enum structure name like pub struct MyEnum so -> "MyEnum"
>> `[array<String>:def_enum]` an enum's items
In order to coply with Rust's naming conversions, the items of the enum i.e fields of the enum, the first letter of each is
automatically uppercased.
For example:
```scheme
(define-enum "MyEnum" ["item1" "item2"]
(jail-derive [Clone Debug Eq PartialEq])
(jail-repr C) ; Rust, C, "other"
(jail-decl "serde(crate = \"self::serde\")") ; can be repeated multiple times
(comment "test123")
)
```
An `'("item1" "item2")` will be converted to the following format:
```Rust
/// test123
#[derive(Clone Debug Eq PartialEq, Deserialize)]
#[repr(C)]
#[serde(crate = "self::serde")]
pub enum MyEnum
{
Item1,
Item2
}
```
And the dynamic scheme config file:
```scheme
(enumtest item1)
```
Will be converted to:
```json
{"enum1":"Item1"}
```
## (struct)
This item is related to serialization part which is not mandatory if it is not required to serialize / deserialize config.
Defines a structure layout. This layout is used to serialize collected data. Structure is binded to specific `(procedure)`.
Structure:
>(struct `[string:struct_title]` `[[symbol(none);string;list:procedure_name]`
> ...
>)
>> where:
>> `[string:struct_title]` - a title of the struture which is used to generate Rust code. It should follow Rust's naming rules i.e `ScreenResolution`.
>> `[[symbol(none);string;list:procedure_name]` - a title/s of `(procedure)` which are described by current instance of `(struct)` or symbol `none` if used in `enum` declaration.
When procedures shares the same data strucuture, a one `(struct)` can be declared to describe struture of the data.
```scheme
(procedure "resolution"
...
)
(struct "ScreenResolution" "resolution"
...
)
; The above struct will be converted to rust code as:
; pub struct ScreenResolution
; {
; ...
; }
```
--or--
```scheme
(procedure "block"
...
)
(procedure "unblock"
...
)
(struct "ScreenResolution" ["block" "unblock"]
...
)
; The above struct will be used to for both "block" and
"unblock".
```
## (field)
Describes a field of the structure.
Structure:
```txt
(field [string:field_name]
; - MODIFICATORS
(f/optional) ; optional modificator (sets field as optional)
; - DATA TYPE
(f/struct [vector[string]:path_to_item])
; -- OR
(f/boolean [vector[string]:path_to_item])
; -- OR
(f/uint [vector[string]:path_to_item]
(val/width [symbol:int_width])
)
; -- OR
(f/int [vector[string]:path_to_item]
(val/width [symbol:int_width])
)
; -- OR
(f/string [vector[string]:path_to_item])
; -- OR
(f/enum [vector[string]:path_to_item])
; -- OR
(f/range [vector[string]:path_to_item])
; -- OR
(f/rangei [vector[string]:path_to_item])
; -- OR
(f/vector
; - SUB DATA TYPE
(f/struct [vector[string]:path_to_item])
; -- OR
(f/boolean [vector[string]:path_to_item])
; -- OR
(f/uint [vector[string]:path_to_item]
(val/width [symbol:int_width])
)
; -- OR
(f/int [vector[string]:path_to_item]
(val/width [symbol:int_width])
)
; -- OR
(f/string [vector[string]:path_to_item])
; -- OR
(f/enum [vector[string]:path_to_item])
; -- OR
(f/argenum [vector[string]:path_to_item] [string:enum_title])
; - VECTOR SPECIFIC MODIFICATOR
(vector/type [symbol[array,hashset]:type])
)
; -- OR
(f/argenum [vector[string]:path_to_item] [string:enum_title])
)
where:
[string:field_name] - a title of the field
[vector[string]:path_to_item] - a path to the item which is constructed from labels.
[symbol[array,hashset]:type] - a type of the collection deserialization.
[symbol:int_width] - a width of the integer i.e 8, 16, 32, 64. See table below 'integer bitwidth'
[string:enum_title] - a title of the enum defined in the `(define-enum)`.
```
Example:
```scheme
(procedure "info"
; ...
)
(struct "ScreenInfo" "info"
; ...
)
; ...
(procedure "resolution"
(arg "arg_res" (string))
(arg "arg_depth" (uint))
(proc "p_info" [info] (allow-proc [optional]))
)
(struct "ScreenResolution" "resolution"
(field "sr_res" (f/string ["arg_res"]))
(field "sr_depth" (f/uint64 ["arg_depth"]))
(field "sr_info" (f/optional (f/struct ["p_info"])))
)
; ...
; The above struct will be converted to rust code as:
; pub struct ScreenResolution
; {
; pub sr_res: String,
; pub sr_depth: u64,
; pub sr_info: Option<ScreenInfo>,
; }
```
### Integer bitwidth
For the integer types it is possible to specify the exact width. If width is not specified the default is 8 bytes i.e 64 bits.
|f/uint8 | 1u | 8 |
|f/uint16 | 2u | 16 |
|f/uint32 | 4u | 32 |
|f/uint64 | 8u | 64 |
|f/long-uint | 16u | 128 |
* same for the f/int*
Example:
```scheme
(struct "Levels" "levels"
(field "ch_a" (f/optional (f/uint32 ["label1" "alpha_lvl"]))
(field "ch_b" (f/int16 ["label2" "beta_lvl"]))
)
```
```rust
Generated Rust code:
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Levels
{
pub ch_a: Option<u32>,
pub ch_b: i16,
}
```
**Important notice**
The `(f/vector)` can generate vector either for `(arg)` declared as `vector` or `(proc)` collection which has struct defined.
So, the following construction will work
```scheme
(procedure "address"
(arg "a_addr" (string))
)
(procedure "machine"
(proc "p_address" '("address") (allow '(collection)))
)
(struct "NetMachine" "machine"
(field "nm_addrs" (f/vector (f/string '("p_address" "a_addr"))))
)
```
and will be serialized as:
```rust
pub struct NetMachine
{
nm_addrs: Vec<String>
}
```
But, usually a `procedure` **address** requires a `struct` descritpion expecially if there are more than one `arg`.
```scheme
(procedure "address"
(arg "a_addr" (string))
)
(struct "NetAddr" "address"
(field "net_addr" (f/string '("a_addr")))
)
(procedure "machine"
(proc "p_address" '("address") (proc-allow '(collection)))
)
(struct "NetMachine" "machine"
(field "nm_addrs" (f/vector (f/struct '("p_address"))))
)
```
### (f/optional)
Sets the field as optional. This means the data type of the field will be wrapped in `Option<>`.
### (vector/type)
A vector/type was replaced with multiple types like:
* f/vector - Vec<>
* f/hashset - HashSet<>
* f/indexset - IndexSet<>
Abstract example:
```scheme
(struct "ScreenResolution" "resolution"
(field "sr_res" (f/string '("arg_res")))
(field "sr_depth" (f/uint64 '("arg_depth")))
(field "sr_info" (f/optional (f/indexset (f/struct '("p_info")))))
)
```
### Field data types
The following data types are available:
|f/uint64| u64|(arg)|
|f/uint32| u32|(arg)|
|f/uint16| u16|(arg)|
|f/uint8| u8|(arg)|
|f/int64| i64|(arg)|
|f/int32| i32|(arg)|
|f/int16| i16|(arg)|
|f/int8| i8|(arg)|
|f/uint-long| u128| (arg)|
|f/int-long| i128| (arg)|
|f/string| String|(arg)|
|f/struct| [struct name]|(proc)|
|f/enum| [enum name] |(proc)|
|f/boolean| bool |(arg)|
|f/range | Range<> |(arg)|
|f/rangei | RangeInclusive<> |(arg)|
|f/vector | Vec<> |(arg) or (proc)|
|f/hashset | HashSet<> |(arg) or (proc)|
|f/insexset | IndexSet<> |(arg) or (proc)|
|f/argenum | pub enum [enum name] |(arg)|
|f/any | ShmTypeAnyField |(arg)|
Only specific `f/type` cab be applied to serialize the whole procedure or single argument. `f/vector` can be applied on both however it depends on the context.
An `ShmTypeAnyField` is a constrant enum which has the following format:
```rust
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum ShmTypeAnyField
{
Int(i64),
UInt(u64),
Bool(bool),
String(String)
}
```
## (enum)
This item is related to serialization part which is not mandatory if it is not required to serialize / deserialize config.
Defines an enumerator layout. This layout is used to serialize collected data. Enum is binded to one or many `(procedure)`.
Procedures should be specified in `(proc)` section.
```txt
(enum [string:enum title] [vector[string]:procedures]
(comment "...") ; optional, single
(enumopt ...)
(enumopt ...)
)
where:
[string:enum title] - a title of the struture which is used to generate Rust code. It should follow Rust's naming rules i.e `GeomType`.
[vector[string]:procedures] - a list of procedures that are serialized as enum.
```
Example:
```scheme
(procedure "Test")
(procedure "Ray"
(arg "length" (uint))
(arg "width" (uint))
)
(procedure "Line"
(arg "xpoint" (int))
(arg "ypoint" (int))
(arg "zpoint" (int))
)
(procedure "levels"
(arg "title" (string))
(proc "label1" ["alpha"] (allow-proc [optional]))
(proc "label2" ["beta"])
(proc "label3" ["Ray" "Line" "Test"] (allow-proc [collection]))
)
(enum "GeomType" ["Ray" "Line" "Test"]
(comment "<comment there>")
;...
)
; The above enum will be constructed as:
; /// <comment there>
;pub enum GeomType
;{
; ...
;}
```
### (enumopt)
Defines an enumerator option for the specific enum instance.
```txt
; Empty struct
(enum-opt-empty [string:procedure_name] [string:enum_alias]
(comment [string:comment]) ; optional
)
where:
[string:procedure_name] - a one `(procedure)` title which was declared in the `(enum)` proc.
[string:enum_alias] - a rename of the enum option i.e (enumopt "alpha" "Alpha") so in rust enum it will be "enum {Alpha, ...}".
(comment [string:comment]) - an option which allowes to generate comment above the item.
```
```txt
; An enum item with tuple
(enum-opt-tuple [string:procedure_name>] [string:enum_alias]
(comment [string:comment]) ; optional
(enum-opt-fields
(field [const=anon:field_name]
; - MODIFICATORS
; - DATA TYPE
(f/optional) ; optional modificator (sets field as optional)
; -- AND
(f/struct [vector[string]:path_to_item])
; -- OR
(f/boolean [vector[string]:path_to_item])
; -- OR
(f/uint [vector[string]:path_to_item])
; -- OR
(f/int [vector[string]:path_to_item])
; -- OR
(f/string [vector[string]:path_to_item])
; -- OR
(f/enum [vector[string]:path_to_item])
; -- OR
(f/any [vector[string]:path_to_item])
; -- OR
(f/range [vector[string]:path_to_item])
; -- OR
(f/rangei [vector[string]:path_to_item])
; -- OR
(f/vector
; - SUB DATA TYPE
(f/struct [vector[string]:path_to_item])
; -- OR
(f/boolean [vector[string]:path_to_item])
; -- OR
(f/uint [vector[string]:path_to_item])
; -- OR
(f/int [vector[string]:path_to_item])
; -- OR
(f/string [vector[string]:path_to_item])
; -- OR
(f/any [vector[string]:path_to_item])
; -- OR
(f/enum [vector[string]:path_to_item])
; -- OR
(f/argenum [string:enum_title] [vector[string]:path_to_item])
)
; -- OR
(f/argenum [string:enum_title] [vector[string]:path_to_item] )
)
)
)
where:
[string:field_name] - a title of the field
[vector[string]:path_to_item] - a path to the item which is constructed from labels.
[symbol[array,hashset]:type] - a type of the collection deserialization.
[string:enum_title] - a title of the enum defined in the `(define-enum)`.
(comment [string:comment]) - an option which allowes to generate comment above the item.
```
```txt
; An enum item with struct
(enum-opt-struct [string:procedure_name] [string:enum_alias]
(comment [string:comment]) ; optional
(enum-opt-fields
(field [const=anon:field_name]
; - MODIFICATORS
; - DATA TYPE
(f/optional) ; optional modificator (sets field as optional)
; -- AND
(f/struct [vector[string]:path_to_item])
; -- OR
(f/boolean [vector[string]:path_to_item])
; -- OR
(f/uint [vector[string]:path_to_item])
; -- OR
(f/int [vector[string]:path_to_item])
; -- OR
(f/string [vector[string]:path_to_item])
; -- OR
(f/enum [vector[string]:path_to_item])
; -- OR
(f/any [vector[string]:path_to_item])
; -- OR
(f/range [vector[string]:path_to_item])
; -- OR
(f/rangei [vector[string]:path_to_item])
; -- OR
(f/vector
; - SUB DATA TYPE
(f/struct [vector[string]:path_to_item])
; -- OR
(f/boolean [vector[string]:path_to_item])
; -- OR
(f/uint [vector[string]:path_to_item])
; -- OR
(f/int [vector[string]:path_to_item])
; -- OR
(f/string [vector[string]:path_to_item])
; -- OR
(f/any [vector[string]:path_to_item])
; -- OR
(f/enum [vector[string]:path_to_item])
; -- OR
(f/argenum [string:enum_title] [vector[string]:path_to_item])
)
; -- OR
(f/argenum [string:enum_title] [vector[string]:path_to_item] )
)
)
)
)
where:
[string:field_name] - a title of the field
[const_symbol=none] - a 'none' symbol
[vector[string]:path_to_item] - a path to the item which is constructed from labels.
[symbol[array,hashset]:type] - a type of the collection deserialization.
[string:enum_title] - a title of the enum defined in the `(define-enum)`.
(comment [string:comment]) - an option which allowes to generate comment above the item.
```
Example:
```scheme
(enum "TestUseEnum" ["yellow" "red" "green" "color-rgb" "color-rgba-profile"]
(comment "An enumerator for the color spaces")
(enum-opt-empty "yellow" "Yellow"
(comment "A bind to yellow color")
)
(enum-opt-empty "red" "Red"
)
(enum-opt-empty "green" "Green"
)
(enum-opt-tuple "color-rgb" "ColorRgb"
(enum-opt-fields
(field anon (f/uint8 ["arg_r"]))
(field anon (f/uint8 ["arg_g"]))
(field anon (f/uint8 ["arg_b"]))
)
)
(enum-opt-struct "color-rgba-profile" "ColorRgbaProfile"
(enum-opt-fields
(field "profile_name" (f/string ["arg_profile_name"]))
(field "col_r" (f/uint8 ["p_color" "arg_r"]))
(field "col_g" (f/uint8 ["p_color" "arg_g"]))
(field "col_b" (f/uint8 ["p_color" "arg_b"]))
(field "col_a" (f/uint8 ["arg_a"]))
)
)
)
```
## (rootprocedure) and (rootstruct)
Is a root of the document. The syntax is same as for `(procedure)` and `(struct)`.
But in order to deserialize `(rootstruct)` into `rust enum`, a single field should be declared with the `anon` field name.
Example:
```scheme
(rootstruct "LdLogStructFormat"
(field anon (f/enum ["l_root"]))
)
```
For example see:
- examples/init_use1.shm
- examples/init_use_dyn1.shm
- examples/inituse1.rs