lyonsyonii / akin Goto Github PK
View Code? Open in Web Editor NEWRust crate for writing repetitive code easier and faster.
Rust crate for writing repetitive code easier and faster.
Hi @LyonSyonII,
First of all, thanks for creating akin
. I like the approach quit a lot.
I'm wondering if global substitutions, and generating items only once can be added to akin
.
An example describes the use case best:
Imagine we would like to create an extension trait for serde_json::Value that adds methods like into_xy
methods that return owned values.
I'd create and implement a trait like this:
trait ValueExt {
fn into_null(self) -> Result<(), Self>;
fn into_bool(self) -> Result<bool, Self>;
fn into_array(self) -> Result<Vec<Value>, Self>;
// etc...
}
impl ValueExt for Value {
fn into_null(self) -> Result<(), Self> { todo!()}
fn into_bool(self) -> Result<bool, Self> { todo!()}
fn into_array(self) -> Result<Vec<Value>, Self> { todo!()}
// etc...
}
Instead of writing all of this by hand, I'd like to use akin
to generate the trait and the trait implementation:
akin::akin! {
let &ident = [ null, bool, array, /* ... */ ];
let &Type = [
{ () },
{ bool },
{ Vec<Value> },
// ...
];
trait JsonValueExt {
fn into_~*ident(self) -> Result<*Type, Self>;
}
impl ValueExt for serde_json::Value {
fn into_~*ident(self) -> Result<*Type, Self> { todo!() }
}
}
But of course this doesn't work (JsonValueExt
is defined several times).
I'm wondering if this use case somehow can be supported.
For example via something like this:
akin::akin! {
// ...
#[akin(context)]
trait JsonValueExt {
// A new `akin` context
fn into_~*ident(self) -> Result<*Type, Self>;
}
// ...
}
#[akin(context)]
would tell akin
to generate the decorated item only once, and substitute within the item (similar to how $($ident)+
works for macro_rules
macros). Something like akin_context! { /* new context */ }
probably also would be useful, for cases where attributes can't be used.
My first idea for a name of the new attribute was inner
, but I think that wouldn't be ideal, because it should be possible to substitute things within the trait definition itself (e.g. for generic traits). Maybe there is a better name than context
, however.
Similarly, the duplicate
crate has a nice feature to define global substitutions, which often come in handy.
I'm wondering if this can be supported via something like:
akin::akin! {
// ...
const &foo = { println!("Hello, world!") };
*foo
// ...
}
...which would expand to just one println!("Hello, world!")
.
Using const
here would be perfect semantically, I believe.
These features would make akin
useful in even more cases.
Currently, I have created an additional macro_rules
macro to generate the trait definition (duplicating the &Type
and &ident
definitions), which works but is not really ideal.
Would it be possible to add these features?
Currently, I haven't learned how to use procedural macros, so I currently can't add these features myself. But if you don't want to add this yourself, but would accept a PR, I could do this when I learn procedural macros at some point (however, that would most likely be at least several months into the future, if not more).
Thanks again for creating akin
!
Hi @LyonSyonII
As of now I don't think there is a good way to express some repetitions:
impl<T> Foo for T where T: Baz<A> + Baz<B> + ... {}
//We could do
akin! {
let &Type = [B, ...];
let &bound = { + Baz<*Type> };
impl<T> Foo for T where T: Baz<A> *bound {}
}
//Or
akin! {
let &Type = [A, B, ...];
let &separator = [NONE, +, ...]
let &bound = { *separator Baz<*Type> };
impl<T> Foo for T where T: *bound {}
}
It would be nice to be able to specify a separator. Maybe something along those lines:
akin! {
let &Type = [A, B, ...];
let &bound = { Baz<*Type> };
impl<T> Foo for T where T: *{+}bound {}
}
Hi @LyonSyonII,
I just discovered a bug:
akin! {
let &foo = [abc];
let &foobar = [def];
*foo
*foobar
}
The foo
of *foobar
gets replaced with abc
.
for example, I need to use akin to make the following code simpler, but some how can't get it to work. If akin can accept a parameter, it will be great!
impltableinfo!(2, T1, Q1, T2, Q2);
impltableinfo!(3, T1, Q1, T2, Q2, T3, Q3);
impltableinfo!(4, T1, Q1, T2, Q2, T3, Q3, T4, Q4);
impltableinfo!(5, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5);
impltableinfo!(6, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6);
impltableinfo!(7, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7);
impltableinfo!(8, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8);
impltableinfo!(9, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8, T9, Q9);
impltableinfo!(10, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8, T9, Q9, TA, QA);
impltableinfo!(11, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8, T9, Q9, TA, QA, TB, QB);
impltableinfo!(12, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8, T9, Q9, TA, QA, TB, QB, TC, QC);
impltableinfo!(13, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8, T9, Q9, TA, QA, TB, QB, TC, QC, TD, QD);
impltableinfo!(14, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8, T9, Q9, TA, QA, TB, QB, TC, QC, TD, QD, TE, QE);
impltableinfo!(15, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8, T9, Q9, TA, QA, TB, QB, TC, QC, TD, QD, TE, QE, TF, QF);
impltableinfo!(16, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8, T9, Q9, TA, QA, TB, QB, TC, QC, TD, QD, TE, QE, TF, QF, TG, QG);
impltableinfo!(17, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8, T9, Q9, TA, QA, TB, QB, TC, QC, TD, QD, TE, QE, TF, QF, TG, QG, TH, QH);
impltableinfo!(18, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8, T9, Q9, TA, QA, TB, QB, TC, QC, TD, QD, TE, QE, TF, QF, TG, QG, TH, QH, TI, QI);
impltableinfo!(19, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8, T9, Q9, TA, QA, TB, QB, TC, QC, TD, QD, TE, QE, TF, QF, TG, QG, TH, QH, TI, QI, TJ, QJ);
impltableinfo!(20, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8, T9, Q9, TA, QA, TB, QB, TC, QC, TD, QD, TE, QE, TF, QF, TG, QG, TH, QH, TI, QI, TJ, QJ, TL, QL);
impltableinfo!(21, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8, T9, Q9, TA, QA, TB, QB, TC, QC, TD, QD, TE, QE, TF, QF, TG, QG, TH, QH, TI, QI, TJ, QJ, TL, QL, TM, QM);
impltableinfo!(22, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8, T9, Q9, TA, QA, TB, QB, TC, QC, TD, QD, TE, QE, TF, QF, TG, QG, TH, QH, TI, QI, TJ, QJ, TL, QL, TM, QM, TN, QN);
impltableinfo!(23, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8, T9, Q9, TA, QA, TB, QB, TC, QC, TD, QD, TE, QE, TF, QF, TG, QG, TH, QH, TI, QI, TJ, QJ, TL, QL, TM, QM, TN, QN, TO, QO);
impltableinfo!(24, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8, T9, Q9, TA, QA, TB, QB, TC, QC, TD, QD, TE, QE, TF, QF, TG, QG, TH, QH, TI, QI, TJ, QJ, TL, QL, TM, QM, TN, QN, TO, QO, TP, QP);
impltableinfo!(25, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8, T9, Q9, TA, QA, TB, QB, TC, QC, TD, QD, TE, QE, TF, QF, TG, QG, TH, QH, TI, QI, TJ, QJ, TL, QL, TM, QM, TN, QN, TO, QO, TP, QP, TQ, QQ);
impltableinfo!(26, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8, T9, Q9, TA, QA, TB, QB, TC, QC, TD, QD, TE, QE, TF, QF, TG, QG, TH, QH, TI, QI, TJ, QJ, TL, QL, TM, QM, TN, QN, TO, QO, TP, QP, TQ, QQ, TR, QR);
impltableinfo!(27, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8, T9, Q9, TA, QA, TB, QB, TC, QC, TD, QD, TE, QE, TF, QF, TG, QG, TH, QH, TI, QI, TJ, QJ, TL, QL, TM, QM, TN, QN, TO, QO, TP, QP, TQ, QQ, TR, QR, TS, QS);
impltableinfo!(28, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8, T9, Q9, TA, QA, TB, QB, TC, QC, TD, QD, TE, QE, TF, QF, TG, QG, TH, QH, TI, QI, TJ, QJ, TL, QL, TM, QM, TN, QN, TO, QO, TP, QP, TQ, QQ, TR, QR, TS, QS, TT, QT);
impltableinfo!(29, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8, T9, Q9, TA, QA, TB, QB, TC, QC, TD, QD, TE, QE, TF, QF, TG, QG, TH, QH, TI, QI, TJ, QJ, TL, QL, TM, QM, TN, QN, TO, QO, TP, QP, TQ, QQ, TR, QR, TS, QS, TT, QT, TU, QU);
impltableinfo!(30, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8, T9, Q9, TA, QA, TB, QB, TC, QC, TD, QD, TE, QE, TF, QF, TG, QG, TH, QH, TI, QI, TJ, QJ, TL, QL, TM, QM, TN, QN, TO, QO, TP, QP, TQ, QQ, TR, QR, TS, QS, TT, QT, TU, QU, TV, QV);
impltableinfo!(31, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8, T9, Q9, TA, QA, TB, QB, TC, QC, TD, QD, TE, QE, TF, QF, TG, QG, TH, QH, TI, QI, TJ, QJ, TL, QL, TM, QM, TN, QN, TO, QO, TP, QP, TQ, QQ, TR, QR, TS, QS, TT, QT, TU, QU, TV, QV, TW, QW);
impltableinfo!(32, T1, Q1, T2, Q2, T3, Q3, T4, Q4, T5, Q5, T6, Q6, T7, Q7, T8, Q8, T9, Q9, TA, QA, TB, QB, TC, QC, TD, QD, TE, QE, TF, QF, TG, QG, TH, QH, TI, QI, TJ, QJ, TL, QL, TM, QM, TN, QN, TO, QO, TP, QP, TQ, QQ, TR, QR, TS, QS, TT, QT, TU, QU, TV, QV, TW, QW, TX, QX);
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.