Playing around with the Rust reflect lib
Days ago, I noticed an interesting lib called reflect. It looks like it’s a sort of macro writing helper lib. Macros are cool, especially in Common Lisp. Rust macros can also bring some fun, but to be honest, they aren’t easy to write. (This is the repo of a macro I wrote in Rust).
So, I’m curious how to use this repo.
Run some demos
I have to be honest that I don’t really understand the README of the repo. So I found the tests/debug directory and tried to study from there.
My first question was, what is reflect::library!
? I used cargo expand
on it, but that was actually a bit misleading. Eventually, I went back to the literal meaning and realized that extern crate
seems to provide a fake interface for future usage.
In mod.rs
, I found that derive
is used in the test files by checking the expanded result.
So, I did the same thing, changing Debug
to MyDebug
.
After copying the result from the repo’s test file, it returned the failed result, as I expected:
assertion `left == right` failed
left: "impl :: std :: fmt :: MyDebug for Point { fn fmt (& self , __arg0 : & mut :: std :: fmt :: Formatter) -> :: std :: fmt :: Result { let __v0 = self ; let __v1 = __arg0 ; let __v3 = & __v0 . x ; let __v4 = & __v0 . y ; let mut __v5 = :: std :: fmt :: Formatter :: debug_struct (__v1 , \"Point\") ; let __v6 = & mut __v5 ; let _ = :: std :: fmt :: DebugStruct :: field (__v6 , \"x\" , __v3) ; let _ = :: std :: fmt :: DebugStruct :: field (__v6 , \"y\" , __v4) ; let __v11 = :: std :: fmt :: DebugStruct :: finish (__v6) ; __v11 } }"
right: "impl :: std :: fmt :: Debug for Point { fn fmt (& self , __arg0 : & mut :: std :: fmt :: Formatter) -> :: std :: fmt :: Result { let __v0 = self ; let __v1 = __arg0 ; let __v3 = & __v0 . x ; let __v4 = & __v0 . y ; let mut __v5 = :: std :: fmt :: Formatter :: debug_struct (__v1 , \"Point\") ; let __v6 = & mut __v5 ; let _ = :: std :: fmt :: DebugStruct :: field (__v6 , \"x\" , __v3) ; let _ = :: std :: fmt :: DebugStruct :: field (__v6 , \"y\" , __v4) ; let __v11 = :: std :: fmt :: DebugStruct :: finish (__v6) ; __v11 } }"
This means that MyDebug
truly affects derive
.
Make it derivable
Now that I understand what it’s doing, I’m going to try to make it derivable.
First, I uncommented this block and needed to comment out the derive
function above.
Then, I used it here. The compiler gave me the error that it couldn’t find MyDebug
in std::fmt
.
Then, I commented out MyDebug
and put back the real Debug
in extern crate
here. And it works now.
Next Step
I am thinking of re-writing the cl-format-macro with this reflect lib.
Conclusion
First, the biggest question was what reflect::library!
does. After understanding that it’s some kind of header file/golang interface, everything is much cleaner.
Second, proc macros are always fun to me because they require a higher level of thinking about the language. But I prefer Common Lisp macros.