I'm interfacing with a C library that provides Array(list) and Dictionary (key + value) functionalities. Both produce and consume Entrys that I'm trying to model in Rust. Those Entrys can be of basic types, but also Arrays or Dictionarys holding Entrys themselves. As an additional requirement, any changes to an Entrymust be forwarded to the underlying C lib with a function call.
Available types
- String
- Integer
- Boolean
- Array (list of these types; mixing types allowed)
- Dictionary (key + value of these types; mixing allowed)
Requirements
- Build hierarchy of arbitrary combination of those types. Nesting allowed.
- Write any changes to an
Entryback to the C lib
Taking serde as reference for how to model a JSON structure, I tried building those Entrys as an enum:
enum Entry {
String(String),
Integer(i32),
Boolean(bool),
Array(Vec<Entry>),
Dict(HashMap<String, Entry>)
}
That works well.
Now I tried to implement my additional requirement: forward any changes to an Entry to the underlying C lib. So I added the reference I get from the C lib as id:
enum Entry {
String{value: String, id: isize},
Integer{value: i32, id: isize},
Boolean{value: bool, id: isize},
Array{value: Vec<Entry>, id: isize},
Dict{value: HashMap<String, Entry>, id: isize}
}
And now I only need to make sure to call update(id, value) on the C lib whenever an Entry gets updated. So I add getter/setter methods and am done. Well, I can't do that, as I can't implement on enum variants (e.g. Entry::String).
Looks like I hit a dead end here.
Second approach: Generic structs.
trait EntryTypes {}
impl EntryTypes for String {}
impl EntryTypes for i32 {}
impl EntryTypes for bool {}
pub struct Entry<T> {
id: isize,
value: T,
}
trait EntryType<T> {
fn value(&self) -> T;
fn set_value(&mut self, value: T);
}
impl<T: EntryTypes> Entry<T> {
fn new(value: T, id: isize) -> Self {
Self { value, id }
}
}
This works for the simple types, but I can't get it to work with Vec and HashMap:
impl EntryTypes for Vec<Box<Entry<EntryTypes>>> {}
The size for values of type `(dyn EntryTypes + 'static)` cannot be known at compilation time
How do I need to approach this?