Update main.rs to move messages across threads

master
Bradlee Speice 2018-01-18 22:54:36 -05:00
parent 838de4e485
commit 0d4cc1ffcd
13 changed files with 154 additions and 30 deletions

2
Cargo.lock generated
View File

@ -12,7 +12,7 @@ dependencies = [
]
[[package]]
name = "capnp_cookbook_1"
name = "capnp_cookbook_2"
version = "0.1.0"
dependencies = [
"capnp 0.8.14 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -1,5 +1,5 @@
[package]
name = "capnp_cookbook_1"
name = "capnp_cookbook_2"
version = "0.1.0"
authors = ["Bradlee Speice <bspeice@kcg.com>"]

BIN
src/.main.rs.swp Normal file

Binary file not shown.

View File

@ -1,57 +1,45 @@
// Note that we use `capnp` here, NOT `capnpc`
extern crate capnp;
// We create a module here to define how we are to access the code
// being included.
pub mod point_capnp {
// The environment variable OUT_DIR is set by Cargo, and
// is the location of all the code that was built as part
// of the codegen step.
// point_capnp.rs is the actual file to include
include!(concat!(env!("OUT_DIR"), "/point_capnp.rs"));
}
fn main() {
// The process of building a Cap'N Proto message is a bit tedious.
// We start by creating a generic Builder; it acts as the message
// container that we'll later be filling with content of our `Point`
let mut builder = capnp::message::Builder::new_default();
// Because we need a mutable reference to the `builder` later,
// we fence off this part of the code to allow sequential mutable
// borrows. As I understand it, non-lexical lifetimes:
// https://github.com/rust-lang/rust-roadmap/issues/16
// will make this no longer necessary
{
// And now we can set up the actual message we're trying to create
let mut point_msg = builder.init_root::<point_capnp::point::Builder>();
// Stuff our message with some content
point_msg.set_x(12);
point_msg.set_y(14);
}
// It's now time to serialize our message to binary. Let's set up a buffer for that:
let mut buffer = Vec::new();
// And actually fill that buffer with our data
capnp::serialize::write_message(&mut buffer, &builder).unwrap();
// Finally, let's deserialize the data
let deserialized = capnp::serialize::read_message(
&mut buffer.as_slice(),
capnp::message::ReaderOptions::new()
).unwrap();
// `deserialized` is currently a generic reader; it understands
// the content of the message we gave it (i.e. that there are two
// int32 values) but doesn't really know what they represent (the Point).
// This is where we map the generic data back into our schema.
let point_reader = deserialized.get_root::<point_capnp::point::Reader>().unwrap();
let point_reader: capnp::message::TypedReader<capnp::serialize::OwnedSegments, point_capnp::point::Owned> =
capnp::message::TypedReader::new(deserialized);
// We can now get our x and y values back, and make sure they match
assert_eq!(point_reader.get_x(), 12);
assert_eq!(point_reader.get_y(), 14);
// Because the point_reader is now working with OwnedSegments (which are owned vectors) and an Owned message
// (which is 'static lifetime), this is now safe
let handle = std::thread::spawn(move || {
// The point_reader owns its data, and we use .get() to retrieve the actual point_capnp::point::Reader
// object from it
let point_root = point_reader.get().unwrap();
assert_eq!(point_root.get_x(), 12);
assert_eq!(point_root.get_y(), 14);
});
handle.join().unwrap();
}

View File

@ -0,0 +1,135 @@
// Generated by the capnpc-rust plugin to the Cap'n Proto schema compiler.
// DO NOT EDIT.
// source: point.capnp
pub mod point {
#[derive(Copy, Clone)]
pub struct Owned;
impl <'a> ::capnp::traits::Owned<'a> for Owned { type Reader = Reader<'a>; type Builder = Builder<'a>; }
impl <'a> ::capnp::traits::OwnedStruct<'a> for Owned { type Reader = Reader<'a>; type Builder = Builder<'a>; }
impl ::capnp::traits::Pipelined for Owned { type Pipeline = Pipeline; }
#[derive(Clone, Copy)]
pub struct Reader<'a> { reader: ::capnp::private::layout::StructReader<'a> }
impl <'a,> ::capnp::traits::HasTypeId for Reader<'a,> {
#[inline]
fn type_id() -> u64 { _private::TYPE_ID }
}
impl <'a,> ::capnp::traits::FromStructReader<'a> for Reader<'a,> {
fn new(reader: ::capnp::private::layout::StructReader<'a>) -> Reader<'a,> {
Reader { reader: reader, }
}
}
impl <'a,> ::capnp::traits::FromPointerReader<'a> for Reader<'a,> {
fn get_from_pointer(reader: &::capnp::private::layout::PointerReader<'a>) -> ::capnp::Result<Reader<'a,>> {
::std::result::Result::Ok(::capnp::traits::FromStructReader::new(try!(reader.get_struct(::std::ptr::null()))))
}
}
impl <'a,> ::capnp::traits::Imbue<'a> for Reader<'a,> {
fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) {
self.reader.imbue(::capnp::private::layout::CapTableReader::Plain(cap_table))
}
}
impl <'a,> Reader<'a,> {
pub fn borrow<'b>(&'b self) -> Reader<'b,> {
Reader { .. *self }
}
pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> {
self.reader.total_size()
}
#[inline]
pub fn get_x(self) -> i32 {
self.reader.get_data_field::<i32>(0)
}
#[inline]
pub fn get_y(self) -> i32 {
self.reader.get_data_field::<i32>(1)
}
}
pub struct Builder<'a> { builder: ::capnp::private::layout::StructBuilder<'a> }
impl <'a,> ::capnp::traits::HasStructSize for Builder<'a,> {
#[inline]
fn struct_size() -> ::capnp::private::layout::StructSize { _private::STRUCT_SIZE }
}
impl <'a,> ::capnp::traits::HasTypeId for Builder<'a,> {
#[inline]
fn type_id() -> u64 { _private::TYPE_ID }
}
impl <'a,> ::capnp::traits::FromStructBuilder<'a> for Builder<'a,> {
fn new(builder: ::capnp::private::layout::StructBuilder<'a>) -> Builder<'a, > {
Builder { builder: builder, }
}
}
impl <'a,> ::capnp::traits::ImbueMut<'a> for Builder<'a,> {
fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) {
self.builder.imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table))
}
}
impl <'a,> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a,> {
fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Builder<'a,> {
::capnp::traits::FromStructBuilder::new(builder.init_struct(_private::STRUCT_SIZE))
}
fn get_from_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>) -> ::capnp::Result<Builder<'a,>> {
::std::result::Result::Ok(::capnp::traits::FromStructBuilder::new(try!(builder.get_struct(_private::STRUCT_SIZE, ::std::ptr::null()))))
}
}
impl <'a,> ::capnp::traits::SetPointerBuilder<Builder<'a,>> for Reader<'a,> {
fn set_pointer_builder<'b>(pointer: ::capnp::private::layout::PointerBuilder<'b>, value: Reader<'a,>) -> ::capnp::Result<()> { pointer.set_struct(&value.reader) }
}
impl <'a,> Builder<'a,> {
pub fn as_reader(self) -> Reader<'a,> {
::capnp::traits::FromStructReader::new(self.builder.as_reader())
}
pub fn borrow<'b>(&'b mut self) -> Builder<'b,> {
Builder { .. *self }
}
pub fn borrow_as_reader<'b>(&'b self) -> Reader<'b,> {
::capnp::traits::FromStructReader::new(self.builder.as_reader())
}
pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> {
self.builder.as_reader().total_size()
}
#[inline]
pub fn get_x(self) -> i32 {
self.builder.get_data_field::<i32>(0)
}
#[inline]
pub fn set_x(&mut self, value: i32) {
self.builder.set_data_field::<i32>(0, value);
}
#[inline]
pub fn get_y(self) -> i32 {
self.builder.get_data_field::<i32>(1)
}
#[inline]
pub fn set_y(&mut self, value: i32) {
self.builder.set_data_field::<i32>(1, value);
}
}
pub struct Pipeline { _typeless: ::capnp::any_pointer::Pipeline }
impl ::capnp::capability::FromTypelessPipeline for Pipeline {
fn new(typeless: ::capnp::any_pointer::Pipeline) -> Pipeline {
Pipeline { _typeless: typeless, }
}
}
impl Pipeline {
}
mod _private {
use capnp::private::layout;
pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 1, pointers: 0 };
pub const TYPE_ID: u64 = 0x9571424bb794dcc2;
}
}

BIN
target/debug/capnp_cookbook_2 Executable file

Binary file not shown.

View File

@ -0,0 +1 @@
/home/bspeice/Development/capnp_cookbook_2/target/debug/capnp_cookbook_2: /home/bspeice/Development/capnp_cookbook_2/src/main.rs /home/bspeice/Development/capnp_cookbook_2/target/debug/build/capnp_cookbook_2-a0bfc56364380222/out/point_capnp.rs /home/bspeice/Development/capnp_cookbook_2/build.rs