-2

Say there is an user that wants to query a random element during runtime from a dynamic struct. The type of the data is unknown, but all the data is either a integer (size unknown), float, string, or vector of one of the aft-mentioned structs, and the struct implements the queryable trait, which mandates that the struct have get methods for all of the data the user is allowed to query.

1
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. Commented Apr 5, 2023 at 6:32

1 Answer 1

1

Rust has no run-time reflection capabilities, so you'll have to implement your own infrastructure for dynamic introspection. You will also likely want the results of such a query to be serializable, and/or to follow a simpler data model (e.g. the JSON data model).

For example, we might define:

enum Value<'a> {
  Queryable(&'a dyn Queryable),
  Json(serde_json::Value),
}

trait Queryable {
  fn query<'a>(&'a self, fieldname: &str) -> Option<Value<'a>>;
}

impl Queryable for Value {
  fn query<'a>(&'a self, fieldname: &str) -> Option<Value<'a>> {
    match self {
      Queryable(q) => q.query(fieldname),
      Json(json) => json.as_object()?.get(fieldname).cloned()
    }
  }
}

struct Root {
  foo: Foo,
}

impl Queryable for Root {
  fn query<'a>(&'a self, fieldname: &str) -> Option<Value<'a>> {
    match fieldname {
      "foo" => Some(Value::Queryable(&self.foo)),
      _ => None,
    }
  }
}

struct Foo {
  bar: f64,
}

impl Queryable for Foo {
  fn query<'a>(&'a self, fieldname: &str) -> Option<Value<'a>> {
    match fieldname {
      "bar" => Some(Value::Json(self.bar.into())),
      _ => None,
    }
  }
}

Then, a nested object access root.foo.bar could be conducted via this model as root.query("foo")?.query("bar").

Implementing your own introspection infrastructure can be tiring, especially since a lot of it could be automated using proc-macros. I recommend looking into async_graphql which has to solve similar problems, as well as Rust-based template engines (though most just use Serde to serialize the objects into a simpler data model). Note that while Serde might make it possible to run some queries over a data model by writing a custom serializer, it doesn't really provide convenient introspection abilities.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.