const fs = require('fs') const test = require('ava') const {execFilePromise, matchOutput, reorderings} = require('./util') process.chdir(__dirname) const RUST_MUTABLE_EXPECTED = [ [ 'files/rust-book/ch10-03-lifetime-syntax.md:reference to an `i32` that has a lifetime parameter named `\'a`, and a mutable', 'files/rust-book/ch10-03-lifetime-syntax.md:&\'a mut i32 // a mutable reference with an explicit lifetime' ], ['files/rust-book/ch15-00-smart-pointers.md:In addition, we’ll cover the *interior mutability* pattern where an immutable'], ['files/rust-book/ch15-03-drop.md:`drop` that takes a mutable reference to `self`. To see when Rust calls `drop`,'], [ 'files/rust-book/ch04-01-what-is-ownership.md:immutable. Another is that not every string value can be known when we write', 'files/rust-book/ch04-01-what-is-ownership.md:With the `String` type, in order to support a mutable, growable piece of text,' ], [ 'files/rust-book/ch15-04-rc.md:Via immutable references, `Rc` allows you to share data between multiple', 'files/rust-book/ch15-04-rc.md:mutable references too, you might violate one of the borrowing rules discussed', 'files/rust-book/ch15-04-rc.md:in Chapter 4: multiple mutable borrows to the same place can cause data races' ], [ 'files/rust-book/ch20-03-graceful-shutdown-and-cleanup.md:this because `self` is a mutable reference, and we also need to be able to', 'files/rust-book/ch20-03-graceful-shutdown-and-cleanup.md:The error tells us we can’t call `join` because we only have a mutable borrow' ], ['files/rust-book/ch13-01-closures.md:captured variables also implement `FnMut`, and closures that don’t need mutable'], ['files/rust-book/ch20-01-single-threaded.md:In the `handle_connection` function, we’ve made the `stream` parameter mutable.'], ['files/rust-book/ch08-02-strings.md:coded into the core language, is a growable, mutable, owned, UTF-8 encoded'], [ 'files/rust-book/ch08-01-vectors.md:make it mutable using the `mut` keyword, as discussed in Chapter 3. The numbers', 'files/rust-book/ch08-01-vectors.md:rule that states you can’t have mutable and immutable references in the same', 'files/rust-book/ch08-01-vectors.md:scope. That rule applies in Listing 8-7, where we hold an immutable reference to', 'files/rust-book/ch08-01-vectors.md:8-8 shows how to use a `for` loop to get immutable references to each element', 'files/rust-book/ch08-01-vectors.md:We can also iterate over mutable references to each element in a mutable vector', 'files/rust-book/ch08-01-vectors.md:Listing 8-9: Iterating over mutable references to', 'files/rust-book/ch08-01-vectors.md:To change the value that the mutable reference refers to, we have to use the' ], [ 'files/rust-book/ch15-02-deref.md:immutable references, you can use the `DerefMut` trait to override the `*`', 'files/rust-book/ch15-02-deref.md:operator on mutable references.', 'files/rust-book/ch15-02-deref.md:happens for mutable references.', 'files/rust-book/ch15-02-deref.md:The third case is trickier: Rust will also coerce a mutable reference to an', 'files/rust-book/ch15-02-deref.md:immutable one. But the reverse is *not* possible: immutable references will', 'files/rust-book/ch15-02-deref.md:never coerce to mutable references. Because of the borrowing rules, if you have', 'files/rust-book/ch15-02-deref.md:a mutable reference, that mutable reference must be the only reference to that', 'files/rust-book/ch15-02-deref.md:data (otherwise, the program wouldn’t compile). Converting one mutable', 'files/rust-book/ch15-02-deref.md:reference to one immutable reference will never break the borrowing rules.', 'files/rust-book/ch15-02-deref.md:Converting an immutable reference to a mutable reference would require that the', 'files/rust-book/ch15-02-deref.md:initial immutable reference is the only immutable reference to that data, but', 'files/rust-book/ch15-02-deref.md:assumption that converting an immutable reference to a mutable reference is' ], [ 'files/rust-book/ch17-03-oo-design-patterns.md:The `add_text` method takes a mutable reference to `self`, because we’re', 'files/rust-book/ch17-03-oo-design-patterns.md:We give `Post` a public method named `request_review` that will take a mutable' ], [ 'files/rust-book/ch15-05-interior-mutability.md:data even when there are immutable references to that data; normally, this', 'files/rust-book/ch15-05-interior-mutability.md:safe API, and the outer type is still immutable.', 'files/rust-book/ch15-05-interior-mutability.md:* At any given time, you can have *either* (but not both of) one mutable', 'files/rust-book/ch15-05-interior-mutability.md: reference or any number of immutable references.', 'files/rust-book/ch15-05-interior-mutability.md:* `Box` allows immutable or mutable borrows checked at compile time; `Rc`', 'files/rust-book/ch15-05-interior-mutability.md: allows only immutable borrows checked at compile time; `RefCell` allows', 'files/rust-book/ch15-05-interior-mutability.md: immutable or mutable borrows checked at runtime.', 'files/rust-book/ch15-05-interior-mutability.md:* Because `RefCell` allows mutable borrows checked at runtime, you can', 'files/rust-book/ch15-05-interior-mutability.md: immutable.', 'files/rust-book/ch15-05-interior-mutability.md:Mutating the value inside an immutable value is the *interior mutability*', 'files/rust-book/ch15-05-interior-mutability.md:### Interior Mutability: A Mutable Borrow to an Immutable Value', 'files/rust-book/ch15-05-interior-mutability.md:A consequence of the borrowing rules is that when you have an immutable value,', 'files/rust-book/ch15-05-interior-mutability.md:{{#rustdoc_include ../listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/src/main.rs}}', 'files/rust-book/ch15-05-interior-mutability.md:{{#include ../listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/output.txt}}', 'files/rust-book/ch15-05-interior-mutability.md:itself in its methods but appear immutable to other code. Code outside the', 'files/rust-book/ch15-05-interior-mutability.md:an immutable value and see why that is useful.', 'files/rust-book/ch15-05-interior-mutability.md:called `send` that takes an immutable reference to `self` and the text of the', 'files/rust-book/ch15-05-interior-mutability.md:`send` method takes an immutable reference to `self`. We also can’t take the', 'files/rust-book/ch15-05-interior-mutability.md:value while the outer value is considered immutable', 'files/rust-book/ch15-05-interior-mutability.md:immutable borrow of `self`, which matches the trait definition. We call', 'files/rust-book/ch15-05-interior-mutability.md:mutable reference to the value inside the `RefCell>`, which is', 'files/rust-book/ch15-05-interior-mutability.md:the vector. Then we can call `push` on the mutable reference to the vector to', 'files/rust-book/ch15-05-interior-mutability.md:immutable reference to the vector.', 'files/rust-book/ch15-05-interior-mutability.md:When creating immutable and mutable references, we use the `&` and `&mut`', 'files/rust-book/ch15-05-interior-mutability.md:increases its count of how many immutable borrows are active. When a `Ref`', 'files/rust-book/ch15-05-interior-mutability.md:value goes out of scope, the count of immutable borrows goes down by one. Just', 'files/rust-book/ch15-05-interior-mutability.md:like the compile-time borrowing rules, `RefCell` lets us have many immutable', 'files/rust-book/ch15-05-interior-mutability.md:borrows or one mutable borrow at any point in time.', 'files/rust-book/ch15-05-interior-mutability.md:Listing 15-22. We’re deliberately trying to create two mutable borrows active', 'files/rust-book/ch15-05-interior-mutability.md:Listing 15-23: Creating two mutable references in the', 'files/rust-book/ch15-05-interior-mutability.md:from `borrow_mut`. Then we create another mutable borrow in the same way in the', 'files/rust-book/ch15-05-interior-mutability.md:variable `two_borrow`. This makes two mutable references in the same scope,', 'files/rust-book/ch15-05-interior-mutability.md:messages it has seen while you’re using it in a context where only immutable', 'files/rust-book/ch15-05-interior-mutability.md:`Rc` lets you have multiple owners of some data, but it only gives immutable', 'files/rust-book/ch15-05-interior-mutability.md:`Rc` holds only immutable values, we can’t change any of the values in the', 'files/rust-book/ch15-05-interior-mutability.md:immutable `List` value. But we can use the methods on `RefCell` that provide' ], [ 'files/rust-book/ch13-02-iterators.md:Note that we needed to make `v1_iter` mutable: calling the `next` method on an', 'files/rust-book/ch13-02-iterators.md:to make `v1_iter` mutable when we used a `for` loop because the loop took', 'files/rust-book/ch13-02-iterators.md:ownership of `v1_iter` and made it mutable behind the scenes.', 'files/rust-book/ch13-02-iterators.md:Also note that the values we get from the calls to `next` are immutable', 'files/rust-book/ch13-02-iterators.md:over immutable references. If we want to create an iterator that takes', 'files/rust-book/ch13-02-iterators.md:`iter`. Similarly, if we want to iterate over mutable references, we can call' ], [ 'files/rust-book/ch03-01-variables-and-mutability.md:As mentioned in Chapter 2, by default variables are immutable. This is one of', 'files/rust-book/ch03-01-variables-and-mutability.md:option to make your variables mutable. Let’s explore how and why Rust', 'files/rust-book/ch03-01-variables-and-mutability.md:When a variable is immutable, once a value is bound to a name, you can’t change', 'files/rust-book/ch03-01-variables-and-mutability.md:{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/src/main.rs}}', 'files/rust-book/ch03-01-variables-and-mutability.md:{{#include ../listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/output.txt}}', 'files/rust-book/ch03-01-variables-and-mutability.md:assign twice to immutable variable x`, because you tried to assign a second', 'files/rust-book/ch03-01-variables-and-mutability.md:value to the immutable `x` variable.', 'files/rust-book/ch03-01-variables-and-mutability.md:value that we previously designated as immutable because this very situation', 'files/rust-book/ch03-01-variables-and-mutability.md:But mutability can be very useful. Variables are immutable only by default; as', 'files/rust-book/ch03-01-variables-and-mutability.md:you did in Chapter 2, you can make them mutable by adding `mut` in front of the', 'files/rust-book/ch03-01-variables-and-mutability.md:is used. In some cases, you’ll want to make a variable mutable because it makes', 'files/rust-book/ch03-01-variables-and-mutability.md:the code more convenient to write than if it had only immutable variables.', 'files/rust-book/ch03-01-variables-and-mutability.md:immutable variables, constants are values that are bound to a name and are not', 'files/rust-book/ch03-01-variables-and-mutability.md:immutable by default—they’re always immutable.', 'files/rust-book/ch03-01-variables-and-mutability.md:on a value but have the variable be immutable after those transformations have' ], [ 'files/rust-book/ch08-03-hash-maps.md:The `or_insert` method on `Entry` is defined to return a mutable reference to', 'files/rust-book/ch08-03-hash-maps.md:inserts the parameter as the new value for this key and returns a mutable', 'files/rust-book/ch08-03-hash-maps.md:`or_insert` method actually returns a mutable reference (`&mut V`) to the value', 'files/rust-book/ch08-03-hash-maps.md:for this key. Here we store that mutable reference in the `count` variable, so', 'files/rust-book/ch08-03-hash-maps.md:asterisk (`*`). The mutable reference goes out of scope at the end of the `for`' ], [ 'files/rust-book/ch04-02-references-and-borrowing.md:Just as variables are immutable by default, so are references. We’re not', 'files/rust-book/ch04-02-references-and-borrowing.md:First, we had to change `s` to be `mut`. Then we had to create a mutable', 'files/rust-book/ch04-02-references-and-borrowing.md:reference with `&mut s` and accept a mutable reference with `some_string: &mut', 'files/rust-book/ch04-02-references-and-borrowing.md:But mutable references have one big restriction: you can have only one mutable', 'files/rust-book/ch04-02-references-and-borrowing.md:multiple mutable references, just not *simultaneous* ones:', 'files/rust-book/ch04-02-references-and-borrowing.md:A similar rule exists for combining mutable and immutable references. This code', 'files/rust-book/ch04-02-references-and-borrowing.md:{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/src/main.rs:here}}', 'files/rust-book/ch04-02-references-and-borrowing.md:{{#include ../listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/output.txt}}', 'files/rust-book/ch04-02-references-and-borrowing.md:Whew! We *also* cannot have a mutable reference while we have an immutable one.', 'files/rust-book/ch04-02-references-and-borrowing.md:Users of an immutable reference don’t expect the values to suddenly change out', 'files/rust-book/ch04-02-references-and-borrowing.md:from under them! However, multiple immutable references are okay because no one', 'files/rust-book/ch04-02-references-and-borrowing.md:compile because the last usage of the immutable references occurs before the', 'files/rust-book/ch04-02-references-and-borrowing.md:mutable reference is introduced:', 'files/rust-book/ch04-02-references-and-borrowing.md:The scopes of the immutable references `r1` and `r2` end after the `println!`', 'files/rust-book/ch04-02-references-and-borrowing.md:where they are last used, which is before the mutable reference `r3` is', 'files/rust-book/ch04-02-references-and-borrowing.md:* At any given time, you can have *either* one mutable reference *or* any', 'files/rust-book/ch04-02-references-and-borrowing.md: number of immutable references.' ], ['files/rust-book/ch05-02-example-structs.md:`rectangle`, whose type is an immutable borrow of a struct `Rectangle`'], [ 'files/rust-book/ch19-01-unsafe-rust.md:* Access or modify a mutable static variable', 'files/rust-book/ch19-01-unsafe-rust.md:references. As with references, raw pointers can be immutable or mutable and', 'files/rust-book/ch19-01-unsafe-rust.md:pointers, *immutable* means that the pointer can’t be directly assigned to', 'files/rust-book/ch19-01-unsafe-rust.md:* Are allowed to ignore the borrowing rules by having both immutable and', 'files/rust-book/ch19-01-unsafe-rust.md: mutable pointers or multiple mutable pointers to the same location', 'files/rust-book/ch19-01-unsafe-rust.md:Listing 19-1 shows how to create an immutable and a mutable raw pointer from', 'files/rust-book/ch19-01-unsafe-rust.md:We’ve created raw pointers by using `as` to cast an immutable and a mutable', 'files/rust-book/ch19-01-unsafe-rust.md:stored. If we instead tried to create an immutable and a mutable reference to', 'files/rust-book/ch19-01-unsafe-rust.md:allow a mutable reference at the same time as any immutable references. With', 'files/rust-book/ch19-01-unsafe-rust.md:raw pointers, we can create a mutable pointer and an immutable pointer to the', 'files/rust-book/ch19-01-unsafe-rust.md:same location and change data through the mutable pointer, potentially creating', 'files/rust-book/ch19-01-unsafe-rust.md:might implement it. This safe method is defined on mutable slices: it takes one', 'files/rust-book/ch19-01-unsafe-rust.md:Then we return two mutable slices in a tuple: one from the start of the', 'files/rust-book/ch19-01-unsafe-rust.md:mutable slice to `i32` values, `as_mut_ptr` returns a raw pointer with the type', 'files/rust-book/ch19-01-unsafe-rust.md:accessing the same mutable global variable, it can cause a data race.', 'files/rust-book/ch19-01-unsafe-rust.md:Listing 19-9: Defining and using an immutable static', 'files/rust-book/ch19-01-unsafe-rust.md:immutable static variable is safe.', 'files/rust-book/ch19-01-unsafe-rust.md:Constants and immutable static variables might seem similar, but a subtle', 'files/rust-book/ch19-01-unsafe-rust.md:variables can be mutable. Accessing and modifying mutable static variables is', 'files/rust-book/ch19-01-unsafe-rust.md:*unsafe*. Listing 19-10 shows how to declare, access, and modify a mutable', 'files/rust-book/ch19-01-unsafe-rust.md:Listing 19-10: Reading from or writing to a mutable', 'files/rust-book/ch19-01-unsafe-rust.md:With mutable data that is globally accessible, it’s difficult to ensure there', 'files/rust-book/ch19-01-unsafe-rust.md:are no data races, which is why Rust considers mutable static variables to be' ], ['files/rust-book/ch15-06-reference-cycles.md:mutability gives us a type that we can use when we need an immutable type but'], [ 'files/rust-book/ch05-01-defining-structs.md:to use this value. If the instance is mutable, we can change a value by using', 'files/rust-book/ch05-01-defining-structs.md:to change the value in the `email` field of a mutable `User` instance.', 'files/rust-book/ch05-01-defining-structs.md:Note that the entire instance must be mutable; Rust doesn’t allow us to mark', 'files/rust-book/ch05-01-defining-structs.md:only certain fields as mutable. As with any expression, we can construct a new' ], ['files/rust-book/ch12-04-testing-the-librarys-functionality.md:we can make a mutable vector before the `for` loop and call the `push` method'], [ 'files/rust-book/ch13-03-improving-our-io-project.md:keyword into the specification of the `args` parameter to make it mutable.', 'files/rust-book/ch13-03-improving-our-io-project.md:Doing so also lets us avoid having a mutable intermediate `results` vector. The', 'files/rust-book/ch13-03-improving-our-io-project.md:functional programming style prefers to minimize the amount of mutable state to', 'files/rust-book/ch13-03-improving-our-io-project.md:make code clearer. Removing the mutable state might enable a future enhancement' ], [ 'files/rust-book/ch05-03-method-syntax.md:block. The method name will be `can_hold`, and it will take an immutable borrow', 'files/rust-book/ch05-03-method-syntax.md:`rect1.can_hold(&rect2)` passes in `&rect2`, which is an immutable borrow to', 'files/rust-book/ch05-03-method-syntax.md:read `rect2` (rather than write, which would mean we’d need a mutable borrow),' ], [ 'files/rust-book/ch02-00-guessing-game-tutorial.md:`bar` variable. In Rust, variables are immutable by default. We’ll be', 'files/rust-book/ch02-00-guessing-game-tutorial.md:a variable mutable:', 'files/rust-book/ch02-00-guessing-game-tutorial.md:let foo = 5; // immutable', 'files/rust-book/ch02-00-guessing-game-tutorial.md:let mut bar = 5; // mutable', 'files/rust-book/ch02-00-guessing-game-tutorial.md:will introduce a mutable variable named `guess`. On the other side of the equal', 'files/rust-book/ch02-00-guessing-game-tutorial.md:To summarize, the `let mut guess = String::new();` line has created a mutable', 'files/rust-book/ch02-00-guessing-game-tutorial.md:string argument needs to be mutable so the method can change the string’s', 'files/rust-book/ch02-00-guessing-game-tutorial.md:immutable by default. Hence, you need to write `&mut guess` rather than', 'files/rust-book/ch02-00-guessing-game-tutorial.md:`&guess` to make it mutable. (Chapter 4 will explain references more' ], [ 'files/rust-book/ch04-03-slices.md:Recall from the borrowing rules that if we have an immutable reference to', 'files/rust-book/ch04-03-slices.md:something, we cannot also take a mutable reference. Because `clear` needs to', 'files/rust-book/ch04-03-slices.md:truncate the `String`, it needs to get a mutable reference. Rust disallows', 'files/rust-book/ch04-03-slices.md:the binary. This is also why string literals are immutable; `&str` is an', 'files/rust-book/ch04-03-slices.md:immutable reference.' ], [ 'files/rust-book/ch16-03-shared-state.md:this case, as a mutable reference to the data inside. The type system ensures', 'files/rust-book/ch16-03-shared-state.md:You might have noticed that `counter` is immutable but we could get a mutable' ] ] const MULTIPLE_RUST_FILES = [ 'files/rust-book/ch04-01-what-is-ownership.md', 'files/rust-book/ch08-03-hash-maps.md', 'files/rust-book/ch17-00-oop.md', 'files/rust-book/ch19-01-unsafe-rust.md', 'files/rust-book/ch19-06-macros.md' ] const TESTS = [ { // The example from the spec args: ['ss', 'files/independence.txt'], expected: [[ 'it becomes necessary for one people', 'to dissolve the political bands', 'and to assume among the powers of the earth,' ]] }, { // Test that the pattern is treated as a regular expression. // This example is from the spec. args: ['the[a-z]', 'files/independence.txt'], expected: [[ 'which have connected them with another,', 'the Laws of Nature and of Nature\'s God entitle them,', 'that they should declare the causes', 'which impel them to the separation.' ]] }, { // Test on a larger file with multiple occurrences in some lines args: ['lock', 'files/rust-book/ch20-02-multithreaded.md'], expected: [[ '`else if` after the `if` block to check for the request to */sleep*. When that', 'Here, we first call `lock` on the `receiver` to acquire the mutex, and then we', 'call `unwrap` to panic on any errors. Acquiring a lock might fail if the mutex', 'holding the lock rather than releasing the lock. In this situation, calling', 'If we get the lock on the mutex, we call `recv` to receive a `Job` from the', 'The call to `recv` blocks, so if there is no job yet, the current thread will', '`unlock` method because the ownership of the lock is based on the lifetime of', 'the `MutexGuard` within the `LockResult>` that the `lock`', 'lock. But this implementation can also result in the lock being held longer', 'scope for the duration of the block, the lock remains held for the duration of', 'By using `loop` instead and acquiring the lock without assigning to a variable,', 'the temporary `MutexGuard` returned from the `lock` method is dropped as soon', 'as the `let job` statement ends. This ensures that the lock is held during the' ]] }, { // Test multiple input files args: ['mutable', ...MULTIPLE_RUST_FILES], expected: RUST_MUTABLE_EXPECTED.filter(([firstLine]) => MULTIPLE_RUST_FILES.some(file => firstLine.startsWith(file)) ) }, { // Test -v flag args: ['-v', 'ss', 'files/independence.txt'], expected: [[ 'When in the Course of human events,', 'which have connected them with another,', 'the separate and equal station to which', 'the Laws of Nature and of Nature\'s God entitle them,', 'a decent respect to the opinions of mankind requires', 'that they should declare the causes', 'which impel them to the separation.' ]] }, { // Test -i flag args: ['-i', 'ZoUnDs', 'files/richard-iii/1/2.txt'], expected: [[ 'Zounds , he dies ! I had forgot the reward .', 'Zounds , ’tis even now at my elbow , persuading me not to kill the Duke .' ]] }, { // Test -r flag args: ['-r', 'mutable', 'files/rust-book'], expected: RUST_MUTABLE_EXPECTED }, { // Test -r with omitted directory. // This also tests a more deeply-nested recursive structure. args: ['-r', 'crow' + 'n'], expected: [ [ 'files/richard-iii/1/1/3/2.txt:To fight on Edward’s party for the crow' + 'n ;', 'files/richard-iii/1/1/3/2.txt:When thou didst crow' + 'n his warlike brows with paper ,' ], [ 'files/richard-iii/2.txt:Let him be crow' + 'ned . In him your comfort lives .', 'files/richard-iii/2.txt:Hither to London , to be crow' + 'ned our king .', 'files/richard-iii/2.txt:Was crow' + 'ned in Paris but at nine months old .' ], ['files/richard-iii/3/1/1/3.txt:I mean your voice for crow' + 'ning of the King .'], [ 'files/richard-iii/3/1/1/2.txt:How “ wear the garland ” ? Dost thou mean the crow' + 'n ?', 'files/richard-iii/3/1/1/2.txt:I’ll have this crow' + 'n of mine cut from my shoulders', 'files/richard-iii/3/1/1/2.txt:Before I’ll see the crow' + 'n so foul misplaced .' ], ['files/richard-iii/3/1/1/1.txt:My husband lost his life to get the crow' + 'n ,'], [ 'files/richard-iii/3/1/3/2.txt:Now by my George , my Garter , and my crow' + 'n —', 'files/richard-iii/3/1/3/2.txt:Thy crow' + 'n , usurped , disgraced his kingly glory .', 'files/richard-iii/3/1/3/2.txt:He makes for England , here to claim the crow' + 'n .' ], [ 'files/richard-iii/3/1/2/1/3.txt:Tomorrow may it please you to be crow' + 'ned ?', 'files/richard-iii/3/1/2/1/3.txt:There to be crow' + 'nèd Richard’s royal queen .' ], ['files/richard-iii/3/1/2/1/2.txt:And that my path were even to the crow' + 'n'], [ 'files/richard-iii/3/1/2/3.txt:For queen , a very caitiff crow' + 'ned with care ;', 'files/richard-iii/3/1/2/3.txt:Hid’st thou that forehead with a golden crow' + 'n', 'files/richard-iii/3/1/2/3.txt:The slaughter of the prince that owed that crow' + 'n' ], ['files/richard-iii/3/1/2/2.txt:And by that knot looks proudly on the crow' + 'n ,'], ['files/richard-iii/3/2.txt:The first was I that helped thee to the crow' + 'n ;'] ] }, { // Test a more complicated regex args: ['-r', '[a-z]{3}\\d', 'files/rust-book'], expected: [ [ 'files/rust-book/ch10-03-lifetime-syntax.md:type stored in the variable `string1`) as well as string literals (which is', 'files/rust-book/ch10-03-lifetime-syntax.md:what variable `string2` contains).', 'files/rust-book/ch10-03-lifetime-syntax.md:In this example, `string1` is valid until the end of the outer scope, `string2`', 'files/rust-book/ch10-03-lifetime-syntax.md:`string2`. Then we’ll move the `println!` that uses `result` outside the inner', 'files/rust-book/ch10-03-lifetime-syntax.md:Listing 10-24: Attempting to use `result` after `string2`', 'files/rust-book/ch10-03-lifetime-syntax.md:`string2` would need to be valid until the end of the outer scope. Rust knows', 'files/rust-book/ch10-03-lifetime-syntax.md:As humans, we can look at this code and see that `string1` is longer than', 'files/rust-book/ch10-03-lifetime-syntax.md:`string2` and therefore `result` will contain a reference to `string1`.', 'files/rust-book/ch10-03-lifetime-syntax.md:Because `string1` has not gone out of scope yet, a reference to `string1` will' ], [ 'files/rust-book/ch09-01-unrecoverable-errors-with-panic.md: at /Users/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88', 'files/rust-book/ch09-01-unrecoverable-errors-with-panic.md: at /Users/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66' ], [ 'files/rust-book/ch04-01-what-is-ownership.md:String in memory', 'files/rust-book/ch04-01-what-is-ownership.md:s1 and s2 pointing to the same value', 'files/rust-book/ch04-01-what-is-ownership.md:s1 and s2 to two places', 'files/rust-book/ch04-01-what-is-ownership.md:s1 moved to s2' ], ['files/rust-book/ch15-04-rc.md:Two lists that share ownership of a third list'], ['files/rust-book/ch13-01-closures.md:parameter, we would separate them with commas, like `|param1, param2|`.'], ['files/rust-book/ch20-01-single-threaded.md:The `String::from_utf8_lossy` function takes a `&[u8]` and produces a `String`'], [ 'files/rust-book/appendix-06-translation.md:- [Cebuano](https://github.com/agentzero1/book)', 'files/rust-book/appendix-06-translation.md:- [Tagalog](https://github.com/josephace135/book)' ], ['files/rust-book/ch20-00-final-project-a-web-server.md:![hello from rust](img/trpl20-01.png)'], ['files/rust-book/ch14-03-cargo-workspaces.md: Running target/debug/deps/add_one-b3235fea9a156f74'], [ 'files/rust-book/ch04-02-references-and-borrowing.md:&String s pointing at String s1', 'files/rust-book/ch04-02-references-and-borrowing.md:```rust,edition2018', ], [ 'files/rust-book/ch05-02-example-structs.md:using `rect1`, which is the reason we use the `&` in the function signature and', 'files/rust-book/ch05-02-example-structs.md:Let’s try it! The `println!` macro call will now look like `println!("rect1 is', 'files/rust-book/ch05-02-example-structs.md:{:?}", rect1);`. Putting the specifier `:?` inside the curly brackets tells' ], ['files/rust-book/ch11-03-test-organization.md:target/debug/deps/integration_test-ce99bcc2479f4607` (the hash at the end of'], ['files/rust-book/ch15-06-reference-cycles.md:Reference cycle of lists'], [ 'files/rust-book/ch14-02-publishing-to-crates-io.md:Rendered HTML documentation for the `add_one` function of `my_crate`', 'files/rust-book/ch14-02-publishing-to-crates-io.md:Rendered HTML documentation with a comment for the crate as a whole', 'files/rust-book/ch14-02-publishing-to-crates-io.md:Rendered documentation for the `art` crate that lists the `kinds` and `utils` modules', 'files/rust-book/ch14-02-publishing-to-crates-io.md:Rendered documentation for the `art` crate with the re-exports on the front page', 'files/rust-book/ch14-02-publishing-to-crates-io.md:$ cargo login abcdefghijklmnopqrstuvwxyz012345' ], [ 'files/rust-book/ch05-01-defining-structs.md:just this user’s email address, we could use `user1.email` wherever we wanted', 'files/rust-book/ch05-01-defining-structs.md:First, Listing 5-6 shows how we create a new `User` instance in `user2` without', 'files/rust-book/ch05-01-defining-structs.md:use the same values from `user1` that we created in Listing 5-2.', 'files/rust-book/ch05-01-defining-structs.md:the values from `user1`', 'files/rust-book/ch05-01-defining-structs.md:values from the fields of the instance in the `user1` variable', 'files/rust-book/ch05-01-defining-structs.md:The code in Listing 5-7 also creates an instance in `user2` that has a', 'files/rust-book/ch05-01-defining-structs.md:`active` and `sign_in_count` fields from `user1`.', 'files/rust-book/ch05-01-defining-structs.md:> let user1 = User {', 'files/rust-book/ch05-01-defining-structs.md:> username: "someusername123",' ], [ 'files/rust-book/ch05-03-method-syntax.md:called the `area` function and passed `rect1` as an argument, we can instead', 'files/rust-book/ch05-03-method-syntax.md:of `rect2` are smaller than the dimensions of `rect1` but `rect3` is wider than', 'files/rust-book/ch05-03-method-syntax.md:`rect1`:', 'files/rust-book/ch05-03-method-syntax.md:Can rect1 hold rect2? true', 'files/rust-book/ch05-03-method-syntax.md:Can rect1 hold rect3? false', 'files/rust-book/ch05-03-method-syntax.md:`rect1.can_hold(&rect2)` passes in `&rect2`, which is an immutable borrow to', 'files/rust-book/ch05-03-method-syntax.md:`rect2`, an instance of `Rectangle`. This makes sense because we only need to', 'files/rust-book/ch05-03-method-syntax.md:read `rect2` (rather than write, which would mean we’d need a mutable borrow),', 'files/rust-book/ch05-03-method-syntax.md:and we want `main` to retain ownership of `rect2` so we can use it again after' ], ['files/rust-book/ch04-03-slices.md:world containing a pointer to the 6th byte of String s and a length 5'], [ 'files/rust-book/ch10-02-traits.md:pub fn notify(item1: impl Summary, item2: impl Summary) {', 'files/rust-book/ch10-02-traits.md:If we wanted this function to allow `item1` and `item2` to have different', 'files/rust-book/ch10-02-traits.md:pub fn notify(item1: T, item2: T) {', 'files/rust-book/ch10-02-traits.md:The generic type `T` specified as the type of the `item1` and `item2`', 'files/rust-book/ch10-02-traits.md:passed as an argument for `item1` and `item2` must be the same.' ], [ 'files/rust-book/ch15-01-box.md:An infinite Cons list', 'files/rust-book/ch15-01-box.md:A finite Cons list' ] ] }, { // Test -i with regex args: ['-i', '-r', '[a-z]{3}\\d', 'files/rust-book'], expected: [ [ 'files/rust-book/ch10-03-lifetime-syntax.md:type stored in the variable `string1`) as well as string literals (which is', 'files/rust-book/ch10-03-lifetime-syntax.md:what variable `string2` contains).', 'files/rust-book/ch10-03-lifetime-syntax.md:In this example, `string1` is valid until the end of the outer scope, `string2`', 'files/rust-book/ch10-03-lifetime-syntax.md:`string2`. Then we’ll move the `println!` that uses `result` outside the inner', 'files/rust-book/ch10-03-lifetime-syntax.md:Listing 10-24: Attempting to use `result` after `string2`', 'files/rust-book/ch10-03-lifetime-syntax.md:`string2` would need to be valid until the end of the outer scope. Rust knows', 'files/rust-book/ch10-03-lifetime-syntax.md:As humans, we can look at this code and see that `string1` is longer than', 'files/rust-book/ch10-03-lifetime-syntax.md:`string2` and therefore `result` will contain a reference to `string1`.', 'files/rust-book/ch10-03-lifetime-syntax.md:Because `string1` has not gone out of scope yet, a reference to `string1` will' ], [ 'files/rust-book/ch09-01-unrecoverable-errors-with-panic.md: at /Users/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88', 'files/rust-book/ch09-01-unrecoverable-errors-with-panic.md: at /Users/runner/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66', 'files/rust-book/ch09-01-unrecoverable-errors-with-panic.md: 4: core::fmt::ArgumentV1::show_usize' ], [ 'files/rust-book/ch04-01-what-is-ownership.md:String in memory', 'files/rust-book/ch04-01-what-is-ownership.md:s1 and s2 pointing to the same value', 'files/rust-book/ch04-01-what-is-ownership.md:s1 and s2 to two places', 'files/rust-book/ch04-01-what-is-ownership.md:s1 moved to s2' ], ['files/rust-book/ch15-04-rc.md:Two lists that share ownership of a third list'], ['files/rust-book/ch13-01-closures.md:parameter, we would separate them with commas, like `|param1, param2|`.'], [ 'files/rust-book/ch20-01-single-threaded.md:The `String::from_utf8_lossy` function takes a `&[u8]` and produces a `String`', 'files/rust-book/ch20-01-single-threaded.md:User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101', 'files/rust-book/ch20-01-single-threaded.md:This is a minimal HTML5 document with a heading and some text. To return this' ], [ 'files/rust-book/appendix-06-translation.md:- [Cebuano](https://github.com/agentzero1/book)', 'files/rust-book/appendix-06-translation.md:- [Tagalog](https://github.com/josephace135/book)' ], ['files/rust-book/ch20-00-final-project-a-web-server.md:![hello from rust](img/trpl20-01.png)'], ['files/rust-book/ch14-03-cargo-workspaces.md: Running target/debug/deps/add_one-b3235fea9a156f74'], [ 'files/rust-book/ch04-02-references-and-borrowing.md:&String s pointing at String s1', 'files/rust-book/ch04-02-references-and-borrowing.md:```rust,edition2018' ], [ 'files/rust-book/ch05-02-example-structs.md:using `rect1`, which is the reason we use the `&` in the function signature and', 'files/rust-book/ch05-02-example-structs.md:Let’s try it! The `println!` macro call will now look like `println!("rect1 is', 'files/rust-book/ch05-02-example-structs.md:{:?}", rect1);`. Putting the specifier `:?` inside the curly brackets tells' ], [ 'files/rust-book/ch06-01-defining-an-enum.md:struct Ipv4Addr {', 'files/rust-book/ch06-01-defining-an-enum.md:struct Ipv6Addr {', 'files/rust-book/ch06-01-defining-an-enum.md: V4(Ipv4Addr),', 'files/rust-book/ch06-01-defining-an-enum.md: V6(Ipv6Addr),' ], ['files/rust-book/ch11-03-test-organization.md:target/debug/deps/integration_test-ce99bcc2479f4607` (the hash at the end of'], ['files/rust-book/ch15-06-reference-cycles.md:Reference cycle of lists'], [ 'files/rust-book/ch14-02-publishing-to-crates-io.md:Rendered HTML documentation for the `add_one` function of `my_crate`', 'files/rust-book/ch14-02-publishing-to-crates-io.md:Rendered HTML documentation with a comment for the crate as a whole', 'files/rust-book/ch14-02-publishing-to-crates-io.md:Rendered documentation for the `art` crate that lists the `kinds` and `utils` modules', 'files/rust-book/ch14-02-publishing-to-crates-io.md:Rendered documentation for the `art` crate with the re-exports on the front page', 'files/rust-book/ch14-02-publishing-to-crates-io.md:$ cargo login abcdefghijklmnopqrstuvwxyz012345' ], [ 'files/rust-book/ch05-01-defining-structs.md:just this user’s email address, we could use `user1.email` wherever we wanted', 'files/rust-book/ch05-01-defining-structs.md:First, Listing 5-6 shows how we create a new `User` instance in `user2` without', 'files/rust-book/ch05-01-defining-structs.md:use the same values from `user1` that we created in Listing 5-2.', 'files/rust-book/ch05-01-defining-structs.md:the values from `user1`', 'files/rust-book/ch05-01-defining-structs.md:values from the fields of the instance in the `user1` variable', 'files/rust-book/ch05-01-defining-structs.md:The code in Listing 5-7 also creates an instance in `user2` that has a', 'files/rust-book/ch05-01-defining-structs.md:`active` and `sign_in_count` fields from `user1`.', 'files/rust-book/ch05-01-defining-structs.md:> let user1 = User {', 'files/rust-book/ch05-01-defining-structs.md:> username: "someusername123",' ], [ 'files/rust-book/ch05-03-method-syntax.md:called the `area` function and passed `rect1` as an argument, we can instead', 'files/rust-book/ch05-03-method-syntax.md:of `rect2` are smaller than the dimensions of `rect1` but `rect3` is wider than', 'files/rust-book/ch05-03-method-syntax.md:`rect1`:', 'files/rust-book/ch05-03-method-syntax.md:Can rect1 hold rect2? true', 'files/rust-book/ch05-03-method-syntax.md:Can rect1 hold rect3? false', 'files/rust-book/ch05-03-method-syntax.md:`rect1.can_hold(&rect2)` passes in `&rect2`, which is an immutable borrow to', 'files/rust-book/ch05-03-method-syntax.md:`rect2`, an instance of `Rectangle`. This makes sense because we only need to', 'files/rust-book/ch05-03-method-syntax.md:read `rect2` (rather than write, which would mean we’d need a mutable borrow),', 'files/rust-book/ch05-03-method-syntax.md:and we want `main` to retain ownership of `rect2` so we can use it again after' ], ['files/rust-book/ch04-03-slices.md:world containing a pointer to the 6th byte of String s and a length 5'], [ 'files/rust-book/ch10-02-traits.md:pub fn notify(item1: impl Summary, item2: impl Summary) {', 'files/rust-book/ch10-02-traits.md:If we wanted this function to allow `item1` and `item2` to have different', 'files/rust-book/ch10-02-traits.md:pub fn notify(item1: T, item2: T) {', 'files/rust-book/ch10-02-traits.md:The generic type `T` specified as the type of the `item1` and `item2`', 'files/rust-book/ch10-02-traits.md:passed as an argument for `item1` and `item2` must be the same.' ], [ 'files/rust-book/ch15-01-box.md:An infinite Cons list', 'files/rust-book/ch15-01-box.md:A finite Cons list' ] ] }, { // Test -z flag, args: ['-z', 'function', 'files/rust-book-gz/ch02-00-guessing-game-tutorial.md.gz'], expected: [[ 'functions, using external crates, and more! The following chapters will explore', 'As you saw in Chapter 1, the `main` function is the entry point into the', 'The `fn` syntax declares a new function, the parentheses, `()`, indicate there', 'are no parameters, and the curly bracket, `{`, starts the body of the function.', 'calling `String::new`, a function that returns a new instance of a `String`.', 'function* of the `String` type. An associated function is implemented on a type,', 'This `new` function creates a new, empty string. You’ll find a `new` function', 'on many types, because it’s a common name for a function that makes a new value', 'Recall that we included the input/output functionality from the standard', 'the `stdin` function from the `io` module:', 'could have written this function call as `std::io::stdin`. The `stdin` function', 'difficult. Rust doesn’t yet include random number functionality in its standard', 'Next, we’re adding two lines in the middle. The `rand::thread_rng` function', '> Note: You won’t just know which traits to use and which methods and functions', '> other functionality in the `rand` crate, for example, run `cargo doc --open`', 'do that by adding the following two lines to the `main` function body:', '`let`, `match`, methods, associated functions, the use of external crates, and', 'variables, data types, and functions, and shows how to use them in Rust.' ]] }, { // Test -z flag with -r args: ['-r', '-z', 'mutable', 'files/rust-book-gz'], expected: RUST_MUTABLE_EXPECTED.map(file => file.map(line => line.replace('rust-book', 'rust-book-gz').replace('.md', '.md.gz') )) } ] for (const {args, expected} of TESTS) { const flags = args.filter(arg => arg.startsWith('-')) const parameters = args.filter(arg => !arg.startsWith('-')) for (const args of reorderings(parameters, flags)) { test(`grep ${args.join(' ')}`, async t => { const {stdout} = await execFilePromise('node', ['../grep.js', ...args]) matchOutput(t, stdout, expected) }) } } // grep.js is allowed to return a nonzero exit code if no matches were found test('grep no matches', async t => { let stdout try { ({stdout} = await execFilePromise('node', ['../grep.js', 'no-such-string', 'files/independence.txt'])) } catch (e) { ({stdout} = e) } matchOutput(t, stdout, []) }) // Test grepping the standard input test('grep stdin', async t => { const grepPromise = execFilePromise('node', ['../grep.js', 'Rust']) fs.createReadStream('files/rust-book/SUMMARY.md') .on('error', _ => t.fail('Failed to open file')) .pipe(grepPromise.child.stdin) .on('error', _ => t.fail('grep.js did not read stdin')) const {stdout} = await grepPromise matchOutput(t, stdout, [[ '# The Rust Programming Language', '[The Rust Programming Language](title-page.md)', '## Basic Rust Literacy', '## Thinking in Rust', '- [Object Oriented Programming Features of Rust](ch17-00-oop.md)', ' - [Unsafe Rust](ch19-01-unsafe-rust.md)', ' - [G - How Rust is Made and “Nightly Rust”](appendix-07-nightly-rust.md)' ]]) }) // Ensure that the streams deal with lines spread across chunks correctly test('multiple-chunk input file', async t => { const lines = new Array(1e5).fill().map((_, i) => `Line ${i + 1}`) for (let i = 0; i < 10; i++) { const search = `${i}` const {stdout} = await execFilePromise( 'node', ['../grep.js', search, 'files/long.txt'] ) const expectedLines = lines.filter(line => line.includes(search)) t.deepEqual(stdout, expectedLines.map(line => `${line}\n`).join('')) } }) // Ensure that the streams deal with lines containing multiple chunks test('multiple-chunk lines', async t => { const contents = await fs.promises.readFile('files/long-lines.txt', 'utf8') const lines = contents.trim().split('\n') for (let i = 0; i < 10; i++) { const {stdout} = await execFilePromise( 'node', ['../grep.js', `${i}`, 'files/long-lines.txt'] ) t.deepEqual(stdout, lines[i] + '\n') } })