diff --git a/Changelog.md b/Changelog.md index b03bf255..4bf2055a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,6 +8,12 @@ - test: Adding missing tests - chore: Changes to the build process or auxiliary tools/libraries/documentation +## quick-protobuf 0.6.4 +- feat: failible get byte + +## pb-rs 0.8.3 +- feat: allow rpc with `{ }` + ## pb-rs 0.8.2 - feat: add optional Owned variant when generating Messages (relies on `Pin`) - fix: propagate `dont_use_cow` to all messages @@ -16,7 +22,6 @@ - feat: avoid Cow::Borrow when comparing `&str` ## pb-rs 0.8.0 - - feat: Added the ability to use custom RPC generation code - feat: Added the ability to modify custom derives such as derive-new - feat: (Large change) Added the `dont_use_cow` method [v2 and v3 tested] which replaces lifetimes diff --git a/README.md b/README.md index b7ec2341..f27576e7 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ It provides both: - no need to use google `protoc` tool to generate the modules - [**quick-protobuf**](quick-protobuf), a protobuf file parser: - this is the crate that you will typically refer to in your library. The generated modules will assume it has been imported. - - it acts like an event parser, the logic to convert it into struct is handle by `pb-rs` + - it acts like an event parser, the logic to convert it into struct is handled by `pb-rs` ## Example: protobuf_example project @@ -104,7 +104,7 @@ You can find basic examples in the [examples](examples) directory. ## Message <-> struct -The best way to check for all kind of generated code is to look for the codegen_example data: +The best way to check for all kinds of generated code is to look for the codegen_example data: - definition: [data_types.proto](quick-protobuf/examples/pb_rs/data_types.proto) - generated code: [data_types.rs](quick-protobuf/examples/pb_rs/data_types.rs) @@ -229,7 +229,7 @@ This library is an alternative to the widely used [rust-protobuf](https://github #### Pros / Cons - Pros - - [Much faster](quick-protobuf/benches/rust-protobuf), in particular when working with string, bytes and repeated packed fixed size fields (no extra allocation) + - [Much faster](perftest), in particular when working with string, bytes and repeated packed fixed size fields (no extra allocation) - No need to install `protoc` on your machine - No trait objects: faster/simpler parser - Very simple generated modules (~10x smaller) so you can easily understand what is happening @@ -255,7 +255,7 @@ quick-protobuf is particularly good at reading large bytes. ## Contribution -Any help is welcomed! (Pull requests of course, bug report, missing functionality etc...) +Any help is welcome! (Pull requests of course, bug reports, missing functionality etc...) ## Licence diff --git a/pb-rs/Cargo.toml b/pb-rs/Cargo.toml index aa195d6f..6940976a 100644 --- a/pb-rs/Cargo.toml +++ b/pb-rs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pb-rs" -version = "0.8.2" +version = "0.8.3" description = "A converter from proto files into quick-protobuf compatible rust module" authors = ["Johann Tuffe "] keywords = ["protobuf", "parser", "quick-protobuf"] diff --git a/pb-rs/src/parser.rs b/pb-rs/src/parser.rs index dcf7de7f..ec52f67e 100644 --- a/pb-rs/src/parser.rs +++ b/pb-rs/src/parser.rs @@ -275,6 +275,7 @@ named!( tag!("rpc") >> many1!(br) >> name: word + >> many0!(br) >> tag!("(") >> many0!(br) >> arg: word @@ -287,7 +288,19 @@ named!( >> many0!(br) >> ret: word >> many0!(br) - >> tag!(");") + >> tag!(")") + >> many0!(br) + >> alt!( + do_parse!( + tuple!( + tag!("{"), + many0!(br), + many0!(alt!(option_ignore | map!(tag!(";"), |_| ()))), + many0!(br), + tag!("}") + ) >> () + ) | map!(tag!(";"), |_| ()) + ) >> many0!(br) >> (RpcFunctionDeclaration { name, arg, ret }) ) @@ -632,6 +645,7 @@ mod test { service RpcService { rpc function0(InStruct0) returns (OutStruct0); rpc function1(InStruct1) returns (OutStruct1); + rpc function2 ( InStruct2 ) returns ( OutStruct2 ) { } } "#; @@ -641,6 +655,7 @@ mod test { let service = &descriptor.rpc_services.get(0).expect("Service not found!"); let func0 = service.functions.get(0).expect("Function 0 not returned!"); let func1 = service.functions.get(1).expect("Function 1 not returned!"); + let func2 = service.functions.get(2).expect("Function 2 not returned!"); assert_eq!("RpcService", service.service_name); assert_eq!("function0", func0.name); assert_eq!("InStruct0", func0.arg); @@ -648,6 +663,9 @@ mod test { assert_eq!("function1", func1.name); assert_eq!("InStruct1", func1.arg); assert_eq!("OutStruct1", func1.ret); + assert_eq!("function2", func2.name); + assert_eq!("InStruct2", func2.arg); + assert_eq!("OutStruct2", func2.ret); } other => panic!("Could not parse RPC Service: {:?}", other), } @@ -666,5 +684,4 @@ mod test { other => panic!("Could not parse RPC Function Declaration: {:?}", other), } } - } diff --git a/quick-protobuf/Cargo.toml b/quick-protobuf/Cargo.toml index 89c96503..1accacb9 100644 --- a/quick-protobuf/Cargo.toml +++ b/quick-protobuf/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "quick-protobuf" description = "A pure Rust protobuf (de)serializer. Quick." -version = "0.6.3" +version = "0.6.4" authors = ["Johann Tuffe "] keywords = ["protobuf", "parser"] license = "MIT" diff --git a/quick-protobuf/src/reader.rs b/quick-protobuf/src/reader.rs index df4a81bf..63f8f5c5 100644 --- a/quick-protobuf/src/reader.rs +++ b/quick-protobuf/src/reader.rs @@ -261,7 +261,11 @@ impl BytesReader { /// Reads fixed64 (little endian u64) #[inline] fn read_fixed M>(&mut self, bytes: &[u8], len: usize, read: F) -> Result { - let v = read(&bytes[self.start..self.start + len]); + let v = read( + &bytes + .get(self.start..self.start + len) + .ok_or_else(|| Error::UnexpectedEndOfBuffer)?, + ); self.start += len; Ok(v) } @@ -341,14 +345,19 @@ impl BytesReader { /// Reads bytes (Vec) #[inline] pub fn read_bytes<'a>(&mut self, bytes: &'a [u8]) -> Result<&'a [u8]> { - self.read_len_varint(bytes, |r, b| Ok(&b[r.start..r.end])) + self.read_len_varint(bytes, |r, b| { + b.get(r.start..r.end) + .ok_or_else(|| Error::UnexpectedEndOfBuffer) + }) } /// Reads string (String) #[inline] pub fn read_string<'a>(&mut self, bytes: &'a [u8]) -> Result<&'a str> { self.read_len_varint(bytes, |r, b| { - ::core::str::from_utf8(&b[r.start..r.end]).map_err(|e| e.into()) + b.get(r.start..r.end) + .ok_or_else(|| Error::UnexpectedEndOfBuffer) + .and_then(|x| ::core::str::from_utf8(x).map_err(|e| e.into())) }) } diff --git a/run_test.sh b/run_test.sh index 3872eee7..391b48c4 100755 --- a/run_test.sh +++ b/run_test.sh @@ -4,9 +4,11 @@ set -e ./generate_modules.sh -cargo run -p quick-protobuf --example pb_rs_example_v3_owned -cargo run -p quick-protobuf --example pb_rs_example -cargo run -p quick-protobuf --example pb_rs_example_v3 -cargo run --no-default-features -p quick-protobuf --example pb_rs_example_nostd +pushd quick-protobuf +cargo run --example pb_rs_example_v3_owned +cargo run --example pb_rs_example +cargo run --example pb_rs_example_v3 +cargo run --example pb_rs_example_nostd --no-default-features +popd cargo test -p pb-rs -p quick-protobuf