rust-in-action / code Goto Github PK
View Code? Open in Web Editor NEWSource code for the book Rust in Action
Home Page: https://www.manning.com/books/rust-in-action?a_aid=rust&a_bid=0367c58f&chan=github
Source code for the book Rust in Action
Home Page: https://www.manning.com/books/rust-in-action?a_aid=rust&a_bid=0367c58f&chan=github
As a MacOS user, it would be nice to have the alternative version of the same code to inspect the virtual memory in Linux. Having a Linux example based on POSIX seems reasonable.
Personally, showing a Windows-only example felt also a bit out of context to me. Right some lines before, the book was showing a very cool picture of ELF (which AFAIK is Linux-only) and I was intrigued to learn more, then it jumps to Windows code.
I wasn't able to run the basic starting example. The shown configuration and tools are both incomplete and not updated. When trying to build using bootimage
, the command is now different (cargo bootimage
) and in particular there was an error about not being able to find the crate core
.
It's thus incomplete because cargo-xbuild
is installed but not actually used. Fortunately, I knew there was another tutorial on writing a kernel with Rust where I found the updated information: https://os.phil-opp.com/minimal-rust-kernel/
Basically, with Rust nightly 2020–07–15, we can now just simply write this in .cargo/config.toml
:
[unstable]
build-std = ["core", "compiler_builtins", "alloc"]
Also this is much better because I was also able, with the latest version which fixed a bug with the nightly toolchain, to continue using rust-analyzer in vscode. OTOH, you are left with no intellisense with cargo-xbuild
.
I hope this info will be helpful for someone, you can see the source code of the chapter with updated configuration at https://github.com/jiayihu/lab/tree/master/rust/fledge-os
code/ch2/ch2-mandelbrot/src/main.rs
Line 58 in 509fe8c
Multiple patterns overlap on their endpoints here:
code/ch2/ch2-mandelbrot/src/main.rs
Lines 55 to 62 in 7d7955e
Hi Tim,
It seems like there are two problems with the ch8-mget example, first the default version of smoltcp 0.5 no longer compiles, I updated to 0.6 and that worked. The second is the example seems to have issues with ethernet not being unicast
❯ cargo run http://www.rustinaction.com/ tap-rust -s 8.8.8.8
warning: unused manifest key: profile.release.codegen_units
warning: trait objects without an explicit `dyn` are deprecated
--> src/dns.rs:40:101
|
40 | pub fn resolve(dns_server_address: &str, domain_name: &str) -> Result<Option<std::net::IpAddr>, Box<Error>> {
|
^^^^^ help: use `dyn`: `dyn Error`
|
= note: `#[warn(bare_trait_objects)]` on by default
Finished dev [unoptimized + debuginfo] target(s) in 0.07s
Running `/home/user/build-artifacts/debug/mget 'http://www.rustinaction.com/' tap-rust -s 8.8.8.8`
thread 'main' panicked at 'Ethernet address f7-f0-a7-28-e7-57 is not unicast', /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/smoltcp-0.6.0/src/iface/ethernet.rs:705:13
This section discusses storing the index in with the data to avoid having to rebuild it on load, though it seems looking at the code the entire index is still built on every load. So it would provide no benefit I believe. (though is an interesting description of in-lining the index in with the data)
I noticed that the stack overflow check is out by one as it's comparing to len()
with >
rather than >=
. I've created a PR to illustrate the issue, although as I added to tests to show it so it's probably not suitable for that chapter of the book.
Spotted in MEAP v16.
Thanks for writing a great book :)
in ch2-mandelbrot, line 58 misses the = for the inclusive range:
11..30 => '*',
should be
11..=30 => '*',
Seems this was overseen in commit 509fe8c
I realized that you don't accept PRs so I thought opening this issue is a better way.
Take chapter5 I'm reading as example. (MEAP v15)
TBH, in Listing 5.14
, I don't know why this is the way to converto from f64
to q7:
impl From<f64> for Q7 {
fn from (n: f64) -> Self {
if n >= 1.0 {
Q7(127)
} else if n <= -1.0 {
Q7(-128)
} else {
Q7((n * 128.0) as i8) // especially here, which confused me, why can't we just use first 7bits in mantissa part of that *f64* number.
}
}
}
Until I'm reading this(full definition): https://en.wikipedia.org/wiki/Q_(number_format)
And I finally understand your code. So in this context, if there are some external reference for q7 definition, it can help me to better understand your code. And make user understand more if he/she interests on this.
running cargo +nightly run
on ch11/ch11-fledge-os-0
returns the following:
error[E0557]: feature has been removed
--> /home/username/.local/share/cargo/registry/src/github.com-1ecc6299db9ec823/x86_64-0.13.5/src/lib.rs:5:43
|
5 | #![cfg_attr(feature = "const_fn", feature(const_fn))] // Needed for generic access to associated consts
| ^^^^^^^^ feature has been removed
|
= note: split into finer-grained feature gates
For more information about this error, try `rustc --explain E0557`.
no issues opened for this in https://github.com/rust-osdev/x86_64, related rust-lang/rust#84510
any help appriciated!
I'm unable to set the time of the OS in Ubuntu 18.04. I run the following command (at the time of writing the time is 13:28):
sudo ./target/debug/clock set -s rfc3339 2020-08-13T17:14:26.604583031+02:00
I don't get any error in std error, os_error_code
is Some(0)
. If I remove the sudo I can see the permission error as expected:
Unable to set the time: Os { code: 1, kind: PermissionDenied, message: "Operation not permitted" }
What command should I use to set time OS time?
Hi
I think in line 73 the x_min parameter that is passed to the calculate_mandelbrot function should be a negative value.
For the positive 2 that's used in the book I don't get any results in the console, just spaces.
In https://github.com/rust-in-action/code/blob/1st-edition/ch9/ch9-clock3/src/main.rs#L40-L50:
impl NTPResult {
fn offset(&self) -> i64 {
let delta = self.delay();
delta.abs() / 2
}
fn delay(&self) -> i64 {
let duration = (self.t4 - self.t1) - (self.t3 - self.t2);
duration.num_milliseconds()
}
}
The definition of offset is incorrect (source on Wikipedia). Offset can be positive or negative, whereas delay is always positive. You can see that the equations above always return positive values.
Offset should let delta = (self.t2 - self.t1) - (self.t3 - self.t4);
. Currently, it rearranges to let delta = (self.t2 - self.t1) - (self.t4 - self.t3);
, i.e. the last two terms are swapped.
(I see there was an attempt to correct in #51, but as the OP later noted, the PR did not fix the issue.)
The book has been released! I need to update the code to match.
error: failed to select a version for the requirement `ring = "^0.11.0"`
candidate versions found which didn't match: 0.16.11, 0.16.10, 0.16.9, ...
location searched: crates.io index
required by package `cookie v0.9.1`
... which is depended on by `rocket v0.3.0`
... which is depended on by `ch1-time-api v0.1.0
Listing 5.3. Inspecting a float’s bit string by interpreting its bits as an integer (ch1-f32-as-u32.rs)**
Is it should be: Listing 5.3. Inspecting a float’s bit string by interpreting its bits as an integer (ch5-f32-as-u32.rs) ?
To print a value a individual bits, the type of that value must implement fmt::Display. f32 doesn’t implement fmt::Binary
Is it should be: To print a value a individual bits, the type of that value must implement fmt::Binary. f32 doesn’t implement fmt::Binary?
Listing 5.6. Impossible Addition (ch1/ch1-impossible-addition.rs)
Is it should be: Listing 5.6. Impossible Addition (ch5/ch5-impossible-addition.rs)
Addition to listing 5.6, rustc can caught such error.(I'm running rustc 1.49.0). It tells me such error message:
error: this arithmetic operation will overflow
--> src\bin\ch5-to-oblivion.rs:3:17
|
3 | let c: u8 = a + b;
| ^^^^^ attempt to compute `200_u8 + 200_u8`, which would overflow
|
= note: `#[deny(arithmetic_overflow)]` on by default
rustc is more powerful now :-)
Is it should be: Listing 5.7. Inspecting Endianness (ch5-endianness.rs)
Hope it can help... Maybe I can find something more, and I will update here :-)
Was randomly skimming on manning and I'm encountering a lot of garbage text. I'm not sure if its specific to this book or a general issue with manning. However, I randomly tried book Full Stack Python and that renders without issue.
All chapters seem to be affected. At least, Chapters 4.1, 5, 6, 7.4.1 I've directly looked at.
AFAICT:
Windows 10
Chrome Version 91.0.4472.124 (Official Build) (64-bit)
No extensions, ad blockers, etc.
Tried refreshing, killing cookies, browser, etc.
There are a couple JS errors occurring, but since they exist for both books, I don't think that's the issue.
for region in regions.iter() { // <5>
println!("{}", ®ion); // <6>
}
In this code, region
is a &&str
, so why is another &
used before region
?
Hi Tim,
in code/ch7/ch7-actionkv1/src/lib.rs line 196..=198:
let next_byte = SeekFrom::End(0);
let current_position = f.seek(SeekFrom::Current(0))?;
f.seek(next_byte)?;
current_position does not necessarily reflects the end of the file, but a new record should always go to the end.
so, shouldn't it be just simple a one line:
let current_position = f.seek(SeekFrom::End(0))?;
Thanks for clarification
Jens
Livebook has a reference The code for this listing is in ch2/ch2-needle-in-haystack.rs.
, which isn't included in the source code
After upgrading to smoltcp 0.6.0 and fixing the MAC unicast bit (#7), the mget example seems to hang in the Request
state waiting for .may_send()
to return true.
I was able to fix this by adjusting the default gateway IP. From the referenced HTTP client example in the smoltcp docs (thanks for linking to that!) it looks like the default gateway IP should match the IP assigned to the TAP device with ip addr add
.
In the book, the TAP device is given IP 192.168.42.100
(via sudo ip addr add 192.168.42.100/24 dev tap-rust
), but the default gateway IP used in the code is 192.168.20.1
(http.rs
, let default_gateway = Ipv4Address::new(192, 168, 20, 1);
).
I changed that line to let default_gateway = Ipv4Address::new(192, 168, 42, 100);
, and the example then ran correctly and I got a response from the server.
code for needle-in-haystack is missing. I wanted to double check here as the octal 0o204; doesnt match anything and prints nothing to the console.
The source code for listing 7.14 seems to be missing from the 1st-edition branch
I've seen a couple other issues for this section in particular, but I tried compiling the code from the repo as is and I got the following error:
➜ ch2-mandelbrot git:(1st-edition) ✗ cargo run
Compiling autocfg v1.0.0
Compiling num-traits v0.2.12
Compiling num-integer v0.1.43
Compiling num-bigint v0.3.0
Compiling num-rational v0.3.0
Compiling num-iter v0.1.41
Compiling num-complex v0.3.0
Compiling num v0.3.0
Compiling ch2-mandelbrot v0.1.0 (/Users/ethanarrowood/Documents/Programming/rust/rust-in-action/code/ch2/ch2-mandelbrot)
error[E0658]: exclusive range pattern syntax is experimental
--> src/main.rs:55:9
|
55 | 0..2 => ' ',
| ^^^^
|
= note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
error[E0658]: exclusive range pattern syntax is experimental
--> src/main.rs:56:9
|
56 | 2..5 => '.',
| ^^^^
|
= note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
error[E0658]: exclusive range pattern syntax is experimental
--> src/main.rs:57:9
|
57 | 5..10 => '•',
| ^^^^^
|
= note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
error[E0658]: exclusive range pattern syntax is experimental
--> src/main.rs:58:9
|
58 | 11..30 => '*',
| ^^^^^^
|
= note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
error[E0658]: exclusive range pattern syntax is experimental
--> src/main.rs:59:9
|
59 | 30..100 => '+',
| ^^^^^^^
|
= note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
error[E0658]: exclusive range pattern syntax is experimental
--> src/main.rs:60:9
|
60 | 100..200 => 'x',
| ^^^^^^^^
|
= note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
error[E0658]: exclusive range pattern syntax is experimental
--> src/main.rs:61:9
|
61 | 200..400 => '$',
| ^^^^^^^^
|
= note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
warning: unnecessary parentheses around assigned value
--> src/main.rs:20:23
|
20 | let x_percent = (img_x as f64 / width as f64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove these parentheses
|
= note: `#[warn(unused_parens)]` on by default
warning: unnecessary parentheses around assigned value
--> src/main.rs:21:23
|
21 | let y_percent = (img_y as f64 / height as f64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove these parentheses
error: aborting due to 7 previous errors; 2 warnings emitted
For more information about this error, try `rustc --explain E0658`.
error: could not compile `ch2-mandelbrot`
To learn more, run the command again with --verbose.
I also ran rustup update stable
earlier; do I need to be on a different rust version to run this one? From the referenced github issue it states I should add #![feature(exclusive_range_pattern)]
to the top of the file and install the nightly build of rust to run it.
Hello buddy!
Great book! Found a trivial discrepancy in Listing 2.21
The result in the LiveBook is shown as:
[1, 2, 3]: 1 + 10 = 11 2 + 10 = 12 3 + 10 = 13 (Σ[1, 2, 3] = 6)
[1, 2, 3]: 1 + 10 = 11 2 + 10 = 12 3 + 10 = 13 (Σ[1, 2, 3] = 6)
[0, 0, 0]: 0 + 10 = 10 0 + 10 = 10 0 + 10 = 10 (Σ[0, 0, 0] = 0)
[0, 0, 0]: 0 + 10 = 10 0 + 10 = 10 0 + 10 = 10 (Σ[0, 0, 0] = 0)
The sum bit has the sum symbol Σ
but the code doesn't have it.
The code as is is missing the Σ
symbol:
fn main() {
let one = [1, 2, 3];
let two: [u8; 3] = [1, 2, 3];
let blank1 = [0; 3];
let blank2: [u8; 3] = [0; 3];
let arrays = [one, two, blank1, blank2];
for a in &arrays {
print!("{:?}: ", a);
for n in a.iter() {
print!("\t{} + 10 = {}", n, n+10);
}
let mut sum = 0;
for i in 0..a.len() {
sum += a[i];
}
println!("\t({:?} = {})", a, sum);
}
}
Line 19 should be:
print!("\tΣ{} + 10 = {}", n, n+10);
The code seems to use pre rust-2018 conventions. For example in the first chapter the code:
extern crate serde_derive; // <3>
...
#[derive(Serialize)] // <6> Automatically generate a string representation of this struct (which will be used as JSON)
struct Timestamp { // <7> Syntax to create a custom type
Can be re-written as
use serde::Serialize;
...
#[derive(Serialize)] // <6> Automatically generate a string representation of this struct (which will be used as JSON)
struct Timestamp { // <7> Syntax to create a custom type
code/ch2/ch2-mandelbrot/src/main.rs
Lines 73 to 74 in 7d7955e
This should be calculate_mandelbrot(1000, -2.0, 1.0, -1.0, 1.0, 80, 24)
as mentioned in https://www.reddit.com/r/rust/comments/o980ip/rust_in_action_is_released/h3aktuf
Working with actionkv2 a bit and it looks like the "delete" keyword is broken for the disk version.
.\akv_disk.exe test_disk insert MN StPaul
.\akv_disk.exe test_disk insert PA Harrisburgh
.\akv_disk.exe test_disk get MN
OUTPUT: [83, 116, 80, 97, 117, 108]
.\akv_disk.exe test_disk delete MN
.\akv_disk.exe test_disk get MN
OUTPUT: [83, 116, 80, 97, 117, 108]
I think it's just adding the store_on_disk after updating the in memory kv. I made the change locally and it seems to be working.
"delete" => {
a.delete(key).unwrap();
store_index_on_disk(&mut a, INDEX_KEY);
}
As can be seen here, the extra closing brace prevents compilation.
Removing the brace solves the issue.
Chapter 5.5.5 CPU 4: Adding the rest
briefly talks about a cpu4.
However, the code for cpu4 is missing.
With a few extra opcodes, it’s possible to implement multiplication and many more functions within your
inchoate CPU. Check the source code that comes along with the book (specifically the directory ch5/ch5-cpu4) for a mostly-complete fuller implementation of the CHIP-8 specification.
At the beginning of the section 8.4 (TCP), we can see some code listings from ch8/ch8-stdlib but i can't find the code into this repository.
Note that the snippet for ch5/ch5-visualizing-f32.rs
is missing the mantissa
variable. This can be easily fixed by adding this before the for loop in decode
. He does mention this in the book but the listing seems to be missing it.
let mut mantissa: f32 = 1.0;
code/ch5/ch5-visualizing-f32.rs
Lines 28 to 49 in 7d7955e
The text reads:
Listing 2.2 prints a + b = 30 to the console
However, the code says: println!("( a + b ) + ( c + d ) = {}", e);
So it should say:
Listing 2.2 prints ( a + b ) + ( c + d ) = 90 to the console
In listing 2.12 Rendering the Mandlebrot set,
code/ch2/ch2-mandelbrot/src/main.rs
Line 14 in 39e24d7
hint number (6) says create rows with_capacity(width)
. Shouldn't that be ideally with_capacity(height)
since we want to create height
number of rows and passing height
is much better?
Also few line below:
code/ch2/ch2-mandelbrot/src/main.rs
Line 17 in 39e24d7
let mut row: Vec<usize> =
should also have Vec::with_capacity(width)
instead of Vec::with_capacity(height)
Section 7.7.11 points out a problem of actionkv v1 is that it has long start up time and describes a way to shorten it by storing the index itself on the database. But actionkv v2 still reads all of the database file and rebuilds the index. Thus the problem of actionkv v1 is not resolved. Considring the discussion of this section, I think it should be resolved.
In Listing 3.15,
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
FileState::Open => write!(f, "OPEN"), // <4>
FileState::Closed => write!(f, "CLOSED"), // <4>
}
In fact, a &
is not necessary, and using match self
directly would be more easily understood.
Hi Tim!
Rust in Action recently went from MEAP to final release, but I've noticed that this repository doesn't always match the code examples mentioned in the book.
E.g., in §2.1.1 Compiling single files with rustc it says:
You’ll find the source code for listing 2.1 in the file ch2/ok.rs
But the file ch2/ok.rs
is only found in the code downloaded from Manning, not in this repo (see PR #34).
The Zip code from Manning is from MEAP 12 of the book. So I was wondering:
Hi, thanks for the book and the much helping source code.
I think I found a problem here:
code/ch9/ch9-clock3/src/main.rs
Lines 41 to 44 in cff02d5
let offset = (self.t2 - self.t1) + (self.t3 - self.t4);
Both this code and the book wording threw me off balance enough to check the wikipedia article, as your code doesn't have any difference between delta and theta, except for the 2 factor. their fixed definitions makes much more sense.
The code @ Animals specialization is not compiling
or is it a codeexample the shows what does not work
Sorry newb here, google brought me here when i was searching for specialization/generics.
Regards Remco
#[allow(arithmetic_overflow)] <1>
fn main() {
let (a, b) = (200, 200);
let c: u8 = a + b; <2>
println!("200 + 200 = {}", c);
}
In this source code, there are two marks <1>/<2>
the author might forget to comment, making the rustc reject to compile it
At line 46 of Listing 2.22,
for &(i, ref line) in local_ctx.iter()
I think introducing ref
here would pose a burden for understanding. A better and simpler way:
for (i, line) in local_ctx.iter()
Both ways are to borrow
, not move
.
The source code of this example uses [email protected]
to send HTTP requests, perhaps this is for the reason that the newer version of reqwest
switches to async mode on the top of tokio
.
If you wanna use the newer version of reqwest
and still send sync requests, use the code snippet below:
// main.rs
use std::error::Error;
use reqwest;
fn main() -> Result<(), Box<dyn Error>> {
let url = "http://www.rustinaction.com/";
let mut response = reqwest::blocking::get(url)?; // use reqwest::blocking::get() to send sync request
let content = response.text()?;
print!("{}", content);
Ok(())
}
// Cargo.toml
...
[dependencies]
reqwest = { version="0.11.8", features = ["blocking"] } // ! enable the blocking feature
BTW, here is the link to reqwest::blocking.
:)
all_rows
doesn't exist in this scope:
code/ch2/ch2-mandelbrot/src/main.rs
Line 28 in 7d7955e
I am new to Rust but when I run the chapter 2-complex example codes, then there is an error like below.
error[E0658]: use of unstable library feature 'dec2flt': internal routines only exposed for testing
--> src/main.rs:1:5
|
1 | use core::num::dec2flt::number;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
Rust & Cargo version
I try to build mget
on rust v1.60 on mac and the build fails because of:
➜ ch8-mget git:(1st-edition) ✗ cargo build
Compiling mget v0.1.0 (/Users/adria/Programming/rust-in-action/ch8/ch8-mget)
error[E0432]: unresolved import `smoltcp::phy::TapInterface`
--> src/main.rs:2:5
|
2 | use smoltcp::phy::TapInterface;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TapInterface` in `phy`
error[E0432]: unresolved import `smoltcp::phy::TapInterface`
--> src/http.rs:7:38
|
7 | use smoltcp::phy::{wait as phy_wait, TapInterface};
| ^^^^^^^^^^^^ no `TapInterface` in `phy`
I also had to modify Cargo.toml
because curly bracket content cannot be separated over several lines.
In my IDE, I can however see that TapInterface
exists.
Any idea?
The ch12/noop
from section 12.7 doesn't exists
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.