3

I am trying to run the examples from the book Programming Rust published by O'Reilly and I am stuck at making the following code compile successfully:

Cargo.toml

[package]
name = "gcd-online"
version = "0.1.0"
authors = ["Jignesh Gohel <abc@example.com>"]
edition = "2018"

[dependencies]
iron = "0.6.0"
mime = "0.3.12"
router = "0.6.0"
urlencoded = "0.6.0"

/src/main.rs

extern crate iron;
extern crate mime;

use iron::prelude::*;
use iron::status;

fn main() {
    println!("Serving on http://localhost:3000...");
    Iron::new(get_form).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_UTF_8);
    response.set_mut(r#"
        <title>GCD Calculator</title>
        <form action="/gcd" method="post">
            <input type="text" name="n" />
            <input type="text" name="m" />
            <button type="submit">Compute GCD</button>
        </form>
    "#);

    Ok(response)
}

Output

   Compiling gcd-online v0.1.0 (~/oreilly-programming-rust-book-examples/chapter-1/gcd-online)                                                          
error[E0277]: the trait bound `mime::Mime: iron::modifier::Modifier<iron::Response>` is not satisfied                                                                           
  --> src/main.rs:17:14                                                                                                                                                         
   |                                                                                                                                                                            
17 |     response.set_mut(mime::TEXT_HTML_UTF_8);                                                                                                                               
   |              ^^^^^^^ the trait `iron::modifier::Modifier<iron::Response>` is not implemented for `mime::Mime`

My Cargo.toml uses latest version of dependencies, however book author uses following versions

[dependencies]
iron = "0.5.1"
mime = "0.2.3"
router = "0.5.1"
urlencoded = "0.5.0"

and as part of which author used following code

#[macro_use] extern crate mime;

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

    response.set_mut(mime!(Text/Html; Charset=Utf8));

    Ok(response)
}

I think the difference in versions is what is causing the compilation error.

I tried to go through the docs of the iron and mime crates but I couldn't figure out how to get past this error.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Jignesh Gohel
  • 6,236
  • 6
  • 53
  • 89
  • An update: I switched `mime` to `0.2.3` and used the macro `mime!` as shown above under **Note** and the code compiled successfully. So I guess there is some compatibility issue between `iron 0.6.0` and `mime 0.3.12`. – Jignesh Gohel Jan 02 '19 at 14:44

1 Answers1

2

As you've noticed, newest versions of mime and iron are not compatible with the example code from the book. The issue was raised on the official book's repository.

You could use the old mime crate, but in the long run it would be best to use mime from the iron crate as explained in the docs.

For iron 0.6.0 you can replace the faulty line:

response.set_mut(mime::TEXT_HTML_UTF_8);

or

response.set_mut(mime!(Text/Html; Charset=Utf8));

with one of the following:

response.headers.set(iron::headers::ContentType("text/html; charset=utf-8".parse::<iron::mime::Mime>().unwrap()));

or

response.headers.set(iron::headers::ContentType(
    iron::mime::Mime(
        iron::mime::TopLevel::Text,
        iron::mime::SubLevel::Html,
            vec![(iron::mime::Attr::Charset, iron::mime::Value::Utf8)])
    )
);
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Leśny Rumcajs
  • 2,259
  • 2
  • 17
  • 33
  • That looks too much to set just a mime type. I hope the crate authors resolves the compatibility issue and also facilitate a concise way to do this like it is the case with older version. Thanks. – Jignesh Gohel Feb 07 '19 at 14:32
  • 1
    I'm not sure it's too much, you can even squash it to: `response.set_mut("text/html; charset=utf-8".parse::().unwrap());`. I suppose it's a matter of taste. – Leśny Rumcajs Feb 07 '19 at 14:52
  • @LeśnyRumcajs Yes, you can use it. Just verified. But you need to use `iron::mime::Mime`, if not, you get an error message **error[E0412]: cannot find type Mime in this scope**. Also whole line should be `response.set_mut("text/html; charset=utf-8".parse::().unwrap());`. – user2319066 Jan 22 '20 at 09:41