update readme, set add nix shell
This commit is contained in:
@@ -1 +1,4 @@
|
|||||||
target/
|
target/
|
||||||
|
|
||||||
|
.direnv
|
||||||
|
.envrc
|
||||||
@@ -2,6 +2,95 @@
|
|||||||
|
|
||||||
**Misses** is a DSL compiler that transforms `.mrs` macro definitions into ready-to-use Rust proc macro source files. Write your macro once in a concise, readable syntax; Misses generates the full `syn`/`quote` boilerplate for you.
|
**Misses** is a DSL compiler that transforms `.mrs` macro definitions into ready-to-use Rust proc macro source files. Write your macro once in a concise, readable syntax; Misses generates the full `syn`/`quote` boilerplate for you.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Why Misses?
|
||||||
|
|
||||||
|
Writing proc macros means wrestling with `syn` parsing, `quote!` boilerplate, error handling, and variadic patterns. You write the same patterns over and over.
|
||||||
|
|
||||||
|
**Misses lets you write the macro once, in readable syntax, and generates all the boilerplate for you.**
|
||||||
|
|
||||||
|
Here's a real example:
|
||||||
|
|
||||||
|
### `derive_getters.mrs`
|
||||||
|
|
||||||
|
```mrs
|
||||||
|
macro derive_getters! {
|
||||||
|
struct $name:ident { $($field:ident : $ty:ty),* } => {
|
||||||
|
T~{
|
||||||
|
impl $name {
|
||||||
|
for field in $fields =>
|
||||||
|
pub fn $field.name(&self) -> &$field.ty { &self.$field.name }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<details>
|
||||||
|
|
||||||
|
<summary>
|
||||||
|
<b>Generated output</b>
|
||||||
|
</summary>
|
||||||
|
|
||||||
|
```rust
|
||||||
|
|
||||||
|
extern crate proc_macro;
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn derive_rpc(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||||
|
let input = proc_macro2::TokenStream::from(input);
|
||||||
|
use quote::format_ident;
|
||||||
|
let (name, params, ret) = {
|
||||||
|
use syn::parse::Parser as _;
|
||||||
|
let __parser = |
|
||||||
|
_input: syn::parse::ParseStream,
|
||||||
|
| -> syn::Result<(syn::Ident, Vec<(syn::Ident, syn::Type)>, syn::Type)> {
|
||||||
|
let name: syn::Ident = _input.parse()?;
|
||||||
|
let params = {
|
||||||
|
let mut __f = Vec::new();
|
||||||
|
while !__brace_content.is_empty() {
|
||||||
|
let __fn: syn::Ident = __brace_content.parse()?;
|
||||||
|
__brace_content.parse::<syn::Token![:]>()?;
|
||||||
|
let __ft: syn::Type = __brace_content.parse()?;
|
||||||
|
__f.push((__fn, __ft));
|
||||||
|
if __brace_content.peek(syn::Token![,]) {
|
||||||
|
__brace_content.parse::<syn::Token![,]>()?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__f
|
||||||
|
};
|
||||||
|
let ret: syn::Type = _input.parse()?;
|
||||||
|
Ok((name, params, ret))
|
||||||
|
};
|
||||||
|
match __parser.parse2(input.clone()) {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(e) => return e.into_compile_error().into(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let req_name = format_ident!("{}Request", name);
|
||||||
|
let res_name = format_ident!("{}Response", name);
|
||||||
|
let __spread_0: proc_macro2::TokenStream = params
|
||||||
|
.iter()
|
||||||
|
.map(|(__field_name, __field_ty)| {
|
||||||
|
quote::quote! {
|
||||||
|
pub # __field_name : # __field_ty,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let __output = quote::quote! {
|
||||||
|
pub struct # req_name { # __spread_0 } pub struct # res_name { pub result : #
|
||||||
|
ret, }
|
||||||
|
};
|
||||||
|
__output.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Quick start
|
## Quick start
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{ pkgs ? import <nixpkgs> {}}:
|
||||||
|
pkgs.mkShell {
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
# Rust toolchain
|
||||||
|
cargo
|
||||||
|
rustc
|
||||||
|
rustfmt
|
||||||
|
clippy
|
||||||
|
rust-analyzer
|
||||||
|
|
||||||
|
# Additional tools
|
||||||
|
cargo-watch
|
||||||
|
cargo-edit
|
||||||
|
# Profiling tools
|
||||||
|
cargo-flamegraph
|
||||||
|
samply
|
||||||
|
perf
|
||||||
|
];
|
||||||
|
|
||||||
|
# Environment variables
|
||||||
|
RUST_BACKTRACE = 1;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user