diff --git a/README.md b/README.md
index 24dd8e5..75f69b3 100644
--- a/README.md
+++ b/README.md
@@ -4,10 +4,260 @@ An encoder/decoder for Konami's binary XML format, used in many of their games.
Requires Rust 1.34 or newer!
-### Setup
+## Setup
- Setup Rust through `rustup` or your own preferred method of acquiring Rust
- For using `kbinxml-rs` as a library, add it as a dependency in your `Cargo.toml` file
+ - For example, if you want the base library and psmap_derive:
+ - `cargo add kbinxml psmap psmap_derive --git https://github.com/mbilker/kbinxml-rs.git`
- For using `kbinxml-rs` as a standalone application, install `kbinxml-rs` using `cargo install kbinxml --features=build_binary` (Note: This will not work at the moment as `kbinxml-rs` has not yet been published to [crates.io](https://crates.io))
-To be written.
+## Code Examples
+
+### Deserialisation
+
+#### From text
+```rust
+use kbinxml;
+
+fn main() {
+ let input = b"
+
+
+ Hello, world!
+
+ ";
+
+ let (nodes, encoding) = kbinxml::from_text_xml(input).unwrap();
+
+ println!("encoding: {}, data: {:?}", encoding, nodes);
+}
+```
+
+This prints (prettified for the README):
+```rust
+encoding: UTF-8, data: NodeCollection {
+ base: NodeDefinition {
+ encoding: UTF_8,
+ node_type: NodeStart,
+ is_array: false,
+ data: Some {
+ key: Uncompressed { "test" },
+ value_data: b""
+ }
+ },
+ attributes: [],
+ children: [
+ NodeCollection {
+ base: NodeDefinition {
+ encoding: UTF_8,
+ node_type: String,
+ is_array: false,
+ data: Some {
+ key: Uncompressed { "entry" },
+ value_data: b"Hello, world!\0"
+ }
+ },
+ attributes: [
+ NodeDefinition {
+ encoding: UTF_8,
+ node_type: Attribute,
+ is_array: false,
+ data: Some {
+ key: Uncompressed { "some_attr" },
+ value_data: b"an attribute\0"
+ }
+ }
+ ],
+ children: []
+ }
+ ]
+}
+```
+
+#### From a file, with binary/text auto-detect
+```rust
+use std::fs;
+use kbinxml;
+
+fn main() {
+ let input = fs::read("testcases_out.kbin").unwrap();
+ let (nodes, encoding) = kbinxml::from_binary(input.into()).unwrap();
+
+ println!("encoding: {}, data: {:?}", encoding, nodes);
+}
+```
+
+#### Using psmap_derive
+
+##### On a single set of nodes:
+```rust
+use kbinxml;
+use psmap;
+use psmap_derive::*;
+
+#[derive(Debug)]
+struct Entry {
+ hello: String,
+ some_attr: String,
+ sub_entry_value: Option,
+ sub_entry_attr: u8,
+}
+
+fn main() -> Result<(), Box> {
+ let input = b"
+
+
+
+ Hello, world!
+ 64
+
+
+ ";
+
+ let (nodes, _encoding) = kbinxml::from_text_xml(input).unwrap();
+
+ // the container NodeCollection must be turned into a single node for psmap
+ let node = nodes.as_node().unwrap();
+
+ // psmap uses `?` internally, so the calling function must return a Result.
+ // If you're making a larger project, using `anyhow::Result` is recommended.
+ let value = psmap! {
+ output: Entry,
+ inputs: [
+ // the top-level node "test" is inaccessible, only the child nodes
+ // and attributes are usable inside psmap
+ node: {
+ "entry" => {
+ attributes: {
+ "some_attr" => some_attr,
+ },
+ value => hello,
+
+ "sub_entry" => {
+ attributes: {
+ // attributes can be parsed with `as`
+ "another_attr" => sub_entry_attr as u8,
+ },
+ value => sub_entry_value,
+ // A value can be made optional using this keyword
+ optional,
+ },
+ }
+ },
+ ],
+ };
+
+ println!("{:?}", value);
+
+ Ok(())
+}
+```
+
+This code prints:
+```rust
+Entry {
+ hello: "Hello, world!",
+ some_attr: "an attribute",
+ sub_entry_value: Some(64),
+ sub_entry_attr: 10
+}
+```
+
+##### On a list of identical nodes (such as a music db):
+```rust
+use kbinxml;
+use psmap;
+use psmap_derive::*;
+
+#[derive(Debug)]
+struct Entry {
+ id: u8,
+ name: String,
+ color: String,
+}
+
+fn main() -> Result<(), Box> {
+ let input = b"
+
+
+
+ BananaYellow
+ AppleRed
+ PeachPink
+ MulberryViolet
+ RockmelonOrange
+ Disguised BananaInvisible
+
+ ";
+
+ let (nodes, _encoding) = kbinxml::from_text_xml(input).unwrap();
+
+ let entries: Result, _> = nodes.children().iter()
+ .map(|node_collection| -> Result> {
+ let node = node_collection.as_node()?;
+ // because we cannot access the top level node "entry", we get its
+ // attribute first
+ let id = node
+ .attributes()
+ .get("id").expect("id not present")
+ .parse::()?;
+
+ // we then provide the `id` to `psmap` using "include"
+ Ok(psmap! {
+ output: Entry,
+ include: [id],
+ inputs: [
+ node: {
+ "name" => name,
+ "color" => color,
+ },
+ ],
+ })
+ })
+ .collect();
+
+ println!("{:?}", entries);
+
+ Ok(())
+}
+```
+
+This code prints (prettified for the README):
+```rust
+Ok([
+ Entry { id: 5, name: "Banana", color: "Yellow" },
+ Entry { id: 8, name: "Apple", color: "Red" },
+ Entry { id: 1, name: "Peach", color: "Pink" },
+ Entry { id: 2, name: "Mulberry", color: "Violet" },
+ Entry { id: 7, name: "Rockmelon", color: "Orange" },
+ Entry { id: 4, name: "Disguised Banana", color: "Invisible" }
+])
+```
+
+### Serialisation
+
+#### To text
+```rust
+let text = kbinxml::to_text_xml(&nodes).unwrap();
+// if you encoded in UTF8 and want a str:
+let text = std::str::from_utf8(&text).unwrap();
+```
+
+#### To bytes
+```rust
+let bytes = kbinxml::to_binary(&nodes).unwrap();
+```
+
+#### To bytes, with encoding options
+```rust
+let options = kbinxml::Options::builder()
+ .compression(kbinxml::CompressionType::Compressed)
+ .encoding(kbinxml::EncodingType::SHIFT_JIS)
+ .build();
+let bytes = kbinxml::to_binary_with_options(options, &nodes).unwrap();
+```
+
+#### From a struct
+There is currently no way to seralise structs directly as with `psmap`, they
+must be converted into nodes manually.