Files

137 lines
9.0 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Rust Book coverage map — what is owned, what is missing</title>
<link rel="stylesheet" href="../assets/style.css" />
</head>
<body>
<h1>Coverage map</h1>
<p class="subtitle">Every chapter of The Rust Programming Language against this workspace · updated after lesson 0009</p>
<div class="callout">
The chapter list is taken verbatim from the book's
<a href="https://github.com/rust-lang/book/blob/main/src/SUMMARY.md">table of contents</a>, not from memory.
<strong>Read</strong> means you covered it in your two months. <strong>Produced</strong> means code you wrote in this
workspace uses it correctly — that is the only column that counts for the
<a href="../MISSION.md">mission</a>.
</div>
<h2>The map</h2>
<table>
<tr><th>Ch</th><th>Topic</th><th>State</th><th>Evidence / gap</th></tr>
<tr><td>1–2</td><td>Getting started, guessing game</td><td>Produced</td>
<td><code>hello_cargo/</code>, <code>guessing_game/</code></td></tr>
<tr><td>3</td><td>Variables, types, functions, control flow</td><td>Produced</td>
<td><code>variables/</code>, <code>function/</code>, <code>control_flow/</code>; 0001 diagnostic solid</td></tr>
<tr><td>4</td><td>Ownership, borrowing, slices</td><td>Produced</td>
<td><code>&amp;self</code> methods and <code>&amp;[Task]</code> accessor in <code>tasks/</code>. Watch for: you have never hit
a borrow-checker fight in your own multi-owner code, because nothing has needed two owners yet.</td></tr>
<tr><td>5</td><td>Structs and methods</td><td>Produced</td><td>0003 / 0004, <code>tasks/src/task.rs</code></td></tr>
<tr><td>6</td><td>Enums and <code>match</code></td><td>Produced</td>
<td><code>Status</code>, <code>Priority</code>, <code>Command</code>, and now <code>TaskError</code> (0006)</td></tr>
<tr><td>7</td><td>Packages, crates, modules</td><td>Produced</td>
<td><code>tasks/</code> is a lib + bin package with four modules</td></tr>
<tr><td>8</td><td>Collections: <code>Vec</code>, <code>String</code>, <code>HashMap</code></td><td>Produced</td>
<td>0008 drill, in <code>tasks/</code>: <code>HashMap&lt;Priority, usize&gt;</code> built with the <code>entry</code>/<code>or_insert</code>
counting idiom, <code>get().copied().unwrap_or(0)</code>, <code>Eq + Hash + Copy</code> derives on a key type, and a
<code>String</code> built by <code>collect</code>. Not done: <code>BTreeMap</code>, <code>HashSet</code>, string slicing by byte index.</td></tr>
<tr><td>9</td><td>Error handling: <code>panic!</code>, <code>Result</code>, <code>?</code></td><td>Produced</td>
<td>0005 + 0006: <code>?</code>, <code>ok_or</code>, own error enum, stderr + exit 1</td></tr>
<tr><td>10.1</td><td>Generic data types</td><td>Produced</td>
<td>0008 drill: <code>fn tally&lt;T, K, F&gt;(items: &amp;[T], key: F) -&gt; HashMap&lt;K, usize&gt;</code> in <code>tasks/src/stats.rs</code>,
with a <code>where</code> clause bounding <code>K: Eq + Hash</code> and <code>F: Fn(&amp;T) -&gt; K</code> — written from the
signature up, called at three different <code>T</code>/<code>K</code> pairs, one of them a non-<code>Copy</code> key.
Not done: generic <em>structs</em> and generic <code>impl</code> blocks.</td></tr>
<tr><td>10.2</td><td>Traits</td><td>Produced</td>
<td><code>Display for Task</code> (0005), <code>Display</code> + <code>Error</code> + <code>From</code> for <code>TaskError</code> (0006),
<code>FromStr for Task</code> with an associated <code>type Err</code> and a hand-written <code>PartialEq</code> (0007)</td></tr>
<tr><td>10.3</td><td>Lifetimes</td><td class="gap">Gap — untouched</td>
<td>Zero exposure in this workspace. You have dodged it by owning everything (<code>String</code>, not <code>&amp;'a str</code>).
Needed to read other people's code and to review a PR; not needed to ship your CLI.</td></tr>
<tr><td>11</td><td>Writing automated tests</td><td class="gap">Taught — drill pending</td>
<td>0009: <code>#[test]</code>, <code>#[cfg(test)] mod tests</code> with <code>use super::*</code>, the three assertion macros
and their failure output, <code>#[should_panic(expected)]</code> vs a <code>-&gt; Result&lt;(), E&gt;</code> test, unit vs
integration access (<code>E0603</code>/<code>E0616</code>), <code>tests/common/mod.rs</code>, the runner flags, and why
<code>src/main.rs</code> is untestable — <code>run</code> moves to the library and writes to <code>&amp;mut impl Write</code>.
Graded by six planted mutants, not by a test count.</td></tr>
<tr><td>12</td><td>I/O project: args, files, stderr, env</td><td>Produced</td>
<td>0007: <code>fs::read_to_string</code>/<code>fs::write</code>, <code>io::Error</code> + <code>ErrorKind::NotFound</code> match guard,
<code>env::var</code> with a default, on top of <code>env::args</code> and stderr + exit 1 from 0005. Not done: <code>BufReader</code>,
file locking, serde — none needed at this size.</td></tr>
<tr><td>13</td><td>Closures and iterators</td><td>Produced</td>
<td>0008 drill: <code>filter</code>/<code>map</code>/<code>collect</code> chains, <code>find</code> vs <code>position</code>,
<code>Vec::retain</code>, <code>lines()</code>, <code>collect::&lt;Result&lt;Vec&lt;_&gt;, E&gt;&gt;()</code> short-circuiting, and a
function that <em>takes</em> a closure (<code>F: Fn</code>). Not done: <code>fold</code>, <code>zip</code>,
<code>impl Iterator</code> for your own type.</td></tr>
<tr><td>14</td><td>Cargo, crates.io, workspaces</td><td>Skip for now</td>
<td>Learn <code>cargo add</code> and features when a dependency is actually needed (serde, axum).</td></tr>
<tr><td>15</td><td>Smart pointers: <code>Box</code>, <code>Rc</code>, <code>RefCell</code>, <code>Deref</code>, <code>Drop</code></td><td>Partial</td>
<td><code>Box&lt;dyn Error&gt;</code> met in 0005/0006. <code>Rc</code>/<code>RefCell</code> untouched — reach for them only when a real
shared-ownership problem appears, not before.</td></tr>
<tr><td>16</td><td>Concurrency: threads, channels, <code>Send</code>/<code>Sync</code></td><td class="gap">Gap</td>
<td>Untouched apart from the <code>Send + Sync</code> bound your 0006 test asserts. Prerequisite for understanding
why an axum handler must be <code>Send</code>.</td></tr>
<tr><td>17</td><td>Async: futures, <code>async</code>/<code>await</code>, streams</td><td class="gap">Gap — by design</td>
<td>Required for axum/tokio, deliberately last. The unused <code>trpl</code> dependency in <code>get-dependecies/</code> is
the abandoned first attempt. Do it after 8, 11, 13.</td></tr>
<tr><td>18</td><td>Trait objects, OOP patterns</td><td>Partial</td>
<td><code>dyn Error</code> is the same mechanism as 18.2. The state-machine pattern (18.3) is optional reading.</td></tr>
<tr><td>19</td><td>Patterns and matching</td><td>Partial</td>
<td><code>match</code> ✓, <code>if let</code> ✓ (0005 drill). Guards (<code>Some(x) if x &gt; 5</code>), <code>@</code> bindings,
<code>let ... else</code>, and <code>matches!</code> — one page of reading, high value per minute.</td></tr>
<tr><td>20</td><td>Unsafe, advanced traits, macros</td><td>Skip</td>
<td>Associated types and generic-parameter defaults matter eventually (serde uses them). Not now.</td></tr>
<tr><td>21</td><td>Final project: multithreaded web server</td><td>Not started</td>
<td>The natural capstone before axum — it is a backend service with no framework.</td></tr>
</table>
<h2>The order that follows from this</h2>
<p>After the 0009 drill, one gap in the book's core is left, and it is the mildest one:</p>
<ol>
<li><strong>Lifetimes</strong> (ch 10.3) — as reading practice, not as a build. You have written two without
noticing: <code>titles_with</code> returns <code>Vec&lt;&amp;str&gt;</code> borrowed from <code>&amp;self</code>, and
<code>Status::label</code> returns <code>&amp;str</code> the same way. Elision filled both annotations in. Reading
other people's signatures needs the explicit form.</li>
<li><strong>Patterns</strong> (ch 19) — one page: match guards, <code>@</code> bindings, <code>matches!</code>,
<code>let … else</code>. Your suite already uses <code>matches!</code>; the rest is high value per minute.</li>
</ol>
<p>Then serde → axum → async, where the traits from 0005–0008 and the testing from 0009 stop being an exercise
and start being the whole API surface: an axum handler is a function a test can call. Chapter 21's web server is
the natural capstone before a framework.</p>
<footer>
<p><strong>Primary source:</strong> <a href="https://doc.rust-lang.org/stable/book/">The Rust Programming Language</a> ·
chapter list from <a href="https://github.com/rust-lang/book/blob/main/src/SUMMARY.md">SUMMARY.md</a>.</p>
<p>Reference: <a href="rust-syntax.html">Rust syntax reference</a> ·
Lessons: <a href="../lessons/0006-your-own-error-type.html">0006</a> ·
<a href="../lessons/0007-files-and-fromstr.html">0007</a> ·
<a href="../lessons/0008-iterators-and-hashmap.html">0008</a> ·
<a href="../lessons/0009-writing-your-own-tests.html">0009</a></p>
<p>Disagree with a "Produced" or a "Gap"? Say so — this table decides what gets taught next, so it is worth arguing about.</p>
</footer>
</body>
</html>