Sergio Benitez sb@sergio.bz 1 Introduction to Rocket 2 Code - - PowerPoint PPT Presentation

sergio benitez
SMART_READER_LITE
LIVE PREVIEW

Sergio Benitez sb@sergio.bz 1 Introduction to Rocket 2 Code - - PowerPoint PPT Presentation

Sergio Benitez sb@sergio.bz 1 Introduction to Rocket 2 Code Generation in Rocket and Rust 3 Whats Next? 1 Introduction to Rocket Simple, Fast, Type-Safe Web Framework Powered by Rusts Code Generation Facilities Enables


slide-1
SLIDE 1
slide-2
SLIDE 2

Sergio Benitez

sb@sergio.bz

slide-3
SLIDE 3
slide-4
SLIDE 4

1

Introduction to Rocket

2 3

Code Generation in Rocket and Rust What’s Next?

slide-5
SLIDE 5

1

Introduction to Rocket

  • Simple, Fast, Type-Safe Web Framework
  • Powered by Rust’s Code Generation Facilities
  • Enables Secure, Robust Web Applications

2 3

Code Generation in Rocket and Rust What’s Next?

slide-6
SLIDE 6

1

Introduction to Rocket

2

Code Generation in Rocket and Rust

  • Demystifying the “Magic” of Code Generation
  • Present and Future Code Generation APIs

3

What’s Next?

slide-7
SLIDE 7

1

Introduction to Rocket

2 3

Code Generation in Rocket and Rust What’s Next?

  • What’s Coming in Future Versions of Rocket
  • Code Generation at Large
slide-8
SLIDE 8

1

Introduction to Rocket

2 3

Code Generation in Rocket and Rust What’s Next?

What’s Coming in Future Versions of Rocket Demystifying the “Magic” of Code Generation Simple, Fast, Type-Safe Web Framework

slide-9
SLIDE 9

1

Introduction to Rocket

2 3

Code Generation in Rocket and Rust What’s Next?

What’s Coming in Future Versions of Rocket Demystifying the “Magic” of Code Generation Simple, Fast, Type-Safe Web Framework

slide-10
SLIDE 10

Rocket is a web framework for Rust that makes it simple to write fast web applications without sacrificing flexibility or type safety.

slide-11
SLIDE 11
  • Dec. 23, 2016

Launch!

  • Feb. 06, 2017

v0.2

⋆2,670

  • Jul. 14, 2017

v0.3

slide-12
SLIDE 12
  • Dec. 23, 2016

Launch!

  • Feb. 06, 2017

v0.2

⋆ 2,670

  • Jul. 14, 2017

v0.3

in production

slide-13
SLIDE 13
slide-14
SLIDE 14
  • Dec. 23, 2016

Launch!

  • Feb. 06, 2017

v0.2

⋆2,670

  • Jul. 14, 2017

v0.3

slide-15
SLIDE 15
  • Dec. 23, 2016

Launch!

  • Feb. 06, 2017

v0.2

Early 2016

slide-16
SLIDE 16

Rocket is a web framework for Rust that makes it simple to write fast web applications without sacrificing flexibility or type safety.

slide-17
SLIDE 17

Routes (Hello, world!)

1 2 3 4 #[get("/")] fn hello() -> &'static str { "Hello, world!" }

slide-18
SLIDE 18

Routes (Hello, world!)

1 2 3 4 #[get("/")] fn hello() -> &'static str { "Hello, world!" }

1

Route Attribute: Description of matching condition.

1

slide-19
SLIDE 19

Routes (Hello, world!)

1 2 3 4 #[get("/")] fn hello() -> &'static str { "Hello, world!" }

1

Route Attribute: Description of matching condition.

1

2

Route Handler: Request processing, produces response.

2

slide-20
SLIDE 20

Routes (Hello, world!)

1 2 3 4 #[get("/")] fn hello() -> &'static str { "Hello, world!" }

1

Route Attribute: Description of matching condition.

1

2

Route Handler: Request processing, produces response.

2

slide-21
SLIDE 21

Routes (Hello, world!)

1 2 3 4 #[get("/")] fn hello() -> &'static str { "Hello, world!" }

1

Route Attribute: Description of matching condition.

1

2

Route Handler: Request processing, produces response.

2

slide-22
SLIDE 22

Routes (Hello, world!)

1 2 3 4 #[get("/")] fn hello() -> &'static str { "Hello, world!" }

1

Route Attribute: Description of matching condition.

1

2

Route Handler: Request processing, produces response.

2

slide-23
SLIDE 23

Mounting & Launching

1 2 3 4 5 6 7 8 #[get("/")] fn hello() -> &'static str { "Hello, world!" } fn main() { rocket::ignite().mount("/", routes![hello]).launch(); } #[get("/")] fn hello() -> &'static str { "Hello, world!" }

Routes need to be mounted to make Rocket aware.

slide-24
SLIDE 24

Mounting & Launching

1 2 3 4 5 6 7 8 #[get("/")] fn hello() -> &'static str { "Hello, world!" } fn main() { rocket::ignite().mount("/", routes![hello]).launch(); } #[get("/")] fn hello() -> &'static str { "Hello, world!" }

Mounting namespaces routes according to a root path.

slide-25
SLIDE 25

Mounting & Launching

1 2 3 4 5 6 7 8 #[get("/")] fn hello() -> &'static str { "Hello, world!" } fn main() { rocket::ignite().mount("/hello", routes![hello]).launch(); } #[get("/")] fn hello() -> &'static str { "Hello, world!" }

Mounting namespaces routes according to a root path.

slide-26
SLIDE 26

Mounting & Launching

1 2 3 4 5 6 7 8 #[get("/")] fn hello() -> &'static str { "Hello, world!" } fn main() { rocket::ignite().mount("/", routes![hello]).launch(); } #[get("/")] fn hello() -> &'static str { "Hello, world!" }

Mounting namespaces routes according to a root path.

slide-27
SLIDE 27

Mounting & Launching

1 2 3 4 5 6 7 8 #[get("/")] fn hello() -> &'static str { "Hello, world!" } fn main() { rocket::ignite().mount("/", routes![hello]).launch(); } #[get("/")] fn hello() -> &'static str { "Hello, world!" }

Launching starts up the server.

slide-28
SLIDE 28

Mounting & Launching

1 2 3 4 5 6 7 8 #[get("/")] fn hello() -> &'static str { "Hello, world!" } fn main() { rocket::ignite().mount("/", routes![hello]).launch(); } #[get("/")] fn hello() -> &'static str { "Hello, world!" }

Launching starts up the server. (also prints emojis 🚁)

slide-29
SLIDE 29

Mounting & Launching

1 2 3 4 5 6 7 8 #[get("/")] fn hello() -> &'static str { "Hello, world!" } fn main() { rocket::ignite().mount("/", routes![hello]).launch(); } #[get("/")] fn hello() -> &'static str { "Hello, world!" }

Launching starts up the server. (also prints emojis 🚁)

slide-30
SLIDE 30

Mounting & Launching

1 2 3 4 5 6 7 8 #[get("/")] fn hello() -> &'static str { "Hello, world!" } fn main() { rocket::ignite().mount("/", routes![hello]).launch(); } #[get("/")] fn hello() -> &'static str { "Hello, world!" }

slide-31
SLIDE 31

Mounting & Launching

1 2 3 4 5 6 7 8 #[get("/")] fn hello() -> &'static str { "Hello, world!" } fn main() { rocket::ignite().mount("/", routes![hello]).launch(); } #[get("/world")] fn hello() -> &'static str { "Hello, world!" }

slide-32
SLIDE 32

Mounting & Launching

1 2 3 4 5 6 7 8 #[get("/")] fn hello() -> &'static str { "Hello, world!" } fn main() { rocket::ignite().mount("/", routes![hello]).launch(); } #[get("/sergio")] fn hello() -> &'static str { "Hello, Sergio!" }

slide-33
SLIDE 33

Rocket is a web framework for Rust that makes it simple to write fast web applications without sacrificing flexibility or type safety.

slide-34
SLIDE 34

Dynamic Paths

slide-35
SLIDE 35

Dynamic Paths

slide-36
SLIDE 36

Dynamic Paths

1 2 3 4

Parameters in <brackets> match any text in segment.

#[get("/<name>/<age>")] fn hello(name: String, age: u8) -> String { format!("Hello, {} year old named {}!", age, name) }

slide-37
SLIDE 37

Dynamic Paths

1 2 3 4

Parameters in <brackets> match any text in segment.

#[get("/<name>/<age>")] fn hello(name: String, age: u8) -> String { format!("Hello, {} year old named {}!", age, name) }

  • Name in <brackets> must have matching function argument.
slide-38
SLIDE 38

Dynamic Paths

1 2 3 4

Parameters in <brackets> match any text in segment.

#[get("/<name>/<age>")] fn hello(name: String, number: u8) -> String { format!("Hello, {} year old named {}!", age, name) }

  • Name in <brackets> must have matching function argument.
slide-39
SLIDE 39
  • Name in <brackets> must have matching function argument.

Dynamic Paths

1 2 3 4

Parameters in <brackets> match any text in segment.

#[get("/<name>/<age>")] fn hello(name: String, number: u8) -> String { format!("Hello, {} year old named {}!", age, name) }

slide-40
SLIDE 40

Dynamic Paths

1 2 3 4

Parameters in <brackets> match any text in segment.

#[get("/<name>/<age>")] fn hello(name: String, number: u8) -> String { format!("Hello, {} year old named {}!", age, name) }

  • Name in <brackets> must have matching function argument.
slide-41
SLIDE 41

Dynamic Paths

1 2 3 4

Parameters in <brackets> match any text in segment.

#[get("/<name>/<age>")] fn hello(name: String, age: u8) -> String { format!("Hello, {} year old named {}!", age, name) }

  • Name in <brackets> must have matching function argument.
slide-42
SLIDE 42

Dynamic Paths

1 2 3 4

Parameters in <brackets> match any text in segment.

#[get("/<name>/<age>")] fn hello(name: String, age: u8) -> String { format!("Hello, {} year old named {}!", age, name) }

  • Type of dynamic parameter is declared in handler signature.
  • Any type implementing FromParam is allowed.
slide-43
SLIDE 43

Dynamic Paths

1 2 3 4

Parameters in <brackets> match any text in segment.

#[get("/<name>/<age>")] fn hello(name: String, age: u8) -> String { format!("Hello, {} year old named {}!", age, name) }

  • Handler can only be called if FromParam conversion succeeds.
slide-44
SLIDE 44

Preventing Directory Traversal

1 2 3 4

Implication: handlers are only called with validated data!

#[get(“/<path..>")] fn files(path: PathBuf) -> Option<NamedFile> { NamedFile::open(Path::new("static/").join(path)).ok() }

  • FromParam* implementation for PathBuf verifies path safety.
slide-45
SLIDE 45

Request Guards

slide-46
SLIDE 46

Request Guards

1 2 #[get("/admin")] fn admin_panel(admin: AdminUser) -> &'static str { ... }

Arbitrary number of FromRequest parameters allowed.

slide-47
SLIDE 47

Request Guards

1 2 #[get("/admin")] fn admin_panel(admin: AdminUser) -> &'static str { ... }

Request guards validate incoming request, protect handlers.

  • Guards may fail, preventing further request processing.
  • Guards may forward, indicating local failure.
slide-48
SLIDE 48

Request Guards & Forwarding

1 2 3 4 5 #[get("/admin")] fn admin_panel(admin: AdminUser) -> &'static str { ... } #[get("/admin", rank = 2)] fn admin_panel_user(user: User) -> &'static str { ... }

Forwarding: Rocket attempts colliding routes in ascending rank order.

#[get("/admin")] fn admin_panel(admin: AdminUser) -> &'static str { ... }

slide-49
SLIDE 49

Request Guards & Forwarding

1 2 3 4 5 #[get("/admin")] fn admin_panel(admin: AdminUser) -> &'static str { ... } #[get("/admin", rank = 2)] fn admin_panel_user(user: User) -> &'static str { ... }

Forwarding: Rocket attempts colliding routes in ascending rank order.

#[get("/admin")] fn admin_panel(admin: AdminUser) -> &'static str { ... }

slide-50
SLIDE 50

Request Guards & Forwarding

1 2 3 4 5 #[get("/admin")] fn admin_panel(admin: AdminUser) -> &'static str { ... } #[get("/admin", rank = 2)] fn admin_panel_user(user: User) -> &'static str { ... }

Forwarding: Rocket attempts colliding routes in ascending rank order.

#[get("/admin")] fn admin_panel(admin: AdminUser) -> &'static str { ... }

slide-51
SLIDE 51

Request Guards & Forwarding

1 2 3 4 5 #[get("/admin")] fn admin_panel(admin: AdminUser) -> &'static str { ... } #[get("/admin", rank = 2)] fn admin_panel_user(user: User) -> &'static str { ... }

Forwarding: Rocket attempts colliding routes in ascending rank order.

#[get("/admin")] fn admin_panel(admin: AdminUser) -> &'static str { ... }

slide-52
SLIDE 52

Request Guards & Forwarding

1 2 3 4 5 #[get("/admin")] fn admin_panel(admin: AdminUser) -> &'static str { ... } #[get("/admin", rank = 2)] fn admin_panel_user(user: User) -> &'static str { ... }

Forwarding: Rocket attempts colliding routes in ascending rank order.

#[get("/admin")] fn admin_panel(admin: AdminUser) -> &'static str { ... }

slide-53
SLIDE 53

Request Guards & Forwarding

1 2 3 4 5 #[get("/admin")] fn admin_panel(admin: AdminUser) -> &'static str { ... } #[get("/admin", rank = 2)] fn admin_panel_user(user: User) -> &'static str { ... }

Forwarding: Rocket attempts colliding routes in ascending rank order.

#[get("/admin")] fn admin_panel(admin: AdminUser) -> &'static str { ... }

slide-54
SLIDE 54

Request Guards & Forwarding

1 2 3 4 5 6 7 8 #[get("/admin")] fn admin_panel(admin: AdminUser) -> &'static str { ... } #[get("/admin", rank = 2)] fn admin_panel_user(user: User) -> &'static str { ... } #[get("/admin", rank = 3)] fn admin_panel_redirect() -> Redirect { ... } #[get("/admin")] fn admin_panel(admin: AdminUser) -> &'static str { ... } #[get("/admin", rank = 2)] fn admin_panel_user(user: User) -> &'static str { ... }

slide-55
SLIDE 55

1

Introduction to Rocket

2 3

Code Generation in Rocket and Rust What’s Next?

What’s Coming in Future Versions of Rocket Demystifying the “Magic” of Code Generation Simple, Fast, Type-Safe Web Framework

slide-56
SLIDE 56

1

Introduction to Rocket

2 3

Code Generation in Rocket and Rust What’s Next?

What’s Coming in Future Versions of Rocket Demystifying the “Magic” of Code Generation Simple, Fast, Type-Safe Web Framework

slide-57
SLIDE 57

1

Introduction to Rocket

2 3

Code Generation in Rocket and Rust What’s Next?

What’s Coming in Future Versions of Rocket Demystifying the “Magic” of Code Generation Simple, Fast, Type-Safe Web Framework

slide-58
SLIDE 58

Hello, World! Revisited

1 2 3 4 5 6 7 8 9 10 #[get("/")] fn hi() -> &'static str { "Hello, world!" } fn main() { rocket::ignite() .mount("/", routes![hi]) .launch(); }

slide-59
SLIDE 59

Hello, World! Revisited

1 2 3 4 5 6 7 8 9 10 #[get("/")] fn hi() -> &'static str { "Hello, world!" } fn main() { rocket::ignite() .mount("/", routes![hi]) .launch(); } static hi_info = RouteInfo { name: "hi", method: Method::Get, path: "/", handler: hi_route, format: None, rank: None, }; fn hi_route(req: &Request) -> Outcome { let responder = hi(); Outcome::from(req, responder) } .mount("/", vec![Route::from(&hi_info)]) 1 2 3 4 5 6 7 8 9 10 11 12 13 .. 16

slide-60
SLIDE 60

Hello, World! Revisited

1 2 3 4 5 6 7 8 9 10 #[get("/")] fn hi() -> &'static str { "Hello, world!" } fn main() { rocket::ignite() .mount("/", routes![hi]) .launch(); } static hi_info = RouteInfo { name: "hi", method: Method::Get, path: "/", handler: hi_route, format: None, rank: None, }; fn hi_route(req: &Request) -> Outcome { let responder = hi(); Outcome::from(req, responder) } .mount("/", vec![Route::from(&hi_info)]) 1 2 3 4 5 6 7 8 9 10 11 12 13 .. 16

slide-61
SLIDE 61

Hello, World! Revisited

1 2 3 4 5 6 7 8 9 10 #[get("/")] fn hi() -> &'static str { "Hello, world!" } fn main() { rocket::ignite() .mount("/", routes![hi]) .launch(); } static hi_info = RouteInfo { name: "hi", method: Method::Get, path: "/", handler: hi_route, format: None, rank: None, }; fn hi_route(req: &Request) -> Outcome { let responder = hi(); Outcome::from(req, responder) } .mount("/", vec![Route::from(&hi_info)]) 1 2 3 4 5 6 7 8 9 10 11 12 13 .. 16

slide-62
SLIDE 62

Hello, World! Revisited

1 2 3 4 5 6 7 8 9 10 #[get("/")] fn hi() -> &'static str { "Hello, world!" } fn main() { rocket::ignite() .mount("/", routes![hi]) .launch(); } static hi_info = RouteInfo { name: "hi", method: Method::Get, path: "/", handler: hi_route, format: None, rank: None, }; fn hi_route(req: &Request) -> Outcome { let responder = hi(); Outcome::from(req, responder) } .mount("/", vec![Route::from(&hi_info)]) 1 2 3 4 5 6 7 8 9 10 11 12 13 .. 16

slide-63
SLIDE 63

Hello, World! Revisited

1 2 3 4 5 6 7 8 9 10 #[get("/")] fn hi() -> &'static str { "Hello, world!" } fn main() { rocket::ignite() .mount("/", routes![hi]) .launch(); } static hi_info = RouteInfo { name: "hi", method: Method::Get, path: "/", handler: hi_route, format: None, rank: None, }; fn hi_route(req: &Request) -> Outcome { let responder = hi(); Outcome::from(req, responder) } .mount("/", vec![Route::from(&hi_info)]) 1 2 3 4 5 6 7 8 9 10 11 12 13 .. 16

slide-64
SLIDE 64

Hello, World! Revisited

1 2 3 4 5 6 7 8 9 10 #[get("/")] fn hi() -> &'static str { "Hello, world!" } fn main() { rocket::ignite() .mount("/", routes![hi]) .launch(); } static hi_info = RouteInfo { name: "hi", method: Method::Get, path: "/", handler: hi_route, format: None, rank: None, }; fn hi_route(req: &Request) -> Outcome { let responder = hi(); Outcome::from(req, responder) } .mount("/", vec![Route::from(&hi_info)]) 1 2 3 4 5 6 7 8 9 10 11 12 13 .. 16

slide-65
SLIDE 65

Guards & Params

1 2 3 4 #[get("/item/<id>")] fn item(user: User, id: u32) { ... }

slide-66
SLIDE 66

1 2 3 4 #[get("/item/<id>")] fn item(user: User, id: u32) { ... } 1 2 3 4 5 6 7 8 static item_info = RouteInfo { name: "item", method: Method::Get, path: "/item/<id>", handler: item_route, format: None, rank: None, };

Guards & Params

slide-67
SLIDE 67

1 2 3 4 #[get("/item/<id>")] fn item(user: User, id: u32) { ... } fn item(user: User, id: u32)

Guards & Params

slide-68
SLIDE 68

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 fn item_route(req: &Request) -> Outcome { let id_param = match req.param_str(0).map(u32::from_param) { Some(Ok(v)) => v, _ => return Outcome::Forward }; let user_param: User = match User::from_request(req) { Outcome::Success(v) => v, Outcome::Forward(_) => return Outcome::Forward, Outcome::Failure(code) => return Outcome::Failure(code) }; let responder = item(id_param, user_param); Outcome::from(req, responder) } fn item(user: User, id: u32)

Guards & Params

slide-69
SLIDE 69

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 fn item_route(req: &Request) -> Outcome { let id_param = match req.param_str(0).map(u32::from_param) { Some(Ok(v)) => v, _ => return Outcome::Forward }; let user_param: User = match User::from_request(req) { Outcome::Success(v) => v, Outcome::Forward(_) => return Outcome::Forward, Outcome::Failure(code) => return Outcome::Failure(code) }; let responder = item(id_param, user_param); Outcome::from(req, responder) } fn item(user: User, id: u32)

Guards & Params

slide-70
SLIDE 70

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 fn item_route(req: &Request) -> Outcome { let id_param = match req.param_str(0).map(u32::from_param) { Some(Ok(v)) => v, _ => return Outcome::Forward }; let user_param: User = match User::from_request(req) { Outcome::Success(v) => v, Outcome::Forward(_) => return Outcome::Forward, Outcome::Failure(code) => return Outcome::Failure(code) }; let responder = item(id_param, user_param); Outcome::from(req, responder) } fn item(user: User, id: u32)

Guards & Params

slide-71
SLIDE 71

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 fn item_route(req: &Request) -> Outcome { let id_param = match req.param_str(0).map(u32::from_param) { Some(Ok(v)) => v, _ => return Outcome::Forward }; let user_param: User = match User::from_request(req) { Outcome::Success(v) => v, Outcome::Forward(_) => return Outcome::Forward, Outcome::Failure(code) => return Outcome::Failure(code) }; let responder = item(id_param, user_param); Outcome::from(req, responder) } fn item(user: User, id: u32)

Guards & Params

slide-72
SLIDE 72

Code Generation

1 2 3 4 #[get("/item/<id>")] fn item(user: User, id: u32) { ... }

  • Static route information from route attribute.
  • Monomorphized route handler from attribute and handler signature.
  • Tied together through mounted structure.

static item_info = RouteInfo { .. }; fn item_route(req: &Request) -> Outcome; vec![Route::from(&item_info)]

slide-73
SLIDE 73

Internals

slide-74
SLIDE 74

fn(Syntax) -> Syntax;

  • Proc. Macro API
slide-75
SLIDE 75

fn(Syntax) -> Syntax;

  • Proc. Macro API

struct Syntax(Vec<TokenTree>); struct TokenTree { node: TokenNode, span: Span }

slide-76
SLIDE 76

fn(Syntax) -> Syntax;

  • Proc. Macro API

struct Syntax(Vec<TokenTree>); struct TokenTree { node: TokenNode, span: Span }

slide-77
SLIDE 77

fn(Syntax) -> Syntax;

  • Proc. Macro API

struct Syntax(Vec<TokenTree>); struct TokenTree { node: TokenNode, span: Span }

slide-78
SLIDE 78

1

Introduction to Rocket

2 3

Code Generation in Rocket and Rust What’s Next?

What’s Coming in Future Versions of Rocket Demystifying the “Magic” of Code Generation Simple, Fast, Type-Safe Web Framework

slide-79
SLIDE 79

1

Introduction to Rocket

2 3

Code Generation in Rocket and Rust What’s Next?

What’s Coming in Future Versions of Rocket Demystifying the “Magic” of Code Generation Simple, Fast, Type-Safe Web Framework

slide-80
SLIDE 80

1

Introduction to Rocket

2 3

Code Generation in Rocket and Rust What’s Next?

What’s Coming in Future Versions of Rocket Demystifying the “Magic” of Code Generation Simple, Fast, Type-Safe Web Framework

slide-81
SLIDE 81

1 2 3 4 5 #[get("/<id>")] fn retrieve(id: PasteId) -> Option<Plain<File>>> { let filename = format!("upload/{id}", id = id); File::open(&filename).map(|f| content::Plain(f)).ok() }

Typed URIs

slide-82
SLIDE 82

1 1 1 2 3 4 5 #[get("/<id>")] fn retrieve(id: PasteId) -> Option<Plain<File>>> { let filename = format!("upload/{id}", id = id); File::open(&filename).map(|f| content::Plain(f)).ok() }

Typed URIs

url!(retrieve: id = PasteId(100)); url!(retrieve: id = 100);

slide-83
SLIDE 83

1 1 1 2 3 4 5 #[get("/<id>")] fn retrieve(id: PasteId) -> Option<Plain<File>>> { let filename = format!("upload/{id}", id = id); File::open(&filename).map(|f| content::Plain(f)).ok() }

Typed URIs

url!(retrieve: id = PasteId(100)); url!(retrieve: id = 100); "/100"

slide-84
SLIDE 84

Database Support

slide-85
SLIDE 85

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

Today

type Pool = r2d2::Pool<ConnectionManager<SqliteConnection>>; static DATABASE_URL: &'static str = env!("DATABASE_URL"); fn init_pool() -> Pool { let config = r2d2::Config::default(); let manager = ConnectionManager::<SqliteConnection>::new(DATABASE_URL); r2d2::Pool::new(config, manager).expect("db pool") } pub struct DbConn(pub r2d2::PooledConnection<ConnectionManager<SqliteConnection>>); impl<'a, 'r> FromRequest<'a, 'r> for DbConn { type Error = (); fn from_request(request: &'a Request<'r>) -> request::Outcome<DbConn, ()> { let pool = request.guard::<State<Pool>>()?; match pool.get() { Ok(conn) => Outcome::Success(DbConn(conn)), Err(_) => Outcome::Failure((Status::ServiceUnavailable, ())) } } }

slide-86
SLIDE 86

1 2 3

main.rs

1 2 3

Rocket.toml

In Rocket v0.4

[[database]] name = "my_db" adapter = "diesel_sqlite" #[derive(DbConn)] #[database("my_db")] struct DbConn(SqliteConnection);

slide-87
SLIDE 87

1

Introduction to Rocket

2 3

Code Generation in Rocket and Rust What’s Next?

What’s Coming in Future Versions of Rocket Demystifying the “Magic” of Code Generation Simple, Fast, Type-Safe Web Framework

slide-88
SLIDE 88

1

Introduction to Rocket

2 3

Code Generation in Rocket and Rust What’s Next?

What’s Coming in Future Versions of Rocket Demystifying the “Magic” of Code Generation Simple, Fast, Type-Safe Web Framework

slide-89
SLIDE 89
slide-90
SLIDE 90

myths

slide-91
SLIDE 91

Too Much “Magic”

slide-92
SLIDE 92

Too Much “Magic”

slide-93
SLIDE 93

Unstable

slide-94
SLIDE 94

Unstable

slide-95
SLIDE 95

Forever on Nightly

slide-96
SLIDE 96

Forever on Nightly

slide-97
SLIDE 97
slide-98
SLIDE 98

https://rocket.rs

guide, tutorial, docs, news, code

slide-99
SLIDE 99

Sergio Benitez

sb@sergio.bz