For taking a instance of a structure and generating a proc_macro2::TokenStream
of tokens which generate the structure
rust
self_rust_tokenize::SelfRustTokenize::to_tokens(String::new("Hello")) === quote!(String::new("Hello"));
Deriving on a custom type
```rust
struct A(i32);
let a = A(12); selfrusttokenize::SelfRustTokenize::to_tokens(a) == quote!(A(12)); ```
The use case may be: sharing a structure between a crate that deals with instances of it and a proc macro crate which generates tokens that build the instances in a exported proc macro
```rust /// Base definition crate pub enum SpecialStructure { // ... }
impl SpecialStructure { pub fn generatefrominput(&str) -> Self { // Some long implementation } }
/// Proc macro crate use base_crate::SpecialStructure;
pub fn makespecialstructure(item: TokenStream) -> TokenStream { let input = parsemacroinput!(item as LitStr).value(); let instance = SpecialStructure::generatefrominput(&input); let instanceconstructor = instance.totokens(); (quote! { { use ::basecrate::SpecialStructure; #instanceconstructor } }).into() }
/// Main crate SpecialStructure::generatefrominput("hello") === makespecialstructure!("hello") ```
note that the derived token stream is not scoped, you have to import the structures themselves
self_rust_tokenize::SelfRustTokenize
trait and not quote::ToTokens
?quote::ToTokens
is defined on many types in std to return a more primitive representation of themselves and can lose their type structure. On the other hand self_rust_tokenize::SelfRustTokenize
implementations on std types keeps the type constructor information. Thus a new trait (self_rust_tokenize::SelfRustTokenize
) is needed to prevent implementation conflicts.
e.g.
rust
self_rust_tokenize::SelfRustTokenize::to_tokens(String::new("Hello")) === quote!(String::new("Hello"));
quote::ToTokens::to_tokens(String::new("Hello")) === quote!("Hello");