wolf4ood/gremlin-rs

TryFromGremlinMap Proc Macro

Closed this issue · 4 comments

Outline

  • Initially would be derivable on struct which contains fields which can Into<GValue>.
  • Would be great to support serializing into foreign types such as Uuid but will require much more work and I am not sure how the implementation should look. Perhaps its something serde can help with?

Purpose

  • Reduce chaining of .get("field").unwrap().get().unwrap() to just one step Struct::try_from_map(map)?

@wolf4ood Any ideas on what supporting serialization into foreign types would look like?

Hi @jdeepee

i've started to work a little bit on this on branch gremlin-derive

The final usage should be something like this

https://github.com/wolf4ood/gremlin-rs/blob/gremlin-derive/gremlin-client/tests/integration_client.rs#L420

Ideally by using FromGValue derive macro we should be able to bind most of the important structs Vertex,Edge,Map etc to custom structs.

WDYT? :)

This is awesome! I just added a PR that allows converting from Map -> custom struct.

The only things left for me would be the ability to have serialization for custom enum's coming from strings in a map as well as serialization of nested types. This is outside of my scope of proc macro knowledge for immediate implementation however.

Example of what I mean:

    #[derive(FromGMap)]
    enum CustomEnum {
        UserType,
        UserType2,
    }

    #[derive(FromGMap)]
    struct User {
        id: Uuid,
        #[gremlin_client(map_value = "type")]
        custom_type: CustomEnum,
        friends: Vec<User>,
    }

    let user = g
        .add_v("user")
        .property("type", CustomEnum::UserType.to_string())
        .as_("source_user")
        .add_v("user")
        .property("type", CustomEnum::UserType.to_string())
        .as_("target_user")
        .add_("friend")
        .from(__.select("source_user"))
        .to(__.select("target_user"))
        .next();

    let user = g
        .v(user.id())
        .as_("user")
        .value_map(true)
        .project(vec!["id", "type", "friends"])
        .by()
        .by()
        .by(__.select("user").out("friend").value_map(true));

    let user = User::try_from(user)?;

Hi @jdeepee

i get what you mean. Still not sure how to implement it.

I've released the PR with proc macro for Map and FromGValue. I would consider this closed.

For the other requirement i would say let's open another issue to track it :)

Thanks