How to implement similar structs in a smart way?

Hello people,

first, I don't have much experience in Rust but to learn more about it I want to implement the following. I want to have an struct Object looking like

enum ObjectType {
   Bool,
   Integer,
   String,
   Name,
   Dict,
}

struct Object {
   object_numer: Option<u32>,
   object_type: ObjectType,
   data: ...
}

where data should have a type depending on object_type. I tried something like

enum ObjectType {
   Bool(bool),
   Integer(u32),
   Name(&'static str),
   ...
}

but for Dict I could not do it, since it should be something like HashMap<ObjectType::Name, Object>. Does someone has suggestions on how to implement this instead of making a separate struct for each ObjectType with the respective type of data and the corresponding fn set_data()?

why couldn't you use a HashMap for the dict? You should have clarified thay.
I assume you got some error like "recursive type has infinite size". If that's the case, it means you need some kind of pointer indirection, such as boxing the recursive type.

struct Foo {
  a: i32,
  recursive_foo: Foo,
}

try and reason about the size of the above Foo struct. a struct's size is equal to the sum of all of it's fields sizes. so in this case: sizeof Foo = sizeof i32 + sizeof Foo. which you'll see leads to sizeof Foo being infinite.
however if we write it like this:

struct Foo {
  a: i32,
  recursive_foo: Box<Foo>,
}

then the size can be calculated, since a boxed type always has size 8 (unless it's a boxed dst, which has size 16).

Does this work?

enum ObjectValue {
    Bool(bool),
    Integer(u32),
    String(String),
    Dict(HashMap<String, ObjectValue>),
}

Because I was not able make the key type of the HashMap ObjectType::Name. I guess this was due to ObjectType::Name not being a type, but an element of an enum.

@tczajka I guess this would work, but the String should only be 127 bytes long, for which I probably could make a struct.

I don't understand what you mean. String is already a struct and is a pretty good data type to represent strings of up to 127 bytes long. If you want to represent names as &'static str like you did in the OP, you can use HashMap<&'static str, ObjectValue>. But that is more limiting than String because &'static str implies the string has to live in memory until the end of the whole program.

If you want to optimize memory use or performance or something like that, there are ways you could approach it, but that's a separate issue, and only recommended if you actually need to optimize.

1 Like

The data structure I want to mimic allows the string representing the key's name in the Dict data type to only be 127 bytes long. Can I alter the String type to only allow for this many bytes?

If you want to enforce that, you probably want a newtype wrapping the hashmap that checks length on insertion. It would involve some amount of boilerplate.

3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.