I see. There isn't a great API for this right now. The problem is, once a
struct Builder is already allocated, the struct can't be resized. But if
you're trying to copy the content of another struct into it, it's possible
that other struct was originally created with a newer version of the schema
which had new fields defined, and so it is larger. If the data were copied
from that larger struct into the smaller struct that has been allocated,
the new fields would be silently dropped. I wanted to avoid that situation.

One thing you could do is manually invoke
Capability::Client::typelessReuqest(), manually passing the
appropriate interface and method IDs. Then you get a request where the root
type is AnyPointer, which you can set to an existing struct. This avoids
the problem of dropping unknown fields, since the destination struct isn't
allocated until the source is known, and it is then allocated with the same
size as the source.

Perhaps we should update the code generator to generate RPC client methods
that can accept an existing struct Reader as input, to make this nicer.

-Kenton

On Thu, Jun 3, 2021 at 8:59 AM Vaci <v...@vaci.org> wrote:

> Ah, I figured out that I can use the layered API to decode each item in
> the list individually:
>
>     Bar::Client cap;
>     kj::ArrayPtr<const char> text;
>     capnp::MallocMessageBuilder mb;
>     capnp::JsonCodec codec;
>     kj::ArrayBuilder<kj::Promise<void>> promises;
>
>     auto value = mb.initRoot<capnp::JsonValue>();
>     codec.decodeRaw(text, value);
>
>     for (auto&& entry: value.getArray()) {
>       auto request = cap.fooRequest();
>       codec.decode(entry, request);
>       promises.add(request.send().ignoreResult());
>     }
>
> However, I'd still be curious to know how to create a request from an
> existing struct, if that's at all possible!
>
> Many thanks,
> Vaci
>
> On Thursday, 3 June 2021 at 09:10:32 UTC+1 Vaci wrote:
>
>> That's not quite what I want to do. Given that a request is a struct
>> type, I want to copy or assign an existing struct to the whole request.
>>
>> I can use the json decoder to write content into the request struct, but
>> I don't see a way to do that when I'm holding an orphan pointer to a struct
>> that is of the same type as the request.
>>
>> Vaci
>>
>> On Wednesday, 2 June 2021 at 15:36:55 UTC+1 ken...@cloudflare.com wrote:
>>
>>> Hi Vaci,
>>>
>>> An RPC request is always a struct type, not a list, so I assume what you
>>> really mean here is that you want to use the list as a field of the
>>> request? E.g. you have:
>>>
>>> struct Foo {}
>>>
>>> interface Bar {
>>>   foo @0 (foos :List(Foo));
>>> }
>>>
>>>
>>> Then you would do:
>>>
>>> auto req = bar.fooRequest();
>>>
>>> auto orphanage = capnp::Orphanage::getForMessageContaining(req);
>>>
>>> auto orphan = json.decode<capnp::List<Foo>>(txt, orphanage);
>>>
>>> req.adoptFoos(kj::mv(orphan));
>>>
>>>
>>> -Kenton
>>>
>>> On Wed, Jun 2, 2021 at 6:29 AM Vaci <va...@vaci.org> wrote:
>>>
>>>> I may be missing something obvious, but is it possible to copy the
>>>> content of a struct into the body of a request builder?
>>>>
>>>> I have an interface of the form:
>>>>
>>>>    struct Foo {};
>>>>
>>>>   interface Bar {
>>>>      foo @0 Foo;
>>>>   };
>>>>
>>>> I want to import a bunch of Foo structures using the json reader and
>>>> use them to populate the requests. This works fine with a single item,
>>>> because I can just decode directly into the request body:
>>>>
>>>> auto foo = bar.fooRequest();
>>>> capnp::JsonCodec json;
>>>> json.decode(txt, foo);
>>>>
>>>> ...but if my input is a list of items, the json decoder will return an
>>>> (orphaned) list of Foo structures, and I can't see a way to use each item
>>>> as request params.
>>>>
>>>> Vaci
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Cap'n Proto" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>> an email to capnproto+...@googlegroups.com.
>>>> To view this discussion on the web visit
>>>> https://groups.google.com/d/msgid/capnproto/55a2f540-cece-474f-8795-b65e15f024e1n%40googlegroups.com
>>>> <https://groups.google.com/d/msgid/capnproto/55a2f540-cece-474f-8795-b65e15f024e1n%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>> .
>>>>
>>> --
> You received this message because you are subscribed to the Google Groups
> "Cap'n Proto" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to capnproto+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/capnproto/206b1c60-4525-487b-82c4-a97db415807cn%40googlegroups.com
> <https://groups.google.com/d/msgid/capnproto/206b1c60-4525-487b-82c4-a97db415807cn%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to capnproto+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/capnproto/CAJouXQkHi6kF9BKBc5BZiKdPkgjff5WGfHcHgt3-Z5zBDjxKNQ%40mail.gmail.com.

Reply via email to