Skip to content

Commit

Permalink
Add basic example and fix Getting Started section of README
Browse files Browse the repository at this point in the history
  • Loading branch information
YuhanLiin committed Nov 10, 2024
1 parent 22545d4 commit 8500a38
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 28 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ members = [
"examples/no-panicking",
"examples/file-descriptor-set",
"examples/arm-app",
"examples/basic",
]

# For the no-panicking example
Expand Down
45 changes: 31 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,21 @@ The `micropb` project consists of two crates:
Add `micropb` crates to your `Cargo.toml`:
```toml
[dependencies]
micropb = "0.1"
# Allow types from `heapless` to be used for container fields
micropb = { version = "0.1.0", features = ["container-heapless"] }

[build-dependencies]
# Allow types from `heapless` to be used for container fields
micropb-gen = { version = "0.1", features = ["container-heapless"] }
micropb-gen = "0.1.0"
```

Then, place your `.proto` file into the project's root directory:
```proto
// example.proto
message Example {
int32 field1 = 1;
bool field2 = 2;
double field3 = 3;
}
```

`micropb-gen` requires `protoc` to build `.proto` files, so [install `protoc`](https://grpc.io/docs/protoc-installation) and add it to your PATH, then invoke the code generator in `build.rs`:
Expand All @@ -58,8 +68,7 @@ fn main() {
Finally, include the generated file in your code:
```rust,ignore
// main.rs
use micropb::{PbRead, PbDecoder, MessageDecode, MessageEncode};
use micropb::{MessageDecode, MessageEncode, PbDecoder, PbEncoder};
mod example {
#![allow(clippy::all)]
Expand All @@ -70,22 +79,30 @@ mod example {
}
fn main() {
let mut example = example::Example::default();
let data: &[u8] = &[ /* Protobuf data bytes */ ];
// Construct new decoder from byte slice
let mut decoder = PbDecoder::new(data);
// Decode a new instance of `Example` into an existing struct
example.decode(&mut decoder, data.len()).expect("decoding failed");
let example = example::Example {
field1: 12,
field2: true,
field3: 0.234,
..Default::default()
};
// Use heapless::Vec as the output stream and build an encoder around it
let mut encoder = PbEncoder::new(micropb::heapless::Vec::<u8, 10>::new());
let mut encoder = PbEncoder::new(micropb::heapless::Vec::<u8, 32>::new());
// Compute the size of the `Example` on the wire
let size = example.compute_size();
// Encode the `Example` to the data stream
example.encode(&mut encoder).expect("Vec over capacity");
let data = encoder.into_writer();
// Construct new decoder from byte slice
let mut decoder = PbDecoder::new(data.as_slice());
// Decode a new instance of `Example` into a new struct
let mut new = example::Example::default();
new.decode(&mut decoder, data.len())
.expect("decoding failed");
assert_eq!(example, new);
}
```

Expand Down
12 changes: 12 additions & 0 deletions examples/basic/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "basic"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
micropb = { version = "0.1", path = "../../micropb", features = ["container-heapless"] }

[build-dependencies]
micropb-gen = { version = "0.1", path = "../../micropb-gen" }
9 changes: 9 additions & 0 deletions examples/basic/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
fn main() {
let mut gen = micropb_gen::Generator::new();
// Compile example.proto into a Rust module
gen.compile_protos(
&["example.proto"],
std::env::var("OUT_DIR").unwrap() + "/example.rs",
)
.unwrap();
}
17 changes: 17 additions & 0 deletions examples/basic/example.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
syntax = "proto3";

message Example {
int32 f_int32 = 1;
int64 f_int64 = 2;
uint32 f_uint32 = 3;
uint64 f_uint64 = 4;
sint32 f_sint32 = 5;
sint64 f_sint64 = 6;
bool f_bool = 7;
fixed32 f_fixed32 = 8;
fixed64 f_fixed64 = 9;
sfixed32 f_sfixed32 = 10;
sfixed64 f_sfixed64 = 11;
float f_float = 12;
double f_double = 13;
}
36 changes: 36 additions & 0 deletions examples/basic/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use micropb::{MessageDecode, MessageEncode, PbDecoder, PbEncoder};

mod example {
#![allow(clippy::all)]
#![allow(nonstandard_style, unused, irrefutable_let_patterns)]
// Let's assume that Example is the only message define in the .proto file that has been
// converted into a Rust struct
include!(concat!(env!("OUT_DIR"), "/example.rs"));
}

fn main() {
let example = example::Example {
f_int32: 12,
f_bool: true,
f_float: 0.234,
..Default::default()
};

// Use heapless::Vec as the output stream and build an encoder around it
let mut encoder = PbEncoder::new(micropb::heapless::Vec::<u8, 32>::new());

// Compute the size of the `Example` on the wire
let _size = example.compute_size();
// Encode the `Example` to the data stream
example.encode(&mut encoder).expect("Vec over capacity");

let data = encoder.into_writer();
// Construct new decoder from byte slice
let mut decoder = PbDecoder::new(data.as_slice());

// Decode a new instance of `Example` into a new struct
let mut new = example::Example::default();
new.decode(&mut decoder, data.len())
.expect("decoding failed");
assert_eq!(example, new);
}
45 changes: 31 additions & 14 deletions micropb/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,21 @@ The `micropb` project consists of two crates:
Add `micropb` crates to your `Cargo.toml`:
```toml
[dependencies]
micropb = "0.1"
# Allow types from `heapless` to be used for container fields
micropb = { version = "0.1.0", features = ["container-heapless"] }

[build-dependencies]
# Allow types from `heapless` to be used for container fields
micropb-gen = { version = "0.1", features = ["container-heapless"] }
micropb-gen = "0.1.0"
```

Then, place your `.proto` file into the project's root directory:
```proto
// example.proto
message Example {
int32 field1 = 1;
bool field2 = 2;
double field3 = 3;
}
```

`micropb-gen` requires `protoc` to build `.proto` files, so [install `protoc`](https://grpc.io/docs/protoc-installation) and add it to your PATH, then invoke the code generator in `build.rs`:
Expand All @@ -58,8 +68,7 @@ fn main() {
Finally, include the generated file in your code:
```rust,ignore
// main.rs
use micropb::{PbRead, PbDecoder, MessageDecode, MessageEncode};
use micropb::{MessageDecode, MessageEncode, PbDecoder, PbEncoder};
mod example {
#![allow(clippy::all)]
Expand All @@ -70,22 +79,30 @@ mod example {
}
fn main() {
let mut example = example::Example::default();
let data: &[u8] = &[ /* Protobuf data bytes */ ];
// Construct new decoder from byte slice
let mut decoder = PbDecoder::new(data);
// Decode a new instance of `Example` into an existing struct
example.decode(&mut decoder, data.len()).expect("decoding failed");
let example = example::Example {
field1: 12,
field2: true,
field3: 0.234,
..Default::default()
};
// Use heapless::Vec as the output stream and build an encoder around it
let mut encoder = PbEncoder::new(micropb::heapless::Vec::<u8, 10>::new());
let mut encoder = PbEncoder::new(micropb::heapless::Vec::<u8, 32>::new());
// Compute the size of the `Example` on the wire
let size = example.compute_size();
// Encode the `Example` to the data stream
example.encode(&mut encoder).expect("Vec over capacity");
let data = encoder.into_writer();
// Construct new decoder from byte slice
let mut decoder = PbDecoder::new(data.as_slice());
// Decode a new instance of `Example` into a new struct
let mut new = example::Example::default();
new.decode(&mut decoder, data.len())
.expect("decoding failed");
assert_eq!(example, new);
}
```

Expand Down

0 comments on commit 8500a38

Please sign in to comment.