This crate implements the epee binary format found in Monero; unlike other crates, this one does not use serde, this is not because serde is bad but its to reduce the load on maintainers as all the traits in this lib are specific to epee instead of general purpose.
The default feature enables the derive feature.
This feature enables the derive macro for creating epee objects for example:
```rust use epee_encoding::EpeeObject;
struct Test { val: u8 } ```
```rust use epeeencoding::{EpeeObject, EpeeObjectBuilder, readepeevalue, writefield, tobytes, frombytes}; use epee_encoding::io::{Read, Write};
pub struct Test { val: u64 }
pub struct __TestEpeeBuilder {
val: Option
impl EpeeObjectBuilder
fn finish(self) -> epee_encoding::error::Result<Test> {
Ok(
Test {
val: self.val.ok_or_else(|| epee_encoding::error::Error::Format("Required field was not found!"))?
}
)
}
}
impl EpeeObject for Test { type Builder = __TestEpeeBuilder;
fn number_of_fields(&self) -> u64 {
1
}
fn write_fields<W: Write>(&self, w: &mut W) -> epee_encoding::error::Result<()> {
// write the fields
write_field(&self.val, "val", w)
} }
let data = [1, 17, 1, 1, 1, 1, 2, 1, 1, 4, 3, 118, 97, 108, 5, 4, 0, 0, 0, 0, 0, 0, 0]; // the data to decode; let val: Test = frombytes(&data).unwrap(); let data = tobytes(&val).unwrap();
```
```rust use epeeencoding::{EpeeObject, frombytes, to_bytes};
struct Test { val: u64 }
let data = [1, 17, 1, 1, 1, 1, 2, 1, 1, 4, 3, 118, 97, 108, 5, 4, 0, 0, 0, 0, 0, 0, 0]; // the data to decode; let val: Test = frombytes(&data).unwrap(); let data = tobytes(&val).unwrap();
```
The EpeeObject
derive macro has a few attributes which correspond to specific C/C++ macro fields.
This is equivalent to KV_SERIALIZE_PARENT
, it flattens all the fields in the object into the parent object.
so this in C/C++: ```cpp struct requestt: public rpcrequestbase { uint8t major_version;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE_PARENT(rpc_request_base)
KV_SERIALIZE(major_version)
END_KV_SERIALIZE_MAP()
};
Would look like this in Rust:
rust
struct RequestT { #[epeeflatten] rpcrequestbase: RequestBase, majorversion: u8, } ```
This allows you to re-name a field for when its encoded, although this isn't related to a specific macro in C/C++ this was included because Monero has some odd names.
example: ```rust
pub struct HandshakeR { #[epeealtname("nodedata")] pub nodedaa: BasicNodeData, } ```
This is equivalent to KV_SERIALIZE_OPT
and allows you to specify a default value for a field, when a default value
is specified the value will be used if it is not contained in the data and the field will not be encoded if the value is
the default value.
so this in C/C++:
```cpp
struct requestt
{
std::vector
BEGINKVSERIALIZEMAP() KVSERIALIZE(txs) KVSERIALIZE() KVSERIALIZEOPT(dandelionppfluff, true) // backwards compatible mode is fluff ENDKVSERIALIZEMAP() }; ```
would look like this in Rust: ```rust
struct RequestT {
txs: Vec
This crate is no-std.
To have an optional field, you should wrap the type in Option
and use the epee_default
attribute.
So it would look like this:
```rust
struct T {
#[epee_default(None)]
val: Option