Thanks for the explanation on the interaction between schema evolution and 
copying structures, that makes sense. 
It may not be a common requirement to want to copy over the entire request 
structure, rather than just initialise a member from an existing reader.

For the moment, I only care about copying content from JSON, but 
typelessRequests might be a nice approach for generally recording and 
replaying RPC calls.

Thanks,
Vaci

On Friday, 4 June 2021 at 20:33:59 UTC+1 ken...@cloudflare.com wrote:

> 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 <va...@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+...@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/93df77ac-b408-465e-bc64-612fbbdc6c5dn%40googlegroups.com.

Reply via email to