Comments (15)
This is the kind of thing I had in mind:
pub struct OwnedReader<T> where T : for<'a> ::capnp::traits::Owned<'a> {
marker: ::std::marker::PhantomData<T>,
message: ::capnp::message::Reader<::capnp::serialize::OwnedSegments>,
}
impl <T> OwnedReader<T> where T: for <'a> ::capnp::traits::Owned<'a> {
pub fn get<'a> (&'a self) -> ::capnp::Result<<T as ::capnp::traits::Owned<'a>>::Reader >
{
self.message.get_root()
}
}
This lets you pass around an owned message without losing type information.
If the data you care about is not at the root of a message, then probably the easiest thing to do would be to copy the data into the root of a new message and then use the above pattern directly.
from capnproto-rust.
How would you implement fn get<'a>(&'a self)
for an OwnedBuilder
?
If I have
struct OwnedBuilder<T> where T: for<'a> ::capnp::traits::Owned<'a> {
marker: ::std::marker::PhantomData<T>,
message: ::capnp::message::Builder<::capnp::message::HeapAllocator>,
}
then implementing get_mut
is straightforward:
impl<T> OwnedBuilder<T> where T: for<'a> ::capnp::traits::Owned<'a> {
fn get_mut<'a>(&'a mut self) -> ::capnp::Result<<T as ::capnp::traits::Owned<'a>>::Builder>
{
self.message.get_root()
}
}
Is it possible to implement
fn get<'a>(&'a self) -> ::capnp::Result<<T as ::capnp::traits::Owned<'a>>::Reader>
as well?
from capnproto-rust.
Unfortunately, that's not possible yet. One way that we might get it to work would be to define a new trait
pub trait AsReader<Reader> {
fn as_reader(self) -> Reader;
}
and we would and then adjust the definition of Owned
:
pub trait Owned<'a> {
type Reader: FromPointerReader<'a> + SetPointerBuilder<Self::Builder>;
type Builder: FromPointerBuilder<'a> + AsReader<Self::Reader>;
}
from capnproto-rust.
To then get a builder again, we would need an AsBuilder
trait, right?
from capnproto-rust.
No, you wouldn't be able to go from a Reader
to a Builder
. That would be roughly equivalent to going from a &Foo
to a &mut Foo
.
from capnproto-rust.
Note also that the generated Builder<'a>
structs have a method borrow_as_reader()
:
impl <'a> Builder<'a> {
pub fn borrow_as_reader<'b>(&'b self) -> Reader<'b> {...}
}
It seems like it would be useful to put this in a trait too, but it seems like we might need higher-kinded types to do so.
Like, we kind of want to define
pub trait Owned<'a> {
type Reader: FromPointerReader<'a> + SetPointerBuilder<Self::Builder>;
type Builder: FromPointerBuilder<'a> + AsReader<Self::Reader> + BorrowAsReader<Self::Reader>;
}
But what would the definition of BorrowAsReader
be?
pub trait BorrowAsReader<Reader> {
fn as_reader(&'a self) -> Reader<'a>;
}
... this doesn't quite work because of the lifetime parameter on Reader
.
from capnproto-rust.
As of 9b4167d, which introduced get_root_as_reader()
, we now have a satisfactory answer to #50 (comment)
How would you implement
fn get<'a>(&'a self)
for anOwnedBuilder
?
fn get<'a>(&'a self) -> ::capnp::Result<<T as ::capnp::traits::Owned<'a>>::Reader> {
self.message.get_root_as_reader()
}
from capnproto-rust.
I'm trying to get an owned reference so I can send this across a thread, and I've copied the above code as follows:
pub struct OwnedReader<T> where T : for<'a> ::capnp::traits::Owned<'a> {
marker: ::std::marker::PhantomData<T>,
message: ::capnp::message::Reader<::capnp::serialize::OwnedSegments>,
}
impl <T> OwnedReader<T> where T: for <'a> ::capnp::traits::Owned<'a> {
pub fn get<'a> (&'a self) -> ::capnp::Result<<T as ::capnp::traits::Owned<'a>>::Reader >
{
self.message.get_root_as_reader()
}
}
And when I try to use a reader like
pub enum Archivable<'a> {
MarketData(OwnedReader<market_data::Reader<'a>>)
}
I get the compile-time exception of:
the trait `for<'a> capnp::traits::Owned<'a>` is not implemented for `market_data_capnp::market_data::Reader<'a>`
Am I approaching this incorrectly? My current workaround is to just send a struct containing the message content as Vec<u8>
and empty enum, and construct the Reader on the other side.
from capnproto-rust.
Does it work like this?
pub enum Archivable {
MarketData(OwnedReader<market_data::Owned>)
}
from capnproto-rust.
Yes after a slight modification to OwnedReader
:
pub struct OwnedReader<T> where T : for<'a> ::capnp::traits::Owned<'a> {
marker: ::std::marker::PhantomData<T>,
message: ::capnp::message::Reader<::capnp::serialize::OwnedSegments>,
}
impl <T> OwnedReader<T> where T: for <'a> ::capnp::traits::Owned<'a> {
pub fn get<'a> (&'a self) -> ::capnp::Result<<T as ::capnp::traits::Owned<'a>>::Reader >
{
**self.message.get_root()**
}
}
Final question though: How do I create an OwnedReader<market_data::Owned>
? Given that market_data::Owned
is an empty struct, I'm not sure where the Vec<u8>
is actually owned at. Thanks for the help!
from capnproto-rust.
Something like this should work:
impl <T> OwnedReader<T> where T : for<'a> ::capnp::traits::Owned<'a> {
pub fn new(message: ::capnp::message::Reader<::capnp::serialize::OwnedSegments>) -> Self {
OwnedReader {
marker: ::std::marker::PhantomData,
message: message,
}
}
}
can be called like this:
OwnedReader<market_data::Owned>::new(message)
from capnproto-rust.
Brilliant. Got this working using standard ::capnp::serialize::read_message()
, greatly appreciate the help. Any chance this could get added to the default library? I'd be happy to write up something on how to use it, and I know this would be helpful for #23 as well.
from capnproto-rust.
Yeah, enough people have asked about this that it would probably make sense to add it to the library. Seems like it would belong in the capnp::message
module. I would lean towards making the OwnedSegments
part generic too, like:
pub struct OwnedReader<S, T>
where S: ::capnp::message::ReaderSegments,
T : for<'a> ::capnp::traits::Owned<'a>
{
marker: ::std::marker::PhantomData<T>,
message: ::capnp::message::Reader<S>,
}
from capnproto-rust.
Working on tests for recently merged code. Is there a way of creating address_book::Owned
from static information (i.e. like in the example)? I'm currently using serialize::read_message
to get back a Reader<OwnedSegments>
.
from capnproto-rust.
I think the easiest path is BufferSegments, see #259 (comment) -- this may be new since the last comment from 2018.
from capnproto-rust.
Related Issues (20)
- Primitive list panicks if the list type is `Void` HOT 1
- Null values for non active union members HOT 3
- Switch Allocator to act more like an owned arena HOT 8
- Reader fails with out of bounds pointer error when reading from compressed stream HOT 1
- Revert text setter ergonomics pessification; add raw_set methods HOT 6
- calculator example fails with java server: Cannot read capability pointer without capTable HOT 2
- c++.capnp compiles to unusable module name HOT 6
- How to send generated readers across threads HOT 3
- From bytes to TypedReader HOT 6
- Allowing construction of NoAllocSliceSegments with buffer and NoAllocBufferSegmentType HOT 7
- Kudos to builders of this Rust library - Every single one of you. HOT 3
- [Question]How to extract generic type values HOT 5
- capnp_rpc does not work on monoio HOT 4
- Dynamic parsing of fields may panic HOT 1
- traits.ListIter incorrectly implementing ExactSizeIterator HOT 1
- oc
- Using same schema file for both Rust and C++ HOT 1
- doc: read_message_from_flat_slice_no_alloc docstring bad autocomplete HOT 1
- Making rust capn proto fully async HOT 2
- Is there any reason why Rc<RefCell> is used compared to Arc<Mutex>?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from capnproto-rust.