fernandobatels / rsfbclient

Rust Firebird Client
MIT License
76 stars 11 forks source link

Make FromRow/IntoParam traits more generic #71

Closed dancingbug closed 3 years ago

dancingbug commented 4 years ago

I think it may be possible to make these traits more generic, and maybe get rid of the single/plural distinction of IntoParam/IntoParams

The technique would be based on type level cons-lists (sometimes called HList or heterogeneous list). I made an example, pasted at the bottom of this comment for demonstration

if we have impl<A:IntoParams, B:IntoParams> IntoParams for (A,B) {...

Then no further trait impl should be needed for (A,(B,(C,(D ... (X, (Y,Z))))))))...

So if we expose a macro to the user for right-associating arbitrary tuples (we could have params!(a,b,c..) become (a, (b, (c, ...)) or do something with a list-builder like param_list.push(x).push(y).push(z) then we can have statically-typed, arbitrary-length parameter lists whenever it's actually possible, without vectors, and without generating a bunch of trait impls for different tuple types.

here is an existing crate with helper macros for this kind of thing: https://docs.rs/tuple_list/0.1.2/tuple_list/

code snippet to demonstrate feasibility

below is a bit of example code to demonstrate this approach and show that it's probably feasible in some way (rust playground link)

trait IntoParams {}
struct A0;
struct A1;
struct A2;
struct A3;
struct A4;
impl IntoParams for A0{}
impl IntoParams for A1{}
impl IntoParams for A2{}
impl IntoParams for A3{}
impl IntoParams for A4{}
impl<A:IntoParams, B:IntoParams> IntoParams for (A,B) {}
fn use_flub<T: IntoParams>(flub: T){}

fn main() {
   let a_flub: (A0, (A1, (A2, (A3, (A4, A0))))) = (A0,(A1,(A2,(A3,(A4,A0)))));
    //proof that a_flub is an IntoParams. otherwise we wouldn't be able to pass it to use_flub
    use_flub(a_flub);
}

This might also simplify an implementation of "compile-time named parameters", if we ever do that.

The vector approach, or something similar, will probably still be needed for some situations

fernandobatels commented 4 years ago

This is a nice resource for use in the #67. For now I'm working directly with the IntoParams trait and some test Structs, but we can solve cases with multiple struct's in the params.