summaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'README.md')
-rw-r--r--README.md96
1 files changed, 57 insertions, 39 deletions
diff --git a/README.md b/README.md
index 94ae801..bffd266 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
[bzipper](https://crates.io/crates/bzipper/) is a binary (de)serialiser for the Rust language.
-Contrary to [Serde](https://crates.io/crates/serde/)/[Bincode](https://crates.io/crates/bincode/), the goal of bzipper is to serialise with a known size constraint.
+In contrast to [Serde](https://crates.io/crates/serde/)/[Bincode](https://crates.io/crates/bincode/), the primary goal of bzipper is to serialise with a known size constraint.
Therefore, this crate may be more suited for networking or other cases where a fixed-sized buffer is needed.
Keep in mind that this project is still work-in-progress.
@@ -20,15 +20,15 @@ For strings, the `FixedString` type is also provided.
## Usage
-This crate revolves around the `Serialise` and `Deserialise` traits, both of which are commonly used in conjunction with streams (more specifically, s-streams and d-streams).
+This crate revolves around the `Serialise` and `Deserialise` traits, both of which use *streams* – or more specifically – s-streams and d-streams.
Many core types come implemented with bzipper, including primitives as well as some standard library types such as `Option` and `Result`.
-It is recommended in most cases to just derive these traits for custom types (enumerations and structures only).
-Here, each field is chained in declaration order:
+It is recommended in most cases to just derive these two traits for custom types (although this is only supported with enumerations and structures).
+Here, each field is *chained* according to declaration order:
-```rs
-use bzipper::{Deserialise, Serialise};
+```rust
+use bzipper::{Buffer, Deserialise, Serialise};
#[derive(Debug, Deserialise, PartialEq, Serialise)]
struct IoRegister {
@@ -36,45 +36,55 @@ struct IoRegister {
value: u16,
}
-let mut buf: [u8; IoRegister::SERIALISED_SIZE] = Default::default();
-IoRegister { addr: 0x04000000, value: 0x0402 }.serialise(&mut buf).unwrap();
+let mut buf = Buffer::new();
+buf.write(IoRegister { addr: 0x04000000, value: 0x0402 }).unwrap();
+
+assert_eq!(buf.len(), 0x6);
assert_eq!(buf, [0x04, 0x00, 0x00, 0x00, 0x04, 0x02]);
-assert_eq!(IoRegister::deserialise(&buf).unwrap(), IoRegister { addr: 0x04000000, value: 0x0402 });
+assert_eq!(buf.read().unwrap(), IoRegister { addr: 0x04000000, value: 0x0402 });
```
### Serialisation
-To serialise an object implementing `Serialise`, simply allocate a buffer for the serialisation.
-The required size of any given serialisation is specified by the `SERIALISED_SIZE` constant:
+To serialise an object implementing `Serialise`, simply allocate a buffer for the serialisation and wrap it in an s-stream (*serialisation stream*) with the `Sstream` type.
+
+```rust
+use bzipper::{Serialise, Sstream};
-```rs
-use bzipper::Serialise;
+let mut buf = [Default::default(); char::MAX_SERIALISED_SIZE];
+let mut stream = Sstream::new(&mut buf);
-let mut buf: [u8; char::SERIALISED_SIZE] = Default::default();
-'Ж'.serialise(&mut buf).unwrap();
+'Ж'.serialise(&mut stream).unwrap();
-assert_eq!(buf, [0x00, 0x00, 0x04, 0x16]);
+assert_eq!(stream, [0x00, 0x00, 0x04, 0x16]);
```
-The only special requirement of the `serialise` method is that the provided byte slice has an element count of exactly `SERIALISED_SIZE`.
+The maximum size of any given serialisation is specified by the `MAX_SERIALISED_SIZE` constant.
+
+We can also use streams to chain multiple elements together:
-We can also use streams to *chain* multiple elements together:
+```rust
+use bzipper::{Serialise, Sstream};
-```rs
-use bzipper::Serialise;
+let mut buf = [Default::default(); char::MAX_SERIALISED_SIZE * 0x5];
+let mut stream = Sstream::new(&mut buf);
-let mut buf: [u8; char::SERIALISED_SIZE * 5] = Default::default();
-let mut stream = bzipper::Sstream::new(&mut buf);
+// Note: For serialising multiple characters, the
+// `FixedString` type is usually preferred.
-stream.append(&'ل');
-stream.append(&'ا');
-stream.append(&'م');
-stream.append(&'د');
-stream.append(&'ا');
+'ل'.serialise(&mut stream).unwrap();
+'ا'.serialise(&mut stream).unwrap();
+'م'.serialise(&mut stream).unwrap();
+'د'.serialise(&mut stream).unwrap();
+'ا'.serialise(&mut stream).unwrap();
-assert_eq!(buf, [0x00, 0x00, 0x06, 0x44, 0x00, 0x00, 0x06, 0x27, 0x00, 0x00, 0x06, 0x45, 0x00, 0x00, 0x06, 0x2F, 0x00, 0x00, 0x06, 0x27]);
+assert_eq!(buf, [
+ 0x00, 0x00, 0x06, 0x44, 0x00, 0x00, 0x06, 0x27,
+ 0x00, 0x00, 0x06, 0x45, 0x00, 0x00, 0x06, 0x2F,
+ 0x00, 0x00, 0x06, 0x27
+]);
```
When serialising primitives, the resulting byte stream is in big endian (a.k.a. network endian).
@@ -82,25 +92,33 @@ It is recommended for implementors to adhere to this convention as well.
### Deserialisation
-Deserialisation works with an almost identical syntax to serialisation.
+Deserialisation works with a similar syntax to serialisation.
-To deserialise a buffer, simply call the `deserialise` method:
+D-streams (*deserialisation streams*) use the `Dstream` type and are constructed in a manner similar to s-streams.
+To deserialise a buffer, simply call the `deserialise` method with the strema:
-```rs
-use bzipper::Deserialise;
+```rust
+use bzipper::{Deserialise, Dstream};
let data = [0x45, 0x54];
-assert_eq!(<u16>::deserialise(&data).unwrap(), 0x4554);
+let stream = Dstream::new(&data);
+assert_eq!(u16::deserialise(&stream).unwrap(), 0x4554);
```
-Just like with serialisations, the `Dstream` can be used to deserialise chained elements:
+And just like s-streams, d-streams can also be used to handle chaining:
-```rs
-use bzipper::Deserialise;
+```rust
+use bzipper::{Deserialise, Dstream};
let data = [0x45, 0x54];
-let stream = bzipper::Dstream::new(&data);
+let stream = Dstream::new(&data);
+
+assert_eq!(u8::deserialise(&stream).unwrap(), 0x45);
+assert_eq!(u8::deserialise(&stream).unwrap(), 0x54);
+
+// The data can also be deserialised as a tuple (up
+// to twelve elements).
-assert_eq!(stream.take::<u8>().unwrap(), 0x45);
-assert_eq!(stream.take::<u8>().unwrap(), 0x54);
+let stream = Dstream::new(&data);
+assert_eq!(<(u8, u8)>::deserialise(&stream).unwrap(), (0x45, 0x54));
```