Skip to content

Instantly share code, notes, and snippets.

@colin-kiegel
Created February 1, 2017 22:53
Embed
What would you like to do?
Rust Cologne Meetup 2017-02-01 - macros 1.1
<!DOCTYPE html>
<html>
<head>
<title>macros 1.1</title>
<meta charset="utf-8">
<style>
@import url(https://fonts.googleapis.com/css?family=Yanone+Kaffeesatz);
@import url(https://fonts.googleapis.com/css?family=Droid+Serif:400,700,400italic);
@import url(https://fonts.googleapis.com/css?family=Ubuntu+Mono:400,700,400italic);
body { font-family: 'Droid Serif'; }
h1, h2, h3 {
font-family: 'Yanone Kaffeesatz';
font-weight: normal;
}
.remark-code, .remark-inline-code { font-family: 'Ubuntu Mono'; }
</style>
</head>
<body>
<textarea id="source">
class: center, middle
# macros 1.1
2017-02-01
Rust Cologne Meetup
Colin Kiegel
---
# macros 1.0
_code generation in Rust today_
1. pattern macros (aka macros by example)
- PRO: good hygiene
- CON: restrictive
2. procedural macros
- PRO: powerful
- CON: only nightly compiler
3. build scripts
- PRO: powerful
- CON: hacky + inconvenient
???
- three ways
- popular libraries require nightly compiler (serde / diesel)
---
# macros **2**.0
_the roadmap_
- pattern macros
- improve hygiene
- less restrictions
- procedural macros
- simplify API
- stable compiler support
???
- will take very long.
---
# the show-stopper
- popular libraries require nightly compiler (serde / diesel)
- solution seems faaaar away .. _unless_ ..
---
# derive
most important use case for code generation
```rust
#[derive(PartialEq)]
struct Foo<T> {
a: i32,
b: T,
}
```
---
# derive
```rust
struct Foo<T> {
a: i32,
b: T,
}
impl<T: PartialEq> PartialEq for Foo<T> {
fn eq(&self, other: &Foo<T>) -> bool {
self.a == other.a && self.b == other.b
}
fn ne(&self, other: &Foo<T>) -> bool {
self.a != other.a || self.b != other.b
}
}
```
---
# welcome macros 1.**1**
custom derive (Rust 1.15)
- minimal API:
- TokenStream <-> String conversion
- helper libs:
- e.g. syn/quote for String <-> AST conversion
???
- scheduled for 2017-02-02
---
# example
code generation in Rust literally _tomorrow_
```rust
// ..
pub fn foo(input: TokenStream) -> TokenStream {
let source = input.to_string();
// Parse the string representation into a syntax tree
let ast = syn::parse_derive_input(&source).unwrap();
// Build the output, possibly using quasi-quotation
let expanded = quote! {
// ...
};
// Parse back to a token stream and return it
expanded.parse().unwrap()
}
```
---
# getting started
https://github.com/dtolnay/syn (<-- s/rustc/proc/)
```rust
extern crate proc_macro;
use proc_macro::TokenStream;
extern crate syn;
#[macro_use]
extern crate quote;
#[proc_macro_derive(Foo)]
pub fn foo(input: TokenStream) -> TokenStream {
// ..
}
```
see also: https://doc.rust-lang.org/beta/book/procedural-macros.html
</textarea>
<script src="https://gnab.github.io/remark/downloads/remark-latest.min.js">
</script>
<script>
var slideshow = remark.create();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment