diff --git a/src/ch18-03-pattern-syntax.md b/src/ch18-03-pattern-syntax.md
new file mode 100644
index 0000000..795e221
--- /dev/null
+++ b/src/ch18-03-pattern-syntax.md
@@ -0,0 +1,697 @@
+## All the Pattern Syntax
+
+We've seen some examples of different kinds of patterns throughout the book.
+This section lists all the syntax valid in patterns and why you might want to
+use each of them.
+
+### Literals
+
+As we saw in Chapter 6, you can match against literals directly:
+
+```rust
+let x = 1;
+
+match x {
+ 1 => println!("one"),
+ 2 => println!("two"),
+ 3 => println!("three"),
+ _ => println!("anything"),
+}
+```
+
+This prints `one` since the value in `x` is 1.
+
+### Named Variables
+
+Named variables are irrefutable patterns that match any value.
+
+As with all variables, variables declared as part of a pattern will shadow
+variables with the same name outside of the `match` construct since a `match`
+starts a new scope. In Listing 18-10, we declare a variable named `x` with the
+value `Some(5)` and a variable `y` with the value `10`. Then we have a `match`
+expression on the value `x`. Take a look at the patterns in the match arms and
+the `println!` at the end, and make a guess about what will be printed before
+running this code or reading further:
+
+Filename: src/main.rs
+
+```rust
+fn main() {
+ let x = Some(5);
+ let y = 10;
+
+ match x {
+ Some(50) => println!("Got 50"),
+ Some(y) => println!("Matched, y = {:?}", y),
+ _ => println!("Default case, x = {:?}", x),
+ }
+
+ println!("at the end: x = {:?}, y = {:?}", x, y);
+}
+```
+
+Listing 18-10: A `match` statement with an arm that
+introduces a shadowed variable `y`
+
+
+
+Let's walk through what happens when the `match` statement runs. The first
+match arm has the pattern `Some(50)`, and the value in `x` (`Some(5)`) does not
+match `Some(50)`, so we continue. In the second match arm, the pattern
+`Some(y)` introduces a new variable name `y` that will match any value inside a
+`Some` value. Because we're in a new scope inside the `match` expression, this
+is a new variable, not the `y` we declared at the beginning that has the
+value 10. The new `y` binding will match any value inside a `Some`, which is
+what we have in `x`, so we execute the expression for that arm and print
+`Matched, y = 5` since this `y` binds to the inner value of the `Some` in `x`,
+which is 5.
+
+If `x` had been a `None` value instead of `Some(5)`, we would have matched the
+underscore since the other two arms' patterns would not have matched. In the
+expression for that match arm, since we did not introduce an `x` variable in
+the pattern of the arm, this `x` is still the outer `x` that has not been
+shadowed. In this hypothetical case, the `match` would print `Default case, x =
+None`.
+
+Once the `match` expression is over, its scope ends, and so does the scope of
+the inner `y`. The last `println!` produces `at the end: x = Some(5), y = 10`.
+
+In order to make a `match` expression that compares the values of the outer `x`
+and `y` rather than introducing a shadowed variable, we would need to use a
+match guard conditional instead. We'll be talking about match guards later in
+this section.
+
+### Multiple patterns
+
+In `match` expressions only, you can match multiple patterns with `|`, which
+means *or*:
+
+```rust
+let x = 1;
+
+match x {
+ 1 | 2 => println!("one or two"),
+ 3 => println!("three"),
+ _ => println!("anything"),
+}
+```
+
+This prints `one or two`.
+
+### Matching Ranges of Values with `...`
+
+You can match an inclusive range of values with `...`:
+
+```rust
+let x = 5;
+
+match x {
+ 1 ... 5 => println!("one through five"),
+ _ => println!("something else"),
+}
+```
+
+If `x` is 1, 2, 3, 4, or 5, the first arm will match.
+
+Ranges are only allowed with numeric values or `char` values. Here's an example
+using ranges of `char` values:
+
+```rust
+let x = 'c';
+
+match x {
+ 'a' ... 'j' => println!("early ASCII letter"),
+ 'k' ... 'z' => println!("late ASCII letter"),
+ _ => println!("something else"),
+}
+```
+
+This will print `early ASCII letter`.
+
+### Destructuring to Break Apart Values
+
+Patterns can be used to *destructure* structs, enums, tuples, and references.
+Destructuring means to break a value up into its component pieces. Listing
+18-11 shows a `Point` struct with two fields, `x` and `y`, that we can break
+apart by using a pattern with a `let` statement:
+
+Filename: src/main.rs
+
+```rust
+struct Point {
+ x: i32,
+ y: i32,
+}
+
+fn main() {
+ let p = Point { x: 0, y: 7 };
+
+ let Point { x, y } = p;
+ assert_eq!(0, x);
+ assert_eq!(7, y);
+}
+```
+
+Listing 18-11: Destructuring using struct field
+shorthand
+
+This creates the variables `x` and `y` that match the `x` and `y` of `p`. The
+names of the variables must match the names of the fields to use this
+shorthand. If we wanted to use names different than the variable names, we can
+specify `field_name: variable_name` in the pattern. In Listing 18-12, `a` will
+have the value in the `Point` instance's `x` field and `b` will have the value
+in the `y` field:
+
+Filename: src/main.rs
+
+```rust
+struct Point {
+ x: i32,
+ y: i32,
+}
+
+fn main() {
+ let p = Point { x: 0, y: 7 };
+
+ let Point { x: a, y: b } = p;
+ assert_eq!(0, a);
+ assert_eq!(7, b);
+}
+```
+
+Listing 18-12: Destructuring struct fields into variables
+with different names than the fields
+
+We can also use destructuring with literal values in order to test and use
+inner parts of a value. Listing 18-13 shows a `match` statement that determines
+whether a point lies directly on the `x` axis (which is true when `y = 0`), on
+the `y` axis (`x = 0`), or neither:
+
+```rust
+# struct Point {
+# x: i32,
+# y: i32,
+# }
+#
+fn main() {
+ let p = Point { x: 0, y: 7 };
+
+ match p {
+ Point { x, y: 0 } => println!("On the x axis at {}", x),
+ Point { x: 0, y } => println!("On the y axis at {}", y),
+ Point { x, y } => println!("On neither axis: ({}, {})", x, y),
+ }
+}
+```
+
+Listing 18-13: Destructuring and matching literal values
+in one pattern
+
+This will print `On the y axis at 7` since the value `p` matches the second arm
+by virtue of `x` having the value 0.
+
+We used destructuring on enums in Chapter 6, such as in Listing 6-5 where we
+destructured an `Option` using a `match` expression and added one to the
+inner value of the `Some` variant.
+
+When the value we're matching against a pattern contains a reference, we can
+specify a `&` in the pattern in order to separate the reference and the value.
+This is especially useful in closures used with iterators that iterate over
+references to values when we want to use the values in the closure rather than
+the references. Listing 18-14 shows how to iterate over references to `Point`
+instances in a vector, and destructure both the reference and the struct in
+order to be able to perform calculations on the `x` and `y` values easily:
+
+```rust
+# struct Point {
+# x: i32,
+# y: i32,
+# }
+#
+let points = vec![
+ Point { x: 0, y: 0 },
+ Point { x: 1, y: 5 },
+ Point { x: 10, y: -3 },
+];
+let sum_of_squares: i32 = points
+ .iter()
+ .map(|&Point {x, y}| x * x + y * y)
+ .sum();
+```
+
+Listing 18-14: Destructuring a reference to a struct into
+the struct field values
+
+Because `iter` iterates over references to the items in the vector, if we
+forgot the `&` in the closure arguments in the `map`, we'd get a type mismatch
+error like this:
+
+```text
+error[E0308]: mismatched types
+ -->
+ |
+14 | .map(|Point {x, y}| x * x + y * y)
+ | ^^^^^^^^^^^^ expected &Point, found struct `Point`
+ |
+ = note: expected type `&Point`
+ found type `Point`
+```
+
+This says Rust was expecting our closure to match `&Point`, but we tried to
+match the value with a pattern that was a `Point` value, not a reference to a
+`Point`.
+
+We can mix, match, and nest destructuring patterns in even more complex ways:
+we can do something complicated like this example where we nest structs and
+tuples inside of a tuple and destructure all the primitive values out:
+
+```rust
+# struct Point {
+# x: i32,
+# y: i32,
+# }
+#
+let ((feet, inches), Point {x, y}) = ((3, 10), Point { x: 3, y: -10 });
+```
+
+This lets us break complex types into their component parts.
+
+### Ignoring Values in a Pattern
+
+There are a few ways to ignore entire values or parts of values: using the `_`
+pattern, using the `_` pattern within another pattern, using a name that starts
+with an underscore, or using `..` to ignore all remaining parts of a value.
+Let's explore how and why to do each of these.
+
+#### Ignoring an Entire Value with `_`
+
+We've seen the use of underscore as a wildcard pattern that will match any value
+but not bind to the value. While the underscore pattern is especially useful as
+the last arm in a `match` expression, we can use it in any pattern, such as
+function arguments as shown in Listing 18-15:
+
+```rust
+fn foo(_: i32) {
+ // code goes here
+}
+```
+
+Listing 18-15: Using `_` in a function signature
+
+Normally, you would change the signature to not have the unused parameter. In
+cases such as implementing a trait, where you need a certain type signature,
+using an underscore lets you ignore a parameter, and the compiler won't warn
+about unused function parameters like it would if we had used a name instead.
+
+#### Ignoring Parts of a Value with a Nested `_`
+
+We can also use `_` inside of another pattern to ignore just part of a value.
+In Listing 18-16, the first `match` arm's pattern matches a `Some` value but
+ignores the value inside of the `Some` variant as specified by the underscore:
+
+```rust
+let x = Some(5);
+
+match x {
+ Some(_) => println!("got a Some and I don't care what's inside"),
+ None => (),
+}
+```
+
+Listing 18-16: Ignoring the value inside of the `Some`
+variant by using a nested underscore
+
+This is useful when the code associated with the `match` arm doesn't use the
+nested part of the variable at all.
+
+We can also use underscores in multiple places within one pattern, as shown in
+Listing 18-17 where we're ignoring the second and fourth values in a tuple of
+five items:
+
+```rust
+let numbers = (2, 4, 8, 16, 32);
+
+match numbers {
+ (first, _, third, _, fifth) => {
+ println!("Some numbers: {}, {}, {}", first, third, fifth)
+ },
+}
+```
+
+Listing 18-17: Ignoring multiple parts of a tuple
+
+This will print `Some numbers: 2, 8, 32`, and the values 4 and 16 will be
+ignored.
+
+#### Ignoring an Unused Variable by Starting its Name with an Underscore
+
+Usually, Rust will warn you if you create a variable but don't use it anywhere,
+since that could be a bug. If you're prototyping or just starting a project,
+though, you might create a variable that you'll use eventually, but temporarily
+it will be unused. If you're in this situation and would like to tell Rust not
+to warn you about the unused variable, you can start the name of the variable
+with an underscore. This works just like a variable name in any pattern, only
+Rust won't warn you if the variable goes unused. In Listing 18-18, we
+do get a warning about not using the variable `y`, but we don't get a warning
+about not using the variable `_x`:
+
+```rust
+fn main() {
+ let _x = 5;
+ let y = 10;
+}
+```
+
+Listing 18-18: Starting a variable name with an underscore
+in order to not get unused variable warnings
+
+Note that there is a subtle difference between using only `_` and using a name
+that starts with an underscore like `_x`: `_x` still binds the value to the
+variable, but `_` doesn't bind at all.
+
+Listing 18-19 shows a case where this distinction matters: `s` will still be
+moved into `_s`, which prevents us from using `s` again:
+
+```rust,ignore
+let s = Some(String::from("Hello!"));
+
+if let Some(_s) = s {
+ println!("found a string");
+}
+
+println!("{:?}", s);
+```
+
+Listing 18-19: An unused variable starting with an
+underscore still binds the value, which may take ownership of the value
+
+Using underscore by itself, however, doesn't ever bind to the value. Listing
+18-20 will compile without any errors since `s` does not get moved into `_`:
+
+```rust
+let s = Some(String::from("Hello!"));
+
+if let Some(_) = s {
+ println!("found a string");
+}
+
+println!("{:?}", s);
+```
+
+Listing 18-20: Using underscore does not bind the
+value
+
+This works just fine. Because we never bind `s` to anything, it's not moved.
+
+#### Ignoring Remaining Parts of a Value with `..`
+
+With values that have many parts, we can extract only a few parts and avoid
+having to list underscores for each remaining part by instead using `..`. The
+`..` pattern will ignore any parts of a value that we haven't explicitly
+matched in the rest of the pattern. In Listing 18-21, we have a `Point` struct
+that holds a coordinate in three dimensional space. In the `match` expression,
+we only want to operate on the `x` coordinate and ignore the values in the `y`
+and `z` fields:
+
+```rust
+struct Point {
+ x: i32,
+ y: i32,
+ z: i32,
+}
+
+let origin = Point { x: 0, y: 0, z: 0 };
+
+match origin {
+ Point { x, .. } => println!("x is {}", x),
+}
+```
+
+Listing 18-21: Ignoring all fields of a `Point` except
+for `x` by using `..`
+
+Using `..` is shorter to type than having to list out `y: _` and `z: _`. The
+`..` pattern is especially useful when working with structs that have lots of
+fields in situations where only one or two fields are relevant.
+
+`..` will expand to as many values as it needs to be. Listing 18-22 shows a use
+of `..` with a tuple:
+
+```rust
+fn main() {
+ let numbers = (2, 4, 8, 16, 32);
+
+ match numbers {
+ (first, .., last) => {
+ println!("Some numbers: {}, {}", first, last);
+ },
+ }
+}
+```
+
+Listing 18-22: Matching only the first and last values in
+a tuple and ignoring all other values with `..`
+
+Here, we have the first and last value matched, with `first` and `last`. The
+`..` will match and ignore all of the things in the middle.
+
+Using `..` must be unambiguous, however. Listing 18-23 shows an example where
+it's not clear to Rust which values we want to match and which values we want
+to ignore:
+
+```rust,ignore
+fn main() {
+ let numbers = (2, 4, 8, 16, 32);
+
+ match numbers {
+ (.., second, ..) => {
+ println!("Some numbers: {}", second)
+ },
+ }
+}
+```
+
+Listing 18-23: An attempt to use `..` in a way that is
+ambiguous
+
+If we compile this example, we get this error:
+
+```text
+error: `..` can only be used once per tuple or tuple struct pattern
+ --> src/main.rs:5:22
+ |
+5 | (.., second, ..) => {
+ | ^^
+```
+
+It's not possible to determine how many values in the tuple should be ignored
+before one value is matched with `second`, and then how many further values are
+ignored after that. We could mean that we want to ignore 2, bind `second` to 4,
+then ignore 8, 16, and 32, or we could mean that we want to ignore 2 and 4,
+bind `second` to 8, then ignore 16 and 32, and so forth. The variable name
+`second` doesn't mean anything special to Rust, so we get a compiler error
+since using `..` in two places like this is ambiguous.
+
+### `ref` and `ref mut` to Create References in Patterns
+
+Usually, when you match against a pattern, the variables that the pattern
+introduces are bound to a value. This means you'll end up moving the value into
+the `match` (or wherever you're using the pattern) since the ownership rules
+apply. Listing 18-24 shows an example:
+
+```rust,ignore
+let robot_name = Some(String::from("Bors"));
+
+match robot_name {
+ Some(name) => println!("Found a name: {}", name),
+ None => (),
+}
+
+println!("robot_name is: {:?}", robot_name);
+```
+
+Listing 18-24: Creating a variable in a match arm pattern
+takes ownership of the value
+
+This example will fail to compile since the value inside the `Some` value in
+`robot_name` is moved within the `match` when `name` binds to that value.
+
+Using `&` in a pattern matches an existing reference in the value, as we saw in
+the "Destructuring to Break Apart Values" section. If you want to create a
+reference instead in order to borrow the value in a pattern variable, use the
+`ref` keyword before the new variable, as shown in Listing 18-25:
+
+```rust
+let robot_name = Some(String::from("Bors"));
+
+match robot_name {
+ Some(ref name) => println!("Found a name: {}", name),
+ None => (),
+}
+
+println!("robot_name is: {:?}", robot_name);
+```
+
+Listing 18-25: Creating a reference so that a pattern
+variable does not take ownership of a value
+
+This example will compile because the value in the `Some` variant in
+`robot_name` is not moved into the `Some(ref name)` arm of the match; the match
+only took a reference to the data in `robot_name` rather than moving it.
+
+To create a mutable reference, use `ref mut` for the same reason as shown in
+Listing 18-26:
+
+```rust
+let mut robot_name = Some(String::from("Bors"));
+
+match robot_name {
+ Some(ref mut name) => *name = String::from("Another name"),
+ None => (),
+}
+
+println!("robot_name is: {:?}", robot_name);
+```
+
+Listing 18-26: Creating a mutable reference to a value as
+part of a pattern using `ref mut`
+
+This example will compile and print `robot_name is: Some("Another name")`.
+Since `name` is a mutable reference, within the match arm code, we need to
+dereference using the `*` operator in order to be able to mutate the value.
+
+### Extra Conditionals with Match Guards
+
+You can introduce *match guards* as part of a match arm by specifying an
+additional `if` conditional after the pattern. The conditional can use
+variables created in the pattern. Listing 18-27 has a `match` expression with a
+match guard in the first arm:
+
+```rust
+let num = Some(4);
+
+match num {
+ Some(x) if x < 5 => println!("less than five: {}", x),
+ Some(x) => println!("{}", x),
+ None => (),
+}
+```
+
+Listing 18-27: Adding a match guard to a pattern
+
+This example will print `less than five: 4`. If `num` was instead `Some(7)`,
+this example would print `7`. Match guards allow you to express more complexity
+than patterns alone give you.
+
+In Listing 18-10, we saw that since patterns shadow variables, we weren't able
+to specify a pattern to express the case when a value was equal to a variable
+outside the `match`. Listing 18-28 shows how we can use a match guard to
+accomplish this:
+
+```rust
+fn main() {
+ let x = Some(5);
+ let y = 10;
+
+ match x {
+ Some(50) => println!("Got 50"),
+ Some(n) if n == y => println!("Matched, n = {:?}", n),
+ _ => println!("Default case, x = {:?}", x),
+ }
+
+ println!("at the end: x = {:?}, y = {:?}", x, y);
+}
+```
+
+Listing 18-28: Using a match guard to test for equality
+with an outer variable
+
+This will now print `Default case, x = Some(5)`. Because the second match arm
+is not introducing a new variable `y` that shadows the outer `y` in the
+pattern, we can use `y` in the match guard. We're still destructuring `x` to
+get the inner value `n`, and then we can compare `n` and `y` in the match guard.
+
+If you're using a match guard with multiple patterns specified by `|`, the
+match guard condition applies to all of the patterns. Listing 18-29 shows a
+match guard that applies to the value matched by all three patterns in the
+first arm:
+
+```rust
+let x = 4;
+let y = false;
+
+match x {
+ 4 | 5 | 6 if y => println!("yes"),
+ _ => println!("no"),
+}
+```
+
+Listing 18-29: Combining multiple patterns with a match
+guard
+
+This prints `no` since the `if` condition applies to the whole pattern `4 | 5 |
+6`, not only to the last value `6`. In other words, the precedence of a match
+guard in relation to a pattern behaves like this:
+
+```text
+(4 | 5 | 6) if y => ...
+```
+
+rather than this:
+
+```text
+4 | 5 | (6 if y) => ...
+```
+
+### `@` Bindings
+
+In order to test a value in a pattern but also be able to create a variable
+bound to the value, we can use `@`. Listing 18-30 shows an example where we
+want to test that a `Message::Hello` `id` field is within the range `3...7` but
+also be able to bind to the value so that we can use it in the code associated
+with the arm:
+
+```rust
+enum Message {
+ Hello { id: i32 },
+}
+
+let msg = Message::Hello { id: 5 };
+
+match msg {
+ Message::Hello { id: id @ 3...7 } => {
+ println!("Found an id in range: {}", id)
+ },
+ Message::Hello { id: 10...12 } => {
+ println!("Found an id in another range")
+ },
+ Message::Hello { id } => {
+ println!("Found some other id: {}", id)
+ },
+}
+```
+
+Listing 18-30: Using `@` to bind to a value in a pattern
+while also testing it
+
+This example will print `Found an id in range: 5`. By specifying `id @` before
+the range, we're capturing whatever value matched the range while also testing
+it. In the second arm where we only have a range specified in the pattern, the
+code associated with the arm doesn't know if `id` is 10, 11, or 12, since we
+haven't saved the `id` value in a variable: we only know that the value matched
+something in that range if that arm's code is executed. In the last arm where
+we've specified a variable without a range, we do have the value available to
+use in the arm's code, but we haven't applied any other test to the value.
+Using `@` lets us test a value and save it in a variable within one pattern.
+
+## Summary
+
+Patterns are a useful feature of Rust that help to distinguish between
+different kinds of data. When used in `match` statements, Rust makes sure that
+your patterns cover every possible value. Patterns in `let` statements and
+function parameters make those constructs more powerful, enabling the
+destructuring of values into smaller parts at the same time as assigning to
+variables.
+
+Now, for the penultimate chapter of the book, let's take a look at some
+advanced parts of a variety of Rust's features.