diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..7dd37ed --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,61 @@ +version: 2 + +jobs: + build: + docker: + - image: circleci/rust:latest + steps: + - checkout + - restore_cache: + key: project-cache + - run: + name: Check formatting + command: | + rustfmt --version + cargo fmt -- --check + - run: + name: Nightly Build + command: | + rustup toolchain install nightly + rustup run nightly rustc --version --verbose + rustup run nightly cargo --version --verbose + rustup run nightly cargo build + - run: + name: Stable Build + command: | + rustup toolchain install stable + rustup run stable rustc --version --verbose + rustup run stable cargo --version --verbose + rustup run stable cargo build + - run: + name: Wasm Build + command: | + rustup toolchain install nightly + rustup update + rustup target add wasm32-unknown-unknown --toolchain nightly + rustup run nightly cargo build --release --target wasm32-unknown-unknown + - save_cache: + key: project-cache + paths: + - "~/.cargo" + - "./target" + test: + docker: + - image: circleci/rust:latest + steps: + - checkout + - run: + name: Test + command: | + rustup toolchain install nightly + rustup run nightly cargo test + rustup toolchain install stable + rustup run stable cargo test +workflows: + version: 2 + build_and_test: + jobs: + - build + - test: + requires: + - build \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index df3441a..f103f7a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,15 @@ [package] name = "xdr-rs-serialize" version = "0.1.0" -authors = ["Kyle Bartush "] +authors = ["Kochavalabs "] +description = "XDR object serialization for Rust" +license = "MIT" +readme = "README.md" +homepage = "https://github.com/kochavalabs/xdr-rs-serialize" +repository = "https://github.com/kochavalabs/xdr-rs-serialize" edition = "2018" +keywords = ["xdr", "serialization"] +exclude = [ "example/*", "xdr-rs-serialize-derive/*" ] -[dependencies] -xdr-rs-serialize-derive = { path = "xdr-rs-serialize-derive" } +[dev-dependencies] +xdr-rs-serialize-derive = { version = "0.1.0", path = "xdr-rs-serialize-derive" } diff --git a/README.md b/README.md index 17b3452..62144ef 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,44 @@ -# Spec Notes - -## Types - -- Integer [ser, des] -- Unsigned Integer [ser, des] -- Enumeration [ser, des] -- Boolean [ser, des] -- Hyper Integer [ser, des] -- Hyper Unsigned Integer [ser, des] -- Floating-Point [ser, des] -- Double-Precision Floating-Point [ser, des] -- Quadruple-Precision Floating Point [] -- Fixed Length Opaque [ser, des] -- Variable-Length Opaque [ser, des] -- String [ser, des] -- Fixed-Length Array [ser, des] -- Variable-Length Array [ser, des] -- Structure [ser, des] -- Discriminated Union [ser, des] -- Void [ser, des] -- Optional-Data [ser, des] +# XDR RS Serialize + +[![CircleCI](https://circleci.com/gh/kochavalabs/xdr-rs-serialize.svg?style=svg)](https://circleci.com/gh/kochavalabs/xdr-rs-serialize) + +Xdr-rs-serialize is a library for facilitating the (de)serialization of rust +objects into the [XDR](https://en.wikipedia.org/wiki/External_Data_Representation) +format. + +## Installation + +This library can be added to your project by using cargo to install the +xdr-rs-serialize crate. + +```bash +cargo add xdr-rs-serialize +``` + +## Usage + +```rust +use xdr_rs_serialize::de::XDRIn; +use xdr_rs_serialize::error::Error; +use xdr_rs_serialize::ser::XDROut; + +fn main() -> Result<(), Error> { + let mut byte_buffer = Vec::new(); + "Hello world!".to_string().write_xdr(&mut byte_buffer)?; + // Notice that a tuple is returned with the String result at index 0 and + // total bytes read at index 1. + let hello_world: String = String::read_xdr(&mut &byte_buffer)?.0; + println!("{}", hello_world); + Ok(()) +} +``` + +For a more complex example see the code under [example/](https://github.com/kochavalabs/xdr-rs-serialize/tree/develop/example) + +## License + +[MIT](https://choosealicense.com/licenses/mit/) + +## Notes + +- The XDR Quad type is currently not supported diff --git a/example/.gitignore b/example/.gitignore new file mode 100644 index 0000000..2f88dba --- /dev/null +++ b/example/.gitignore @@ -0,0 +1,3 @@ +/target +**/*.rs.bk +Cargo.lock \ No newline at end of file diff --git a/example/Cargo.toml b/example/Cargo.toml new file mode 100644 index 0000000..3a2709b --- /dev/null +++ b/example/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "example" +version = "0.1.0" +authors = ["Kyle Bartush "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +xdr-rs-serialize= { path = "../" } +xdr-rs-serialize-derive = { path = "../xdr-rs-serialize-derive" } diff --git a/example/src/main.rs b/example/src/main.rs new file mode 100644 index 0000000..aed5783 --- /dev/null +++ b/example/src/main.rs @@ -0,0 +1,133 @@ +#[macro_use] +extern crate xdr_rs_serialize_derive; + +#[allow(unused_imports)] +use xdr_rs_serialize::de::{ + read_fixed_array, read_fixed_opaque, read_var_array, read_var_opaque, read_var_string, XDRIn, +}; +#[allow(unused_imports)] +use xdr_rs_serialize::ser::{ + write_fixed_array, write_fixed_opaque, write_var_array, write_var_opaque, write_var_string, + XDROut, +}; + +use xdr_rs_serialize::error::Error; + +// Simple xdr struct made up of a hyper and a u_hyper. +#[derive(Default, Debug, XDROut, XDRIn)] +pub struct Simple { + pub hyper_: i64, + + pub u_hyper_: u64, +} + +// Enum example, explicit discrimination is recommended. +#[derive(Debug, XDROut, XDRIn)] +pub enum SampleEnum { + ONE = 0, + TWO = 1, + Three = 2, +} + +impl Default for SampleEnum { + fn default() -> Self { + SampleEnum::ONE + } +} + +// Signature typedef as opaque[64] +#[derive(Default, Debug, XDROut, XDRIn)] +pub struct Signature { + #[array(fixed = 64)] + pub t: Vec, +} + +// Union of 3 possible types, Null, 32 bit integer, or the Simple struct +// defined above. +#[derive(Debug, XDROut, XDRIn)] +pub enum SampleUnion { + NONE(()), + + T1(i32), + + T2(Simple), +} + +impl Default for SampleUnion { + fn default() -> Self { + SampleUnion::NONE(()) + } +} + +// Complex struct containing examples of most available types. +#[derive(Default, Debug, XDROut, XDRIn)] +pub struct Complex { + // Union defined above. + pub uni: SampleUnion, + + // Enum defined above. + pub enu: SampleEnum, + + // A typdef of a signature. + pub sig: Signature, + + // The boolean data type. + pub t_bool: bool, + + // The integer data type. + pub t_int: i32, + + // The unsigned integer data type. + pub u_int: u32, + + // The hyper data type. + pub hyp: i64, + + // The unsigned hyper data type. + pub u_hyper: u64, + + // A fixed opaque data type of size 12 + #[array(fixed = 12)] + pub fixed_opaque: Vec, + + // A variable length opaque array with max size of 122 + #[array(var = 122)] + pub var_opaque: Vec, + + // An array of Simple structs with a fixed size of 12. + #[array(fixed = 12)] + pub fixed_xdr: Vec, + + // A variable array of integers with a max size of 12 + #[array(var = 12)] + pub var_xdr: Vec, + + // A variable array string type with no size bound (2^32 chars implicit) + pub test: String, + + // A struct + pub sub_struct: Simple, +} + +fn main() -> Result<(), Error> { + // Create an XDR object and update it. + let mut to_xdr = Complex::default(); + to_xdr.test = "This is a string.".to_string(); + + // Default does not currently initialize arrays to the correct size, + // so fixed arrays must be manually initialized. + to_xdr.fixed_opaque = vec![3; 12]; + to_xdr.fixed_xdr = vec![3; 12]; + // Typedefs are wrapped in structs with the datatype at property t + to_xdr.sig.t = vec![1; 64]; + + // Write the xdr encoded bytes to a buffer. + let mut buffer_bytes = Vec::new(); + to_xdr.write_xdr(&mut buffer_bytes)?; + + // Read the xdr bytes back to a Complex object. + let from_xdr = Complex::read_xdr(&mut buffer_bytes.to_vec())?; + println!("{:?}", from_xdr); + + Ok(()) +} diff --git a/src/lib.rs b/src/lib.rs index 25b6c74..c02a674 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ - mod de; +pub mod de; pub mod error; pub mod ser; diff --git a/src/ser.rs b/src/ser.rs index d37b353..174cc12 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -171,7 +171,8 @@ pub fn write_var_array( } pub fn write_var_string(val: String, size: u32, out: &mut Vec) -> Result { - if val.len() as u32 > size { + if val.len() as u32 > size && size != 0 { + println!("{} {}", val.len(), size); return Err(Error::VarArrayWrongSize); } Ok(val.write_xdr(out)?) diff --git a/xdr-rs-serialize-derive/Cargo.toml b/xdr-rs-serialize-derive/Cargo.toml index 7b5db5c..c136f9f 100644 --- a/xdr-rs-serialize-derive/Cargo.toml +++ b/xdr-rs-serialize-derive/Cargo.toml @@ -1,8 +1,14 @@ [package] name = "xdr-rs-serialize-derive" version = "0.1.0" -authors = ["Kyle Bartush "] +authors = ["Kochavalabs "] +description = "XDR object serialization for Rust" +license = "MIT" +readme = "README.md" +homepage = "https://github.com/kochavalabs/xdr-rs-serialize" +repository = "https://github.com/kochavalabs/xdr-rs-serialize" edition = "2018" +keywords = ["xdr", "serialization"] [dependencies] syn = { version = "0.15.12" , features = ["full", "extra-traits", "parsing"] } @@ -10,4 +16,5 @@ quote = "0.6.8" proc-macro2 = "0.4" [lib] +name = "xdr_rs_serialize_derive" proc-macro = true diff --git a/xdr-rs-serialize-derive/README.md b/xdr-rs-serialize-derive/README.md new file mode 100644 index 0000000..429d8b2 --- /dev/null +++ b/xdr-rs-serialize-derive/README.md @@ -0,0 +1,14 @@ +# xdr-rs-serialize-derive + +Derivation macros to derive the serialization and deserialization of objects using XDR. + +## Add dependency + +```toml +[dependencies] +xdr-rs-serialize-derive = "0.1.0" +``` + +## License + +[MIT](https://choosealicense.com/licenses/mit/)