Giter VIP home page Giter VIP logo

Comments (15)

dwrensha avatar dwrensha commented on September 22, 2024

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.

vks avatar vks commented on September 22, 2024

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.

dwrensha avatar dwrensha commented on September 22, 2024

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.

vks avatar vks commented on September 22, 2024

To then get a builder again, we would need an AsBuilder trait, right?

from capnproto-rust.

dwrensha avatar dwrensha commented on September 22, 2024

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.

dwrensha avatar dwrensha commented on September 22, 2024

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.

dwrensha avatar dwrensha commented on September 22, 2024

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 an OwnedBuilder?

fn get<'a>(&'a self) -> ::capnp::Result<<T as ::capnp::traits::Owned<'a>>::Reader> {
   self.message.get_root_as_reader()
}

from capnproto-rust.

bspeice avatar bspeice commented on September 22, 2024

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.

dwrensha avatar dwrensha commented on September 22, 2024

Does it work like this?

pub enum Archivable {
    MarketData(OwnedReader<market_data::Owned>)
}

from capnproto-rust.

bspeice avatar bspeice commented on September 22, 2024

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.

dwrensha avatar dwrensha commented on September 22, 2024

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.

bspeice avatar bspeice commented on September 22, 2024

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.

dwrensha avatar dwrensha commented on September 22, 2024

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.

bspeice avatar bspeice commented on September 22, 2024

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.

tv42 avatar tv42 commented on September 22, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.