miniconf icon indicating copy to clipboard operation
miniconf copied to clipboard

[derive] support generic `Tree` types of generic depth

Open ryan-summers opened this issue 1 year ago • 4 comments

Currently, it doesn't seem possible to do the following properly:

struct A<T: TreeKey<Y>, const Y: usize> {
    inner: T,
    outer: u32,
}

We would need to annotate the inner: T with #[tree(depth(Y))], but the current depth parsing requires an integer. The depth isn't known until compile time, but is known to be Y >= 1. It seems like the depth should optionally take this compile-time generic as well.

ryan-summers avatar Mar 22 '24 13:03 ryan-summers

Hmm, it's actually not possible to know what the depth of the outer structure should be when a generic depth is present. I.e. what if you have one item marked as #[tree(depth(3))] and another with #[tree(depth(Y))]. Should we implement TreeKey<Y+1> or TreeKey<4>? It's possible that Y could be both greater than or less than 3.

I think we can probably just work around this for now by mandating:

  1. Only a single generic depth may be used in a structure
  2. Any generic depth will automatically be assumed to be the deepest component of the tree.

If we have a future use case, we could add more macros to override these assumptions.

ryan-summers avatar Mar 22 '24 14:03 ryan-summers

The issue is the generic depth Y here, not the generic type T. With fixed Y it should work fine (https://github.com/quartiq/miniconf/blob/18e56cca8a26ee0833ec61afd7c3b40ca8ac6f51/tests/generics.rs#L68)

You could blanket generate the impls in the derive macro for many Y (like it's done for arrays). Or we'd need to make the the derive explicitly derive only one Y and stop auto-detecting/auto-guessing it.

jordens avatar Mar 22 '24 14:03 jordens

I think a blanket implementation is actually the only way. Arithmetic on const generics (i.e. impl TreeKey<{Y + 1}>) is not stable currently.

ryan-summers avatar Mar 22 '24 15:03 ryan-summers

One problem would be that a generic field type may not be dominating the overall depth. Then the outer detph would not determine the inner depth in all cases. The offset would have to be constant. And Y1,Y2 combinations of a struct with multiple inner generic types with generic depth would be impossible unless Y1 = Y2 + constant. A way to do this may be to support depth: Vec<usize> on fields and then determine the fixed offset.

jordens avatar Sep 30 '24 10:09 jordens