[Solved] Writing a JSON append function that's borrow-friendly

#1

I’m rewriting a C++ plugin that provides requests and JSON functionality. One of the functions is JsonAppend, which appends objects or arrays to one another. It takes an a and a b which are both slab-style “pointers” to a global pool of serde::Value objects.

So, a and b come in as integers which are then used to look up a JSON value in a HashMap - simple right?

The value that a points to should be acquired as mutable, because it’s being appended to. The value that b points to doesn’t need to be mutable because it’s being merged with a.

Here’s the corresponding C++ code:

And here’s my non-working Rust implementation of that function:

With the issue being that self.json_nodes is being borrowed twice.

Now, I thought of cloning the node pool but that seems wasteful, especially since the pool could get quite big and doing that on serialisation functions that may be called very frequently (users use this library for structured logging, so speed is something I’m focused on).

Would appreciate any help! I thought I had mastered the borrow checker but apparently not…

0 Likes

#2

So the problem you’re getting is that in the case that the second match results in Some(v) and there is already a reference to the first one (As in a succeeded) you end up with two references to objects under the same struct (self.json_nodes)? You could do the same thing you do in C++; clone it on get.
Otherwise, are you going to extend a with b or append a clone of b to a? Because if you were to do the latter, then clone b and take a &mut to a, or if you were to do the first one, then implement a remove function here and make it have a signature like so:

pub fn remove(&mut self, id: i32) -> Option<T> 

So that you can extract it, and extend a

0 Likes

#3

Ah, thanks, your reply made me re-think the order and move the b code above a and use clone, all works now!

1 Like

closed #4

This topic was automatically closed after 27 hours. New replies are no longer allowed.

0 Likes