valuable icon indicating copy to clipboard operation
valuable copied to clipboard

Implement valuable value pointer

Open taiki-e opened this issue 4 years ago • 6 comments

Example

use valuable::*;

#[derive(Valuable)]
struct Struct1 {
    x: String,
    y: Struct2,
}

#[derive(Valuable)]
struct Struct2 {
    z: String,
}

struct Visitor;

impl Visit for Visitor {
    fn visit_value(&mut self, value: Value<'_>) {
        println!("{:?}", value);
    }
}

fn main() {
    let value = Struct1 {
        x: "a".to_owned(),
        y: Struct2 {
            z: "b".to_owned(),
        },
    };

    let mut visitor = Visitor;

    visit_pointer!(value.x, visitor);   // "a"
    visit_pointer!(value.y, visitor);   // Struct2 { z: "b" }
    visit_pointer!(value.y.z, visitor); // "b"
}

TODO

  • [ ] function to create Pointer from str
  • [ ] decide APIs
    • [ ] naming
      • [ ] types and methods in pointer module
      • [ ] rename valuable-derive to valuable-macro(s)? (because visit_pointer! macro is proc-macro)
  • [ ] write docs
  • [x] add tests

taiki-e avatar Jun 30 '21 16:06 taiki-e

Can there be a Pointer::from_str? When querying data at runtime on arbitrary paths, you can't build a macro.

Keats avatar Jul 04 '21 06:07 Keats

@Keats Good point. It definitely makes sense to provide the ability to dynamically create a pointer from str.

taiki-e avatar Jul 06 '21 05:07 taiki-e

@taiki-e ping me when it's ready it works for a str, I'll be happy to try it out!

Keats avatar Jul 07 '21 17:07 Keats

@taiki-e is that still planned? Can I help?

Keats avatar Oct 13 '21 07:10 Keats

Another thought: in addition to having the macros (and possibly a Pointer::parse("x.y.z"), as suggested in https://github.com/tokio-rs/valuable/pull/59#issuecomment-873531929), I wonder if it would make sense to have a programmatic builder API for constructing pointer paths? Something like

/// `x[0].y`
let ptr = Pointer::builder()
   .field("x")
   .index(0)
   .field("y")
   .finish();

or similar?

But, that can probably be added in a follow-up branch as well.

hawkw avatar Oct 13 '21 16:10 hawkw

Also, I wonder if it would be worth adding a method like

pub trait Valuable {
   // ...

   fn get_pointer<'a>(&'a self, pointer: Pointer<'_>) -> Option<Value<'a>> {
      // ...
   }
}

that traverses a Pointer path and returns it as a Value if the pointed path exists in self?

This could probably have a default implementation (or be part of an extension trait, in order to make it totally impossible for users to override it).

visit_pointer is a method for it: https://github.com/tokio-rs/valuable/pull/59/files#diff-a7abcaf3ded7efa976120acbbda5060e74513453ccbced80d88a443dc464110fR75-R78

taiki-e avatar Nov 23 '21 07:11 taiki-e