-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.

Star
  • 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. – Community Apr 05 '23 at 06:32

1 Answers1

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.

amon
  • 134,135