Programming Rust: Fast, Safe Systems Development

Category: Programming
Author: Jim Blandy, Jason Orendorff
4.6
This Month Hacker News 1

Comments

by quietbritishjim   2019-08-08
I know everyone says how good Rust's documentation is but I tried learning Rust with The Rust Book and found it frustrating: too long and wordy on the easy bits and without useful insight on the hard bits. I ended up buying Programming Rust by Jim Blandy [0] on a recommendation from HN comments and found it must easier to learn from. I'm already familiar with several other languages, which that book assumes, so your milage may vary.

[0] https://www.amazon.co.uk/Programming-Rust-Jim-Blandy/dp/1491...

by burtgummer45   2019-07-21

All I've got is the 3 books that I keep referring to. I think because rust is both a high level and low level language it tries to hide some things from you, but at the same time the low level leaks through. It has the most difficult 'mental model' of any language I've used. Here are the books, you probably know most of them, they are all good in different ways.

https://doc.rust-lang.org/book/

https://smile.amazon.com/Programming-Rust-Fast-Systems-Development/dp/1491927283/ref=sr_1_1?keywords=programming+rust&qid=1551578981&s=gateway&sr=8-1

https://smile.amazon.com/Beginning-Rust-Professional-Carlo-Milanesi/dp/1484234677/ref=sr_1_1?keywords=beginning+rust&qid=1551579001&s=gateway&sr=8-1

by SanlyBowitz   2019-07-21

Going through the second chapter of O'Reilly's Programming Rust. They start out by walking you through how to build a web-server with the Iron crate, but the final code doesn't compile.

Here's the final code:

extern crate iron;
#[macro_use] extern crate mime;
extern crate router;
extern crate urlencoded;

use iron::prelude::*;
use iron::status;
use router::Router;
use std::str::FromStr;
use urlencoded::UrlEncodedBody;

fn main() {
    let mut router = Router::new();

    router.get("/", get_form, "root");
    router.post("/gcd", post_gcd, "gcd");

    println!("Serving on http://localhost:3000...");
    Iron::new(router).http("localhost:3000").unwrap();
}

fn get_form(_request: &mut Request) -> IronResult<Response> {
    let mut response = Response::new();

    response.set_mut(status::Ok);
    response.set_mut(mime!(Text/Html; Charset=Utf8));
    response.set_mut(r#"
        <title>GCD Calculator</title>
        <form action = "gcd" method="post">
          <input type="text" name="n">
          <input type="text" name="n">
          <button type="submit">Compute GCD</button>
        </form>
    "#);

    Ok(response)
}

fn gcd(mut n: u64, mut m: u64) -> u64 {
    assert!(n != 0 && m != 0);
    while m != 0 {
        if m < n {
            let t = m;
            m = n;
            n = t;
        }
        m = m % n
    }
    n
}

fn post_gcd(request: &mut Request) -> IronResult<Response> {
    let mut response = Response::new();

    let form_data = match request.get_ref::<UrlEncodedBody>() {
        Err(e) => {
            response.set_mut(status::BadRequest);
            response.set_mut(format!("Error parsing form data {:?}\n", e));
            return Ok(response);
        }
        Ok(map) => map
    };

    let unparsed_numbers = match form_data.get("n") {
        None => {
            response.set_mut(status::BadRequest);
            response.set_mut(format!("form data has no 'n' parameter\n"));
            return Ok(response);
        }
        Some(nums) => nums
    };

    let mut numbers = Vec::new();
    for unparsed in unparsed_numbers {
        match u64::from_str(&unparsed) {
            Err(_) => {
                response.set_mut(status::BadRequest);
                response.set_mut(
                    format!("Value for 'n' parameter not a number: {:?}\n",
                            unparsed));
                return Ok(response);
            }
            Ok(n) => { numbers.push(n); }
        }
    }

    let mut d = numbers[0];

    for m in &numbers[1..] {
        d = gcd(d, *m);
    }

    response.set_mut(status::Ok);
    response.set_mut(mime!(Text/Html; Charset=Utf8));
    response.set_mut(format!("The greatest common divisor of the numbers {:?} is <b>{}</b>\n",
                             numbers, d));
    Ok(response)
}

...and here are the compiler errors I get:

error[E0631]: type mismatch in function arguments
  --> src/main.rs:15:12
   |
15 |     router.get("/", get_form, "root");
   |            ^^^ expected signature of `for<'r, 's, 't0> fn(&'r mut iron::request::Request<'s, 't0>) -> _`
...
22 | fn get_form(_request: &mut Request) -> IronResult<Response> {
   | ----------------------------------------------------------- found signature of `for<'r, 's, 't0> fn(&'r mut iron::Request<'s, 't0>) -> _`
   |
   = note: required because of the requirements on the impl of `iron::middleware::Handler` for `for<'r, 's, 't0> fn(&'r mut iron::Request<'s, 't0>) -> std::result::Result<iron::Response, iron::IronError> {get_form}`

error[E0631]: type mismatch in function arguments
  --> src/main.rs:16:12
   |
16 |     router.post("/gcd", post_gcd, "gcd");
   |            ^^^^ expected signature of `for<'r, 's, 't0> fn(&'r mut iron::request::Request<'s, 't0>) -> _`
...
52 | fn post_gcd(request: &mut Request) -> IronResult<Response> {
   | ---------------------------------------------------------- found signature of `for<'r, 's, 't0> fn(&'r mut iron::Request<'s, 't0>) -> _`
   |
   = note: required because of the requirements on the impl of `iron::middleware::Handler` for `for<'r, 's, 't0> fn(&'r mut iron::Request<'s, 't0>) -> std::result::Result<iron::Response, iron::IronError> {post_gcd}`

error[E0277]: expected a `std::ops::Fn<(&mut iron::Request<'_, '_>,)>` closure, found `router::Router`
  --> src/main.rs:19:5
   |
19 |     Iron::new(router).http("localhost:3000").unwrap();
   |     ^^^^^^^^^ expected an `Fn<(&mut iron::Request<'_, '_>,)>` closure, found `router::Router`
   |
   = help: the trait `for<'r, 's, 't0> std::ops::Fn<(&'r mut iron::Request<'s, 't0>,)>` is not implemented for `router::Router`
   = note: required because of the requirements on the impl of `iron::Handler` for `router::Router`
   = note: required by `<iron::Iron<H>>::new`

error[E0599]: no method named `http` found for type `iron::Iron<router::Router>` in the current scope
  --> src/main.rs:19:23
   |
19 |     Iron::new(router).http("localhost:3000").unwrap();
   |                       ^^^^
   |
   = note: the method `http` exists but the following trait bounds were not satisfied:
           `router::Router : iron::Handler`

error[E0277]: the trait bound `urlencoded::UrlEncodedBody: plugin::Plugin<iron::Request<'_, '_>>` is not satisfied
  --> src/main.rs:55:35
   |
55 |     let form_data = match request.get_ref::<UrlEncodedBody>() {
   |                                   ^^^^^^^ the trait `plugin::Plugin<iron::Request<'_, '_>>` is not implemented for `urlencoded::UrlEncodedBody`
   |
   = help: the following implementations were found:
             <urlencoded::UrlEncodedBody as plugin::Plugin<iron::request::Request<'a, 'b>>>

error: aborting due to 5 previous errors

Some errors occurred: E0277, E0599, E0631.
For more information about an error, try `rustc --explain E0277`.
error: Could not compile `iron-gcd`.

To learn more, run the command again with --verbose.

What am I doing wrong here?

by manaskarekar   2019-07-12
>the borrowing/ownership semantics of rust (at the time I looked at it) felt needlessly over complicated.

Taking a wild guess here, but it sounds like you maybe referring to issues addressed by Non-Lexical Lifetimes (NLL)?

Reference: https://www.amazon.com/Programming-Rust-Fast-Systems-Develop...

by tracker1   2019-06-03
Somewhat agreed... If I hadn't started with the O'Reily book[1], would probably order. If the eBook were half the price, would get it anyway.

Edit: looks like it's a few bucks less on Amazon

[1] https://www.amazon.com/Programming-Rust-Fast-Systems-Develop... [2] https://www.amazon.com/Rust-Programming-Language-Steve-Klabn...

by integricho   2019-04-26
Off-topic, but I'll just ask, is the book Programming Rust: Fast, Safe Systems Development 1st Edition [1] still relevant / worth reading (given the book is based on an older, although stable? version of Rust)? If it isn't, does anyone know maybe if a 2nd, updated edition can be expected?

[1] https://www.amazon.com/Programming-Rust-Fast-Systems-Develop...