@booklib/core 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (374) hide show
  1. package/.cursor/rules/booklib-standards.mdc +40 -0
  2. package/.gemini/context.md +372 -0
  3. package/AGENTS.md +166 -0
  4. package/CHANGELOG.md +226 -0
  5. package/CLAUDE.md +81 -0
  6. package/CODE_OF_CONDUCT.md +31 -0
  7. package/CONTRIBUTING.md +304 -0
  8. package/LICENSE +21 -0
  9. package/PLAN.md +28 -0
  10. package/README.ja.md +198 -0
  11. package/README.ko.md +198 -0
  12. package/README.md +503 -0
  13. package/README.pt-BR.md +198 -0
  14. package/README.uk.md +241 -0
  15. package/README.zh-CN.md +198 -0
  16. package/SECURITY.md +9 -0
  17. package/agents/architecture-reviewer.md +136 -0
  18. package/agents/booklib-reviewer.md +90 -0
  19. package/agents/data-reviewer.md +107 -0
  20. package/agents/jvm-reviewer.md +146 -0
  21. package/agents/python-reviewer.md +128 -0
  22. package/agents/rust-reviewer.md +115 -0
  23. package/agents/ts-reviewer.md +110 -0
  24. package/agents/ui-reviewer.md +117 -0
  25. package/assets/logo.svg +36 -0
  26. package/bin/booklib-mcp.js +304 -0
  27. package/bin/booklib.js +1705 -0
  28. package/bin/skills.cjs +1292 -0
  29. package/booklib-router.mdc +36 -0
  30. package/booklib.config.json +19 -0
  31. package/commands/animation-at-work.md +10 -0
  32. package/commands/clean-code-reviewer.md +10 -0
  33. package/commands/data-intensive-patterns.md +10 -0
  34. package/commands/data-pipelines.md +10 -0
  35. package/commands/design-patterns.md +10 -0
  36. package/commands/domain-driven-design.md +10 -0
  37. package/commands/effective-java.md +10 -0
  38. package/commands/effective-kotlin.md +10 -0
  39. package/commands/effective-python.md +10 -0
  40. package/commands/effective-typescript.md +10 -0
  41. package/commands/kotlin-in-action.md +10 -0
  42. package/commands/lean-startup.md +10 -0
  43. package/commands/microservices-patterns.md +10 -0
  44. package/commands/programming-with-rust.md +10 -0
  45. package/commands/refactoring-ui.md +10 -0
  46. package/commands/rust-in-action.md +10 -0
  47. package/commands/skill-router.md +10 -0
  48. package/commands/spring-boot-in-action.md +10 -0
  49. package/commands/storytelling-with-data.md +10 -0
  50. package/commands/system-design-interview.md +10 -0
  51. package/commands/using-asyncio-python.md +10 -0
  52. package/commands/web-scraping-python.md +10 -0
  53. package/community/registry.json +1616 -0
  54. package/hooks/hooks.json +23 -0
  55. package/hooks/posttooluse-capture.mjs +67 -0
  56. package/hooks/suggest.js +153 -0
  57. package/lib/agent-behaviors.js +40 -0
  58. package/lib/agent-detector.js +96 -0
  59. package/lib/config-loader.js +39 -0
  60. package/lib/conflict-resolver.js +148 -0
  61. package/lib/context-builder.js +574 -0
  62. package/lib/discovery-engine.js +298 -0
  63. package/lib/doctor/hook-installer.js +83 -0
  64. package/lib/doctor/usage-tracker.js +87 -0
  65. package/lib/engine/ai-features.js +253 -0
  66. package/lib/engine/auditor.js +103 -0
  67. package/lib/engine/bm25-index.js +178 -0
  68. package/lib/engine/capture.js +120 -0
  69. package/lib/engine/corrections.js +198 -0
  70. package/lib/engine/doctor.js +195 -0
  71. package/lib/engine/graph-injector.js +137 -0
  72. package/lib/engine/graph.js +161 -0
  73. package/lib/engine/handoff.js +405 -0
  74. package/lib/engine/indexer.js +242 -0
  75. package/lib/engine/parser.js +53 -0
  76. package/lib/engine/query-expander.js +42 -0
  77. package/lib/engine/reranker.js +40 -0
  78. package/lib/engine/rrf.js +59 -0
  79. package/lib/engine/scanner.js +151 -0
  80. package/lib/engine/searcher.js +139 -0
  81. package/lib/engine/session-coordinator.js +306 -0
  82. package/lib/engine/session-manager.js +429 -0
  83. package/lib/engine/synthesizer.js +70 -0
  84. package/lib/installer.js +70 -0
  85. package/lib/instinct-block.js +33 -0
  86. package/lib/mcp-config-writer.js +88 -0
  87. package/lib/paths.js +57 -0
  88. package/lib/profiles/design.md +19 -0
  89. package/lib/profiles/general.md +16 -0
  90. package/lib/profiles/research-analysis.md +22 -0
  91. package/lib/profiles/software-development.md +23 -0
  92. package/lib/profiles/writing-content.md +19 -0
  93. package/lib/project-initializer.js +916 -0
  94. package/lib/registry/skills.js +102 -0
  95. package/lib/registry-searcher.js +99 -0
  96. package/lib/rules/rules-manager.js +169 -0
  97. package/lib/skill-fetcher.js +333 -0
  98. package/lib/well-known-builder.js +70 -0
  99. package/lib/wizard/index.js +404 -0
  100. package/lib/wizard/integration-detector.js +41 -0
  101. package/lib/wizard/project-detector.js +100 -0
  102. package/lib/wizard/prompt.js +156 -0
  103. package/lib/wizard/registry-embeddings.js +107 -0
  104. package/lib/wizard/skill-recommender.js +69 -0
  105. package/llms-full.txt +254 -0
  106. package/llms.txt +70 -0
  107. package/package.json +45 -0
  108. package/research-reports/2026-04-01-current-architecture.md +160 -0
  109. package/research-reports/IDEAS.md +93 -0
  110. package/rules/common/clean-code.md +42 -0
  111. package/rules/java/effective-java.md +42 -0
  112. package/rules/kotlin/effective-kotlin.md +37 -0
  113. package/rules/python/effective-python.md +38 -0
  114. package/rules/rust/rust.md +37 -0
  115. package/rules/typescript/effective-typescript.md +42 -0
  116. package/scripts/gen-llms-full.mjs +36 -0
  117. package/scripts/gen-og.mjs +142 -0
  118. package/scripts/validate-frontmatter.js +25 -0
  119. package/skills/animation-at-work/SKILL.md +270 -0
  120. package/skills/animation-at-work/assets/example_asset.txt +1 -0
  121. package/skills/animation-at-work/evals/evals.json +44 -0
  122. package/skills/animation-at-work/evals/results.json +13 -0
  123. package/skills/animation-at-work/examples/after.md +64 -0
  124. package/skills/animation-at-work/examples/before.md +35 -0
  125. package/skills/animation-at-work/references/api_reference.md +369 -0
  126. package/skills/animation-at-work/references/review-checklist.md +79 -0
  127. package/skills/animation-at-work/scripts/audit_animations.py +295 -0
  128. package/skills/animation-at-work/scripts/example.py +1 -0
  129. package/skills/clean-code-reviewer/SKILL.md +444 -0
  130. package/skills/clean-code-reviewer/audit.json +35 -0
  131. package/skills/clean-code-reviewer/evals/evals.json +185 -0
  132. package/skills/clean-code-reviewer/evals/results.json +13 -0
  133. package/skills/clean-code-reviewer/examples/after.md +48 -0
  134. package/skills/clean-code-reviewer/examples/before.md +33 -0
  135. package/skills/clean-code-reviewer/references/api_reference.md +158 -0
  136. package/skills/clean-code-reviewer/references/practices-catalog.md +282 -0
  137. package/skills/clean-code-reviewer/references/review-checklist.md +254 -0
  138. package/skills/clean-code-reviewer/scripts/pre-review.py +206 -0
  139. package/skills/data-intensive-patterns/SKILL.md +267 -0
  140. package/skills/data-intensive-patterns/assets/example_asset.txt +1 -0
  141. package/skills/data-intensive-patterns/evals/evals.json +54 -0
  142. package/skills/data-intensive-patterns/evals/results.json +13 -0
  143. package/skills/data-intensive-patterns/examples/after.md +61 -0
  144. package/skills/data-intensive-patterns/examples/before.md +38 -0
  145. package/skills/data-intensive-patterns/references/api_reference.md +34 -0
  146. package/skills/data-intensive-patterns/references/patterns-catalog.md +551 -0
  147. package/skills/data-intensive-patterns/references/review-checklist.md +193 -0
  148. package/skills/data-intensive-patterns/scripts/adr.py +213 -0
  149. package/skills/data-intensive-patterns/scripts/example.py +1 -0
  150. package/skills/data-pipelines/SKILL.md +259 -0
  151. package/skills/data-pipelines/assets/example_asset.txt +1 -0
  152. package/skills/data-pipelines/evals/evals.json +45 -0
  153. package/skills/data-pipelines/evals/results.json +13 -0
  154. package/skills/data-pipelines/examples/after.md +97 -0
  155. package/skills/data-pipelines/examples/before.md +37 -0
  156. package/skills/data-pipelines/references/api_reference.md +301 -0
  157. package/skills/data-pipelines/references/review-checklist.md +181 -0
  158. package/skills/data-pipelines/scripts/example.py +1 -0
  159. package/skills/data-pipelines/scripts/new_pipeline.py +444 -0
  160. package/skills/design-patterns/SKILL.md +271 -0
  161. package/skills/design-patterns/assets/example_asset.txt +1 -0
  162. package/skills/design-patterns/evals/evals.json +46 -0
  163. package/skills/design-patterns/evals/results.json +13 -0
  164. package/skills/design-patterns/examples/after.md +52 -0
  165. package/skills/design-patterns/examples/before.md +29 -0
  166. package/skills/design-patterns/references/api_reference.md +1 -0
  167. package/skills/design-patterns/references/patterns-catalog.md +726 -0
  168. package/skills/design-patterns/references/review-checklist.md +173 -0
  169. package/skills/design-patterns/scripts/example.py +1 -0
  170. package/skills/design-patterns/scripts/scaffold.py +807 -0
  171. package/skills/domain-driven-design/SKILL.md +142 -0
  172. package/skills/domain-driven-design/assets/example_asset.txt +1 -0
  173. package/skills/domain-driven-design/evals/evals.json +48 -0
  174. package/skills/domain-driven-design/evals/results.json +13 -0
  175. package/skills/domain-driven-design/examples/after.md +80 -0
  176. package/skills/domain-driven-design/examples/before.md +43 -0
  177. package/skills/domain-driven-design/references/api_reference.md +1 -0
  178. package/skills/domain-driven-design/references/patterns-catalog.md +545 -0
  179. package/skills/domain-driven-design/references/review-checklist.md +158 -0
  180. package/skills/domain-driven-design/scripts/example.py +1 -0
  181. package/skills/domain-driven-design/scripts/scaffold.py +421 -0
  182. package/skills/effective-java/SKILL.md +227 -0
  183. package/skills/effective-java/assets/example_asset.txt +1 -0
  184. package/skills/effective-java/evals/evals.json +46 -0
  185. package/skills/effective-java/evals/results.json +13 -0
  186. package/skills/effective-java/examples/after.md +83 -0
  187. package/skills/effective-java/examples/before.md +37 -0
  188. package/skills/effective-java/references/api_reference.md +1 -0
  189. package/skills/effective-java/references/items-catalog.md +955 -0
  190. package/skills/effective-java/references/review-checklist.md +216 -0
  191. package/skills/effective-java/scripts/checkstyle_setup.py +211 -0
  192. package/skills/effective-java/scripts/example.py +1 -0
  193. package/skills/effective-kotlin/SKILL.md +271 -0
  194. package/skills/effective-kotlin/assets/example_asset.txt +1 -0
  195. package/skills/effective-kotlin/audit.json +29 -0
  196. package/skills/effective-kotlin/evals/evals.json +45 -0
  197. package/skills/effective-kotlin/evals/results.json +13 -0
  198. package/skills/effective-kotlin/examples/after.md +36 -0
  199. package/skills/effective-kotlin/examples/before.md +38 -0
  200. package/skills/effective-kotlin/references/api_reference.md +1 -0
  201. package/skills/effective-kotlin/references/practices-catalog.md +1228 -0
  202. package/skills/effective-kotlin/references/review-checklist.md +126 -0
  203. package/skills/effective-kotlin/scripts/example.py +1 -0
  204. package/skills/effective-python/SKILL.md +441 -0
  205. package/skills/effective-python/evals/evals.json +44 -0
  206. package/skills/effective-python/evals/results.json +13 -0
  207. package/skills/effective-python/examples/after.md +56 -0
  208. package/skills/effective-python/examples/before.md +40 -0
  209. package/skills/effective-python/ref-01-pythonic-thinking.md +202 -0
  210. package/skills/effective-python/ref-02-lists-and-dicts.md +146 -0
  211. package/skills/effective-python/ref-03-functions.md +186 -0
  212. package/skills/effective-python/ref-04-comprehensions-generators.md +211 -0
  213. package/skills/effective-python/ref-05-classes-interfaces.md +188 -0
  214. package/skills/effective-python/ref-06-metaclasses-attributes.md +209 -0
  215. package/skills/effective-python/ref-07-concurrency.md +213 -0
  216. package/skills/effective-python/ref-08-robustness-performance.md +248 -0
  217. package/skills/effective-python/ref-09-testing-debugging.md +253 -0
  218. package/skills/effective-python/ref-10-collaboration.md +175 -0
  219. package/skills/effective-python/references/api_reference.md +218 -0
  220. package/skills/effective-python/references/practices-catalog.md +483 -0
  221. package/skills/effective-python/references/review-checklist.md +190 -0
  222. package/skills/effective-python/scripts/lint.py +173 -0
  223. package/skills/effective-typescript/SKILL.md +262 -0
  224. package/skills/effective-typescript/audit.json +29 -0
  225. package/skills/effective-typescript/evals/evals.json +37 -0
  226. package/skills/effective-typescript/evals/results.json +13 -0
  227. package/skills/effective-typescript/examples/after.md +70 -0
  228. package/skills/effective-typescript/examples/before.md +47 -0
  229. package/skills/effective-typescript/references/api_reference.md +118 -0
  230. package/skills/effective-typescript/references/practices-catalog.md +371 -0
  231. package/skills/effective-typescript/scripts/review.py +169 -0
  232. package/skills/kotlin-in-action/SKILL.md +261 -0
  233. package/skills/kotlin-in-action/assets/example_asset.txt +1 -0
  234. package/skills/kotlin-in-action/evals/evals.json +43 -0
  235. package/skills/kotlin-in-action/evals/results.json +13 -0
  236. package/skills/kotlin-in-action/examples/after.md +53 -0
  237. package/skills/kotlin-in-action/examples/before.md +39 -0
  238. package/skills/kotlin-in-action/references/api_reference.md +1 -0
  239. package/skills/kotlin-in-action/references/practices-catalog.md +436 -0
  240. package/skills/kotlin-in-action/references/review-checklist.md +204 -0
  241. package/skills/kotlin-in-action/scripts/example.py +1 -0
  242. package/skills/kotlin-in-action/scripts/setup_detekt.py +224 -0
  243. package/skills/lean-startup/SKILL.md +160 -0
  244. package/skills/lean-startup/assets/example_asset.txt +1 -0
  245. package/skills/lean-startup/evals/evals.json +43 -0
  246. package/skills/lean-startup/evals/results.json +13 -0
  247. package/skills/lean-startup/examples/after.md +80 -0
  248. package/skills/lean-startup/examples/before.md +34 -0
  249. package/skills/lean-startup/references/api_reference.md +319 -0
  250. package/skills/lean-startup/references/review-checklist.md +137 -0
  251. package/skills/lean-startup/scripts/example.py +1 -0
  252. package/skills/lean-startup/scripts/new_experiment.py +286 -0
  253. package/skills/microservices-patterns/SKILL.md +384 -0
  254. package/skills/microservices-patterns/evals/evals.json +45 -0
  255. package/skills/microservices-patterns/evals/results.json +13 -0
  256. package/skills/microservices-patterns/examples/after.md +69 -0
  257. package/skills/microservices-patterns/examples/before.md +40 -0
  258. package/skills/microservices-patterns/references/patterns-catalog.md +391 -0
  259. package/skills/microservices-patterns/references/review-checklist.md +169 -0
  260. package/skills/microservices-patterns/scripts/new_service.py +583 -0
  261. package/skills/programming-with-rust/SKILL.md +209 -0
  262. package/skills/programming-with-rust/evals/evals.json +37 -0
  263. package/skills/programming-with-rust/evals/results.json +13 -0
  264. package/skills/programming-with-rust/examples/after.md +107 -0
  265. package/skills/programming-with-rust/examples/before.md +59 -0
  266. package/skills/programming-with-rust/references/api_reference.md +152 -0
  267. package/skills/programming-with-rust/references/practices-catalog.md +335 -0
  268. package/skills/programming-with-rust/scripts/review.py +142 -0
  269. package/skills/refactoring-ui/SKILL.md +362 -0
  270. package/skills/refactoring-ui/assets/example_asset.txt +1 -0
  271. package/skills/refactoring-ui/evals/evals.json +45 -0
  272. package/skills/refactoring-ui/evals/results.json +13 -0
  273. package/skills/refactoring-ui/examples/after.md +85 -0
  274. package/skills/refactoring-ui/examples/before.md +58 -0
  275. package/skills/refactoring-ui/references/api_reference.md +355 -0
  276. package/skills/refactoring-ui/references/review-checklist.md +114 -0
  277. package/skills/refactoring-ui/scripts/audit_css.py +250 -0
  278. package/skills/refactoring-ui/scripts/example.py +1 -0
  279. package/skills/rust-in-action/SKILL.md +350 -0
  280. package/skills/rust-in-action/evals/evals.json +38 -0
  281. package/skills/rust-in-action/evals/results.json +13 -0
  282. package/skills/rust-in-action/examples/after.md +156 -0
  283. package/skills/rust-in-action/examples/before.md +56 -0
  284. package/skills/rust-in-action/references/practices-catalog.md +346 -0
  285. package/skills/rust-in-action/scripts/review.py +147 -0
  286. package/skills/skill-router/SKILL.md +186 -0
  287. package/skills/skill-router/evals/evals.json +38 -0
  288. package/skills/skill-router/evals/results.json +13 -0
  289. package/skills/skill-router/examples/after.md +63 -0
  290. package/skills/skill-router/examples/before.md +39 -0
  291. package/skills/skill-router/references/api_reference.md +24 -0
  292. package/skills/skill-router/references/routing-heuristics.md +89 -0
  293. package/skills/skill-router/references/skill-catalog.md +174 -0
  294. package/skills/skill-router/scripts/route.py +266 -0
  295. package/skills/spring-boot-in-action/SKILL.md +340 -0
  296. package/skills/spring-boot-in-action/evals/evals.json +39 -0
  297. package/skills/spring-boot-in-action/evals/results.json +13 -0
  298. package/skills/spring-boot-in-action/examples/after.md +185 -0
  299. package/skills/spring-boot-in-action/examples/before.md +84 -0
  300. package/skills/spring-boot-in-action/references/practices-catalog.md +403 -0
  301. package/skills/spring-boot-in-action/scripts/review.py +184 -0
  302. package/skills/storytelling-with-data/SKILL.md +241 -0
  303. package/skills/storytelling-with-data/assets/example_asset.txt +1 -0
  304. package/skills/storytelling-with-data/evals/evals.json +47 -0
  305. package/skills/storytelling-with-data/evals/results.json +13 -0
  306. package/skills/storytelling-with-data/examples/after.md +50 -0
  307. package/skills/storytelling-with-data/examples/before.md +33 -0
  308. package/skills/storytelling-with-data/references/api_reference.md +379 -0
  309. package/skills/storytelling-with-data/references/review-checklist.md +111 -0
  310. package/skills/storytelling-with-data/scripts/chart_review.py +301 -0
  311. package/skills/storytelling-with-data/scripts/example.py +1 -0
  312. package/skills/system-design-interview/SKILL.md +233 -0
  313. package/skills/system-design-interview/assets/example_asset.txt +1 -0
  314. package/skills/system-design-interview/evals/evals.json +46 -0
  315. package/skills/system-design-interview/evals/results.json +13 -0
  316. package/skills/system-design-interview/examples/after.md +94 -0
  317. package/skills/system-design-interview/examples/before.md +27 -0
  318. package/skills/system-design-interview/references/api_reference.md +582 -0
  319. package/skills/system-design-interview/references/review-checklist.md +201 -0
  320. package/skills/system-design-interview/scripts/example.py +1 -0
  321. package/skills/system-design-interview/scripts/new_design.py +421 -0
  322. package/skills/using-asyncio-python/SKILL.md +290 -0
  323. package/skills/using-asyncio-python/assets/example_asset.txt +1 -0
  324. package/skills/using-asyncio-python/evals/evals.json +43 -0
  325. package/skills/using-asyncio-python/evals/results.json +13 -0
  326. package/skills/using-asyncio-python/examples/after.md +68 -0
  327. package/skills/using-asyncio-python/examples/before.md +39 -0
  328. package/skills/using-asyncio-python/references/api_reference.md +267 -0
  329. package/skills/using-asyncio-python/references/review-checklist.md +149 -0
  330. package/skills/using-asyncio-python/scripts/check_blocking.py +270 -0
  331. package/skills/using-asyncio-python/scripts/example.py +1 -0
  332. package/skills/web-scraping-python/SKILL.md +280 -0
  333. package/skills/web-scraping-python/assets/example_asset.txt +1 -0
  334. package/skills/web-scraping-python/evals/evals.json +46 -0
  335. package/skills/web-scraping-python/evals/results.json +13 -0
  336. package/skills/web-scraping-python/examples/after.md +109 -0
  337. package/skills/web-scraping-python/examples/before.md +40 -0
  338. package/skills/web-scraping-python/references/api_reference.md +393 -0
  339. package/skills/web-scraping-python/references/review-checklist.md +163 -0
  340. package/skills/web-scraping-python/scripts/example.py +1 -0
  341. package/skills/web-scraping-python/scripts/new_scraper.py +231 -0
  342. package/skills/writing-plans/audit.json +34 -0
  343. package/tests/agent-detector.test.js +83 -0
  344. package/tests/corrections.test.js +245 -0
  345. package/tests/doctor/hook-installer.test.js +72 -0
  346. package/tests/doctor/usage-tracker.test.js +140 -0
  347. package/tests/engine/benchmark-eval.test.js +31 -0
  348. package/tests/engine/bm25-index.test.js +85 -0
  349. package/tests/engine/capture-command.test.js +35 -0
  350. package/tests/engine/capture.test.js +17 -0
  351. package/tests/engine/graph-augmented-search.test.js +107 -0
  352. package/tests/engine/graph-injector.test.js +44 -0
  353. package/tests/engine/graph.test.js +216 -0
  354. package/tests/engine/hybrid-searcher.test.js +74 -0
  355. package/tests/engine/indexer-bm25.test.js +37 -0
  356. package/tests/engine/mcp-tools.test.js +73 -0
  357. package/tests/engine/project-initializer-mcp.test.js +99 -0
  358. package/tests/engine/query-expander.test.js +36 -0
  359. package/tests/engine/reranker.test.js +51 -0
  360. package/tests/engine/rrf.test.js +49 -0
  361. package/tests/engine/srag-prefix.test.js +47 -0
  362. package/tests/instinct-block.test.js +23 -0
  363. package/tests/mcp-config-writer.test.js +60 -0
  364. package/tests/project-initializer-new-agents.test.js +48 -0
  365. package/tests/rules/rules-manager.test.js +230 -0
  366. package/tests/well-known-builder.test.js +40 -0
  367. package/tests/wizard/integration-detector.test.js +31 -0
  368. package/tests/wizard/project-detector.test.js +51 -0
  369. package/tests/wizard/prompt-session.test.js +61 -0
  370. package/tests/wizard/prompt.test.js +16 -0
  371. package/tests/wizard/registry-embeddings.test.js +35 -0
  372. package/tests/wizard/skill-recommender.test.js +34 -0
  373. package/tests/wizard/slot-count.test.js +25 -0
  374. package/vercel.json +21 -0
@@ -0,0 +1,209 @@
1
+ ---
2
+ name: programming-with-rust
3
+ version: "1.0"
4
+ license: MIT
5
+ tags: [rust, systems-programming]
6
+ description: >
7
+ Write and review Rust code using practices from "Programming with Rust" by Donis Marshall.
8
+ Covers ownership, borrowing, lifetimes, error handling with Result/Option, traits, generics,
9
+ pattern matching, closures, fearless concurrency, and macros. Use when writing Rust, reviewing
10
+ Rust code, or learning Rust idioms. Trigger on: "Rust", "ownership", "borrow checker",
11
+ "lifetimes", "Result", "Option", "traits", "fearless concurrency", ".rs files", "cargo".
12
+ ---
13
+
14
+ # Programming with Rust Skill
15
+
16
+ Apply the practices from Donis Marshall's "Programming with Rust" to review existing code and write new Rust. This skill operates in two modes: **Review Mode** (analyze code for violations of Rust idioms) and **Write Mode** (produce safe, idiomatic Rust from scratch).
17
+
18
+ ## Reference Files
19
+
20
+ - `ref-01-fundamentals.md` — Ch 1-3: Rust model, tooling, variables, primitives, references
21
+ - `ref-02-types-strings.md` — Ch 4-5: String vs &str, formatting, Display/Debug traits
22
+ - `ref-03-control-collections.md` — Ch 6-7: Control flow, iterators, arrays, Vec, HashMap
23
+ - `ref-04-ownership-lifetimes.md` — Ch 8-10: Ownership, move semantics, borrowing, lifetimes
24
+ - `ref-05-functions-errors.md` — Ch 11-12: Functions, Result, Option, panics, custom errors
25
+ - `ref-06-structs-generics.md` — Ch 13-14: Structs, impl blocks, generics, bounds
26
+ - `ref-07-patterns-closures.md` — Ch 15-16: Pattern matching, closures, Fn/FnMut/FnOnce
27
+ - `ref-08-traits.md` — Ch 17: Trait definition, dispatch, supertraits, associated types
28
+ - `ref-09-concurrency.md` — Ch 18-19: Threads, channels, Mutex, RwLock, atomics
29
+ - `ref-10-advanced.md` — Ch 20-23: Memory, interior mutability, macros, FFI, modules
30
+
31
+ ## How to Use This Skill
32
+
33
+ **Before responding**, read the reference files relevant to the code's topic. For ownership/borrowing issues read `ref-04`. For error handling read `ref-05`. For a full review, read all files.
34
+
35
+ ---
36
+
37
+ ## Mode 1: Code Review
38
+
39
+ When the user asks you to **review** Rust code, follow this process:
40
+
41
+ ### Step 1: Read Relevant References
42
+ Identify which chapters apply. If unsure, read all reference files.
43
+
44
+ ### Step 2: Analyze the Code
45
+
46
+ **CRITICAL: First assess whether the code is already idiomatic.** If the code correctly uses patterns like `Arc<Mutex<T>>` for shared state, `.expect("reason")` for mutex locks, `&str` parameters, custom error types with `Display + Error + From`, iterator adapters like `.find().cloned()`, or proper `Result`/`?` propagation — **acknowledge these as correct and do not manufacture problems**. The goal is accurate assessment, not finding something to criticize.
47
+
48
+ Check these areas in order of severity:
49
+
50
+ 1. **Ownership & Borrowing** (Ch 8, 10): Unnecessary `.clone()` calls? Mutable borrow conflicts? Move semantics misunderstood? Cloning a single found item (e.g., `.find().cloned()`) is correct and intentional — do not flag it.
51
+ 2. **Lifetimes** (Ch 9): Missing or incorrect annotations? Can elision rules eliminate them? `'static` used where a shorter lifetime would do?
52
+ 3. **Error Handling** (Ch 12): Is `.unwrap()` used without a meaningful reason where `?` or proper matching belongs? `.expect("mutex poisoned")` with a descriptive reason string is correct idiomatic Rust — do not flag it. Are custom error types with `Display`, `Error`, and `From` implementations missing where they'd help callers?
53
+ 4. **Traits & Generics** (Ch 14, 17): Are trait bounds as narrow as possible? When a function could return a single concrete type, `impl Trait` is preferred over `Box<dyn Trait>` for zero-cost static dispatch. However, when a function **must** return one of multiple different concrete types at runtime (e.g., `if condition { Box::new(TypeA) } else { Box::new(TypeB) }`), `Box<dyn Trait>` is the correct and necessary choice — do not flag it as wrong. When reviewing code that uses `Box<dyn Trait>` for multiple-type returns, you should still **note** that if only one type were ever returned, `impl Trait` would be preferred — frame this as a general educational point, not a bug. Also note: trait methods that return `String` via `.clone()` could instead return `&str` with a lifetime annotation (`fn summary(&self) -> &str`) to avoid heap allocation — mention this as a suggestion.
54
+ 5. **Pattern Matching** (Ch 15): Are `match` arms exhaustive? Can `if let` / `while let` simplify single-arm matches? Are wildcards masking unhandled cases?
55
+ 6. **Concurrency** (Ch 18, 19): `Arc<Mutex<T>>` for shared mutable state across threads is correct idiomatic Rust — acknowledge it positively. Is shared state protected when it should be? Are channels used correctly? Note: `RwLock` is only preferable over `Mutex` when reads vastly outnumber writes — do not flag `Mutex` as wrong when `RwLock` would merely be an option.
56
+ 7. **Memory** (Ch 20): Is `RefCell` used outside of single-threaded interior mutability? Is `Box` used unnecessarily when stack allocation would work?
57
+ 8. **Idioms**: Is `for item in collection` preferred over manual indexing? Are iterator adapters (`map`, `filter`, `collect`) used over manual loops? `&str` parameters with `.to_string()` conversion at the boundary is correct — do not flag it.
58
+
59
+ ### Step 3: Report Findings
60
+
61
+ If the code is already idiomatic, lead with that assessment and cite the patterns it uses correctly (with chapter references). Then mention any genuine improvements or minor suggestions.
62
+
63
+ For each real issue, report:
64
+ - **Chapter reference** (e.g., "Ch 12: Error Handling")
65
+ - **Location** in the code
66
+ - **What's wrong** (the anti-pattern)
67
+ - **How to fix it** (the idiomatic Rust approach)
68
+ - **Priority**: Critical (safety/correctness), Important (idiom/maintainability), Suggestion (polish)
69
+
70
+ **Priority calibration:**
71
+ - Implementing `Default` alongside a `new()` constructor is a **Suggestion** (polish), not Important. It is a minor note, not a real issue.
72
+ - `Mutex` vs `RwLock` is a **Suggestion** when the existing `Mutex` is correct.
73
+ - Returning `&str` instead of `String` from a trait method is a **Suggestion** when `String` works fine.
74
+ - Never elevate suggestions to Important or Critical just to have something to say.
75
+ - When code is already idiomatic, **limit suggestions to at most one minor polish note** (e.g., `Default`). Do not pile on additional suggestions like deriving `Clone` for structs that don't need it, adding `Default` to every type, or noting `RwLock` as an option. One suggestion maximum keeps the review signal clear.
76
+
77
+ ### Step 4: Provide Fixed Code
78
+ Offer a corrected version with comments explaining each change.
79
+
80
+ ---
81
+
82
+ ## Mode 2: Writing New Code
83
+
84
+ When the user asks you to **write** new Rust code, apply these core principles:
85
+
86
+ ### Ownership & Memory Safety
87
+
88
+ 1. **Prefer borrowing over cloning** (Ch 8). Pass `&T` or `&mut T` rather than transferring ownership when the caller still needs the value. Clone only when ownership genuinely needs to be duplicated.
89
+
90
+ 2. **Respect the single-owner rule** (Ch 8). Each value has exactly one owner. When you move a value, the old binding is invalid — design data flow around this.
91
+
92
+ 3. **Use lifetime elision** (Ch 9). Annotate lifetimes only when the compiler cannot infer them. Explicit annotations are for structs holding references and functions with multiple reference parameters where elision is ambiguous.
93
+
94
+ 4. **Prefer `&str` over `String` in function parameters** (Ch 4). Accept `&str` to work with both `String` (via deref coercion) and string literals without allocation.
95
+
96
+ ### Error Handling
97
+
98
+ 5. **Return `Result<T, E>`, never panic in library code** (Ch 12). Panics are for unrecoverable programmer errors. Use `Result` for anything that can fail at runtime.
99
+
100
+ 6. **Use the `?` operator for error propagation** (Ch 12). Replace `.unwrap()` chains with `?` to propagate errors cleanly to callers.
101
+
102
+ 7. **Define custom error types for public APIs** (Ch 12). Implement `std::error::Error` and use `thiserror` or manual `impl` to give callers structured errors they can match on.
103
+
104
+ 8. **Never use `.unwrap()` in production paths** (Ch 12). Use `.expect("reason")` only in tests or where panic is truly the right response. In all other cases, handle with `match`, `if let`, or `?`.
105
+
106
+ ### Traits & Generics
107
+
108
+ 9. **Prefer `impl Trait` over `dyn Trait` for return types when a single concrete type is returned** (Ch 17). Static dispatch is zero-cost. Use `dyn Trait` (typically `Box<dyn Trait>`) only when the function must return one of multiple different concrete types at runtime — that is genuinely the correct tool and should not be changed to `impl Trait`.
109
+
110
+ 10. **Use trait bounds instead of concrete types** (Ch 14). `fn process<T: Display + Debug>(item: T)` is more reusable than accepting a concrete type.
111
+
112
+ 11. **Implement standard traits** (Ch 17). Derive `Debug`, `Clone`, `PartialEq` where appropriate. Implement `Display` for user-facing output, `From`/`Into` for conversions.
113
+
114
+ ### Pattern Matching
115
+
116
+ 12. **Use `match` for exhaustive handling** (Ch 15). The compiler enforces exhaustiveness — treat it as a feature, not a burden.
117
+
118
+ 13. **Use `if let` for single-variant matching** (Ch 15). `if let Some(x) = opt { }` is cleaner than a two-arm `match` when you only care about one case.
119
+
120
+ 14. **Destructure in function parameters** (Ch 15). `fn process(&Point { x, y }: &Point)` avoids manual field access inside the body.
121
+
122
+ ### Concurrency
123
+
124
+ 15. **Use channels for message passing** (Ch 18). Prefer `std::sync::mpsc` channels over shared mutable state when threads can communicate by value.
125
+
126
+ 16. **Wrap shared state in `Arc<Mutex<T>>`** (Ch 19). `Arc` for shared ownership across threads, `Mutex` for mutual exclusion. `Arc<Mutex<T>>` is the correct default — only suggest `RwLock` if there is evidence that reads vastly outnumber writes and contention is a measured concern.
127
+
128
+ 17. **Prefer `Mutex::lock().unwrap()` with `.expect()`** (Ch 19). Poisoned mutexes indicate a panic in another thread — `.expect("mutex poisoned")` makes this explicit.
129
+
130
+ ### Code Structure Template
131
+
132
+ ```rust
133
+ use std::fmt;
134
+
135
+ /// Domain error type for public APIs (Ch 12)
136
+ #[derive(Debug)]
137
+ pub enum AppError {
138
+ NotFound(String),
139
+ InvalidInput(String),
140
+ Io(std::io::Error),
141
+ }
142
+
143
+ impl fmt::Display for AppError {
144
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
145
+ match self {
146
+ AppError::NotFound(msg) => write!(f, "not found: {msg}"),
147
+ AppError::InvalidInput(msg) => write!(f, "invalid input: {msg}"),
148
+ AppError::Io(e) => write!(f, "I/O error: {e}"),
149
+ }
150
+ }
151
+ }
152
+
153
+ impl std::error::Error for AppError {}
154
+
155
+ impl From<std::io::Error> for AppError {
156
+ fn from(e: std::io::Error) -> Self {
157
+ AppError::Io(e)
158
+ }
159
+ }
160
+
161
+ /// Accept &str, not String (Ch 4)
162
+ pub fn find_user(name: &str) -> Result<User, AppError> {
163
+ // Use ? for propagation (Ch 12)
164
+ let data = load_data()?;
165
+ data.iter()
166
+ .find(|u| u.name == name)
167
+ .cloned() // clone only the found item (Ch 8)
168
+ .ok_or_else(|| AppError::NotFound(name.to_string()))
169
+ }
170
+
171
+ /// Derive standard traits (Ch 17)
172
+ #[derive(Debug, Clone, PartialEq)]
173
+ pub struct User {
174
+ pub name: String,
175
+ pub role: Role,
176
+ }
177
+
178
+ /// Enum for valid states (Ch 15)
179
+ #[derive(Debug, Clone, PartialEq)]
180
+ pub enum Role {
181
+ Admin,
182
+ Viewer,
183
+ Editor,
184
+ }
185
+ ```
186
+
187
+ ---
188
+
189
+ ## Priority of Practices by Impact
190
+
191
+ ### Critical (Safety & Correctness)
192
+ - Ch 8: Understand ownership — moving vs borrowing, no use-after-move
193
+ - Ch 10: One mutable borrow OR many immutable borrows — never both
194
+ - Ch 12: Never `.unwrap()` in production; use `Result` and `?`
195
+ - Ch 19: Always protect shared mutable state with `Mutex` or `RwLock`
196
+
197
+ ### Important (Idiom & Maintainability)
198
+ - Ch 4: Prefer `&str` params over `String`
199
+ - Ch 9: Rely on lifetime elision; annotate only when required
200
+ - Ch 12: Custom error types for public APIs
201
+ - Ch 14/17: Trait bounds over concrete types; `impl Trait` over `dyn Trait` when returning a single concrete type; `Box<dyn Trait>` is correct when multiple concrete types may be returned
202
+ - Ch 15: Exhaustive `match`; use `if let` for single-arm cases
203
+ - Ch 17: Derive/implement standard traits (`Debug`, `Display`, `From`)
204
+
205
+ ### Suggestions (Polish)
206
+ - Ch 6: Use iterator adapters (`map`, `filter`, `flat_map`) over manual loops
207
+ - Ch 16: Use closures with `move` when capturing environment across thread boundaries
208
+ - Ch 20: Prefer stack allocation; use `Box` only when size is unknown at compile time
209
+ - Ch 21: Use `derive` macros before writing manual `impl` blocks
@@ -0,0 +1,37 @@
1
+ {
2
+ "evals": [
3
+ {
4
+ "id": "eval-01-unwrap-clone-ownership",
5
+ "prompt": "Review this Rust code:\n\n```rust\nfn process_users(users: Vec<String>) -> Vec<String> {\n let copy = users.clone();\n let mut result = Vec::new();\n for i in 0..copy.len() {\n result.push(copy[i].clone());\n }\n result\n}\n\nfn read_file(path: String) -> String {\n std::fs::read_to_string(path).unwrap()\n}\n\nfn find(map: HashMap<String, u32>, key: String) -> u32 {\n map.get(&key).unwrap().clone()\n}\n```",
6
+ "expectations": [
7
+ "Flag Ch 8: users.clone() is unnecessary — borrow &[String] instead of taking ownership of Vec<String>",
8
+ "Flag Ch 6: manual index loop should be replaced with iterator adapters (.iter().cloned().collect())",
9
+ "Flag Ch 12: .unwrap() in read_file will panic on I/O error — should return Result<String, std::io::Error> and use ?",
10
+ "Flag Ch 8: find takes owned HashMap — borrows &HashMap<String, u32> instead",
11
+ "Flag Ch 12: .unwrap() in find panics on missing key — return Option<u32> or Result",
12
+ "Provide corrected versions using &[String], iterators, Result, ?, and &HashMap"
13
+ ]
14
+ },
15
+ {
16
+ "id": "eval-02-subtle-trait-dispatch",
17
+ "prompt": "Review this Rust code:\n\n```rust\nuse std::fmt;\n\ntrait Summarize {\n fn summary(&self) -> String;\n}\n\nstruct Article { title: String, body: String }\nstruct Tweet { content: String }\n\nimpl Summarize for Article {\n fn summary(&self) -> String { self.title.clone() }\n}\nimpl Summarize for Tweet {\n fn summary(&self) -> String { self.content.clone() }\n}\n\n// Returns a trait object\nfn make_summary(is_article: bool) -> Box<dyn Summarize> {\n if is_article {\n Box::new(Article { title: String::from(\"news\"), body: String::from(\"...\") })\n } else {\n Box::new(Tweet { content: String::from(\"hello\") })\n }\n}\n\n// Takes a trait object\nfn print_all(items: &Vec<Box<dyn Summarize>>) {\n for item in items {\n println!(\"{}\", item.summary());\n }\n}\n```",
18
+ "expectations": [
19
+ "Note that Box<dyn Summarize> in make_summary is actually appropriate here because the function must return one of two different concrete types — this is a valid use of dynamic dispatch (Ch 17)",
20
+ "Flag &Vec<Box<dyn Summarize>> in print_all — prefer &[Box<dyn Summarize>] (a slice reference is more general than a Vec reference)",
21
+ "Suggest that if only one type were returned, impl Summarize would be preferred over Box<dyn Summarize> for zero-cost static dispatch (Ch 17)",
22
+ "Note .clone() in summary() implementations — title/body could be returned as &str with lifetime annotation to avoid allocation (Ch 8, 9)",
23
+ "Do NOT flag the dynamic dispatch in make_summary as wrong — it is the correct choice when returning heterogeneous types"
24
+ ]
25
+ },
26
+ {
27
+ "id": "eval-03-idiomatic-rust-already-good",
28
+ "prompt": "Review this Rust code:\n\n```rust\nuse std::fmt;\nuse std::sync::{Arc, Mutex};\n\n#[derive(Debug)]\npub enum StoreError {\n NotFound(String),\n Io(std::io::Error),\n}\n\nimpl fmt::Display for StoreError {\n fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n match self {\n StoreError::NotFound(k) => write!(f, \"key not found: {k}\"),\n StoreError::Io(e) => write!(f, \"io error: {e}\"),\n }\n }\n}\n\nimpl std::error::Error for StoreError {}\n\nimpl From<std::io::Error> for StoreError {\n fn from(e: std::io::Error) -> Self { StoreError::Io(e) }\n}\n\n#[derive(Debug, Clone)]\npub struct Record {\n pub key: String,\n pub value: String,\n}\n\npub struct Store {\n records: Arc<Mutex<Vec<Record>>>,\n}\n\nimpl Store {\n pub fn new() -> Self {\n Store { records: Arc::new(Mutex::new(Vec::new())) }\n }\n\n pub fn insert(&self, key: &str, value: &str) {\n let mut records = self.records.lock().expect(\"mutex poisoned\");\n records.push(Record { key: key.to_string(), value: value.to_string() });\n }\n\n pub fn find(&self, key: &str) -> Result<Record, StoreError> {\n let records = self.records.lock().expect(\"mutex poisoned\");\n records\n .iter()\n .find(|r| r.key == key)\n .cloned()\n .ok_or_else(|| StoreError::NotFound(key.to_string()))\n }\n}\n```",
29
+ "expectations": [
30
+ "Recognize this code is idiomatic Rust — do NOT manufacture issues",
31
+ "Acknowledge: custom StoreError with Display + Error + From (Ch 12), Arc<Mutex<T>> for shared state (Ch 19), &str parameters with .to_string() conversion (Ch 4), iterator .find().cloned() over manual loops (Ch 6), .expect('mutex poisoned') with reason string (Ch 19)",
32
+ "At most note that Default could be derived or implemented for Store alongside new()",
33
+ "Do not flag .cloned() on the found record — cloning a single found item is correct and intentional"
34
+ ]
35
+ }
36
+ ]
37
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "pass_rate": 1,
3
+ "passed": 15,
4
+ "total": 15,
5
+ "baseline_pass_rate": 0.733,
6
+ "baseline_passed": 11,
7
+ "baseline_total": 15,
8
+ "delta": 0.267,
9
+ "model": "default",
10
+ "evals_run": 3,
11
+ "date": "2026-03-28",
12
+ "non_standard_provider": true
13
+ }
@@ -0,0 +1,107 @@
1
+ # After: Programming with Rust
2
+
3
+ The same service rewritten with idiomatic Rust — proper ownership, Result-based error handling, borrowing over cloning, iterator adapters, and trait bounds.
4
+
5
+ ```rust
6
+ use std::collections::HashMap;
7
+ use std::fmt;
8
+ use std::sync::{Arc, Mutex};
9
+
10
+ // Custom error type — callers can match on variants (Ch 12)
11
+ #[derive(Debug)]
12
+ pub enum ConfigError {
13
+ Io(std::io::Error),
14
+ UserNotFound(String),
15
+ }
16
+
17
+ impl fmt::Display for ConfigError {
18
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19
+ match self {
20
+ ConfigError::Io(e) => write!(f, "I/O error: {e}"),
21
+ ConfigError::UserNotFound(name) => write!(f, "user not found: {name}"),
22
+ }
23
+ }
24
+ }
25
+
26
+ impl std::error::Error for ConfigError {}
27
+
28
+ impl From<std::io::Error> for ConfigError {
29
+ fn from(e: std::io::Error) -> Self {
30
+ ConfigError::Io(e)
31
+ }
32
+ }
33
+
34
+ // &str instead of String — works with both literals and String via deref coercion (Ch 4)
35
+ // Returns Result — caller decides how to handle failure (Ch 12)
36
+ fn load_config(path: &str) -> Result<String, ConfigError> {
37
+ let content = std::fs::read_to_string(path)?; // ? propagates I/O error (Ch 12)
38
+ Ok(content)
39
+ }
40
+
41
+ // Borrows the map — no clone, caller retains ownership (Ch 8, 10)
42
+ fn get_user<'a>(users: &'a HashMap<String, String>, name: &str) -> Result<&'a str, ConfigError> {
43
+ users
44
+ .get(name)
45
+ .map(|s| s.as_str())
46
+ .ok_or_else(|| ConfigError::UserNotFound(name.to_string()))
47
+ }
48
+
49
+ // Iterator adapters replace manual index loop (Ch 6)
50
+ fn active_names(users: &[(String, bool)]) -> Vec<&str> {
51
+ users
52
+ .iter()
53
+ .filter(|(_, active)| *active)
54
+ .map(|(name, _)| name.as_str())
55
+ .collect()
56
+ }
57
+
58
+ // Safe shared counter with Arc<Mutex<T>> (Ch 19)
59
+ fn make_counter() -> Arc<Mutex<u32>> {
60
+ Arc::new(Mutex::new(0))
61
+ }
62
+
63
+ fn increment(counter: &Arc<Mutex<u32>>) {
64
+ let mut count = counter.lock().expect("mutex poisoned");
65
+ *count += 1;
66
+ }
67
+
68
+ // Trait bound instead of concrete type — accepts anything Display (Ch 14, 17)
69
+ fn print_item(item: &impl fmt::Display) {
70
+ println!("{item}");
71
+ }
72
+
73
+ fn main() -> Result<(), ConfigError> {
74
+ let config = load_config("config.toml")?; // ? instead of unwrap (Ch 12)
75
+ println!("{config}");
76
+
77
+ let mut users = HashMap::new();
78
+ users.insert(String::from("alice"), String::from("admin"));
79
+
80
+ // Borrow users — still usable after the call (Ch 8)
81
+ let role = get_user(&users, "alice")?;
82
+ println!("{role}");
83
+ println!("{users:?}"); // still valid — was only borrowed
84
+
85
+ let items = vec![
86
+ (String::from("alice"), true),
87
+ (String::from("bob"), false),
88
+ ];
89
+ let names = active_names(&items);
90
+ println!("{names:?}");
91
+
92
+ let counter = make_counter();
93
+ increment(&counter);
94
+ println!("count: {}", counter.lock().unwrap());
95
+
96
+ Ok(())
97
+ }
98
+ ```
99
+
100
+ **Key improvements:**
101
+ - `ConfigError` gives callers structured, matchable errors (Ch 12)
102
+ - `?` replaces `.unwrap()` for clean error propagation (Ch 12)
103
+ - `&str` / `&HashMap` parameters borrow instead of consuming (Ch 4, 8, 10)
104
+ - Iterator adapters replace manual index loops (Ch 6)
105
+ - `Arc<Mutex<T>>` replaces `unsafe static mut` for safe shared state (Ch 19)
106
+ - `impl fmt::Display` trait bound instead of concrete `String` parameter (Ch 14, 17)
107
+ - `main()` returns `Result` so errors surface cleanly (Ch 12)
@@ -0,0 +1,59 @@
1
+ # Before: Programming with Rust
2
+
3
+ A user service with common Rust anti-patterns — ownership misuse, panic-prone error handling, unnecessary cloning, and poor trait design.
4
+
5
+ ```rust
6
+ use std::collections::HashMap;
7
+
8
+ // No custom error type — callers can't match on failures
9
+ fn load_config(path: String) -> String { // takes owned String unnecessarily
10
+ std::fs::read_to_string(path).unwrap() // panics on any I/O error
11
+ }
12
+
13
+ // Clones entire map just to read it
14
+ fn get_user(users: HashMap<String, String>, name: String) -> String {
15
+ let users_copy = users.clone(); // unnecessary clone of the whole map
16
+ match users_copy.get(&name) {
17
+ Some(user) => user.clone(),
18
+ None => String::from("unknown"), // silently returns fallback — hides missing users
19
+ }
20
+ }
21
+
22
+ // Accumulates with a manual loop instead of iterator adapters
23
+ fn active_names(users: Vec<(String, bool)>) -> Vec<String> {
24
+ let mut result = Vec::new();
25
+ for i in 0..users.len() {
26
+ if users[i].1 == true {
27
+ result.push(users[i].0.clone());
28
+ }
29
+ }
30
+ result
31
+ }
32
+
33
+ // Shared state with no synchronization
34
+ static mut COUNTER: u32 = 0;
35
+
36
+ fn increment() {
37
+ unsafe {
38
+ COUNTER += 1; // data race — undefined behavior in concurrent code
39
+ }
40
+ }
41
+
42
+ // Concrete type parameter instead of trait bound
43
+ fn print_user(user: String) {
44
+ println!("{}", user);
45
+ }
46
+
47
+ fn main() {
48
+ let config = load_config(String::from("config.toml"));
49
+ println!("{}", config);
50
+
51
+ let mut users = HashMap::new();
52
+ users.insert(String::from("alice"), String::from("admin"));
53
+
54
+ // Moves users into get_user — can't use it after
55
+ let name = get_user(users, String::from("alice"));
56
+ println!("{}", name);
57
+ // println!("{:?}", users); // would fail: users was moved
58
+ }
59
+ ```
@@ -0,0 +1,152 @@
1
+ # Programming with Rust — Chapter Reference
2
+
3
+ All 23 chapters from Donis Marshall's "Programming with Rust" with key topics and priority levels.
4
+
5
+ ## Ch 1: Introduction to Rust
6
+ **Key topics:** Functional programming, expression-oriented, pattern-oriented, safeness, ownership, lifetimes, fearless concurrency, zero-cost abstraction, Rust terminology, tools
7
+ **Priority:** Foundation
8
+
9
+ ## Ch 2: Getting Started
10
+ **Key topics:** Cargo, crates, library vs binary, `main` function, command-line arguments, comments, `rustup`
11
+ **Priority:** Foundation
12
+
13
+ ## Ch 3: Variables
14
+ **Key topics:** Immutability by default (`let` vs `let mut`), integer types, overflow behavior, floating point, boolean, char, pointers, references, operators
15
+ **Priority:** Important — immutability by default is a key Rust safety idiom
16
+
17
+ ## Ch 4: Strings
18
+ **Key topics:** `&str` (string slice, stack) vs `String` (heap-allocated, owned), deref coercion, `format!`, helpful string functions
19
+ **Idiom:** Accept `&str` in function parameters — `String` derefs to `&str` automatically
20
+ **Priority:** Important
21
+
22
+ ## Ch 5: Console
23
+ **Key topics:** `println!`, positional/variable/named arguments, padding/alignment, `Display` trait, `Debug` trait, `format!`, `write!`
24
+ **Priority:** Suggestion
25
+
26
+ ## Ch 6: Control Flow
27
+ **Key topics:** `if` as expression, `while`, `for`/`in` (iterator-based), `loop`, `break`/`continue`, loop labels, `Iterator` trait
28
+ **Idiom:** Use `for item in collection` over manual indexing; use iterator adapters over manual loops
29
+ **Priority:** Important
30
+
31
+ ## Ch 7: Collections
32
+ **Key topics:** Arrays (fixed-size, stack), slices, Vecs (heap, growable), multidimensional, `HashMap` (entry API, iteration, update)
33
+ **Priority:** Important
34
+
35
+ ## Ch 8: Ownership
36
+ **Key topics:** Stack vs heap, shallow vs deep copy, move semantics, borrow, copy semantics, `Clone` trait, `Copy` trait
37
+ **Critical rules:**
38
+ - Each value has exactly one owner
39
+ - When owner goes out of scope, value is dropped
40
+ - Move transfers ownership — old binding is invalid
41
+ - `Copy` types (primitives) are copied instead of moved
42
+ **Priority:** Critical
43
+
44
+ ## Ch 9: Lifetimes
45
+ **Key topics:** Lifetime annotation syntax (`'a`), lifetime elision rules, function headers, complex lifetimes, `'static`, structs/methods with lifetimes, subtyping, anonymous lifetimes, generics and lifetimes
46
+ **Idiom:** Rely on elision; annotate only when compiler cannot infer (multiple reference params with ambiguous output lifetime)
47
+ **Priority:** Critical
48
+
49
+ ## Ch 10: References
50
+ **Key topics:** Declaration, borrowing, dereferencing, comparing references, reference notation, mutability, limits to multiple borrowers
51
+ **Critical rules:**
52
+ - At any time: one `&mut T` OR any number of `&T` — never both
53
+ - References must not outlive the referent
54
+ **Priority:** Critical
55
+
56
+ ## Ch 11: Functions
57
+ **Key topics:** Function definition, parameters, return values, `const fn`, nested functions, function pointers, function aliases
58
+ **Priority:** Important
59
+
60
+ ## Ch 12: Error Handling
61
+ **Key topics:** `Result<T, E>`, `Option<T>`, panics, `panic!` macro, handling panics, `.unwrap()`, `.expect()`, `?` operator, `match` on Result/Option, `.map()`, rich errors, custom error types
62
+ **Critical rules:**
63
+ - Library code: always `Result`, never panic
64
+ - Use `?` for propagation, not `.unwrap()`
65
+ - Define custom error types implementing `std::error::Error`
66
+ - Implement `From<E>` for automatic `?` conversion
67
+ **Priority:** Critical
68
+
69
+ ## Ch 13: Structures
70
+ **Key topics:** Struct definition, alternate initialization, move semantics with structs, mutability, methods (`&self`, `&mut self`, `self`), associated functions (`new`), `impl` blocks, operator overloading, tuple structs, unit-like structs
71
+ **Priority:** Important
72
+
73
+ ## Ch 14: Generics
74
+ **Key topics:** Generic functions, trait bounds, `where` clause, generic structs, associated functions, generic enums, generic traits, explicit specialization
75
+ **Idiom:** Use `where` clause for complex bounds; prefer narrowest possible bounds
76
+ **Priority:** Important
77
+
78
+ ## Ch 15: Patterns
79
+ **Key topics:** `let` destructuring, wildcards (`_`), complex patterns, ownership in patterns, irrefutable patterns, ranges, multiple patterns (`|`), control flow patterns, struct destructuring, function parameter patterns, `match` expressions, match guards
80
+ **Idiom:** `match` is exhaustive — let the compiler enforce all cases; use `if let` for single-variant matches
81
+ **Priority:** Important
82
+
83
+ ## Ch 16: Closures
84
+ **Key topics:** Closure syntax, captured variables, closures as arguments/return values, `Fn` (immutable borrow), `FnMut` (mutable borrow), `FnOnce` (move/consume), `move` keyword, `impl` keyword for return types
85
+ **Idiom:** Use `move` closures when passing to threads to transfer ownership of captured values
86
+ **Priority:** Important
87
+
88
+ ## Ch 17: Traits
89
+ **Key topics:** Trait definition, default functions, marker traits (`Send`, `Sync`), associated functions, associated types, extension methods, fully qualified syntax, supertraits, static dispatch (`impl Trait`), dynamic dispatch (`dyn Trait`), enums and traits
90
+ **Critical rules:**
91
+ - Prefer `impl Trait` (static, zero-cost) over `dyn Trait` (runtime overhead via vtable)
92
+ - Use `dyn Trait` only when returning heterogeneous types or building plugin systems
93
+ **Priority:** Critical
94
+
95
+ ## Ch 18: Threads 1
96
+ **Key topics:** Synchronous vs asynchronous calls, `std::thread::spawn`, thread type, `Builder`, CSP (Communicating Sequential Process), async/sync/rendezvous channels (`mpsc`), `try_recv`, store example
97
+ **Idiom:** Prefer message passing (channels) over shared state when possible
98
+ **Priority:** Important
99
+
100
+ ## Ch 19: Threads 2
101
+ **Key topics:** `Mutex<T>`, nonscoped mutex, mutex poisoning, `RwLock<T>`, condition variables (`Condvar`), atomic operations (`AtomicUsize`, etc.), store/load, fetch-and-modify, compare-and-exchange
102
+ **Idiom:** Use `Arc<Mutex<T>>` for shared mutable state; `Arc<RwLock<T>>` for read-heavy workloads
103
+ **Priority:** Critical
104
+
105
+ ## Ch 20: Memory
106
+ **Key topics:** Stack vs heap allocation, static values, `Box<T>` (heap allocation), interior mutability pattern, `RefCell<T>` (runtime borrow checking, single-threaded), `OnceCell<T>` (lazy initialization)
107
+ **Idiom:** Stack-allocate by default; use `Box` only when size is unknown at compile time or for recursive types
108
+ **Priority:** Important
109
+
110
+ ## Ch 21: Macros
111
+ **Key topics:** Tokens, declarative macros (`macro_rules!`), repetition, multiple matchers, procedural macros (derive, attribute, function-like), `#[derive(...)]`
112
+ **Idiom:** Use `#[derive]` before writing manual `impl` blocks; write `macro_rules!` for repeated patterns
113
+ **Priority:** Suggestion
114
+
115
+ ## Ch 22: Interoperability
116
+ **Key topics:** FFI, `extern "C"`, `unsafe` blocks, `libc` crate, structs across FFI, `bindgen` (C → Rust), `cbindgen` (Rust → C)
117
+ **Priority:** Suggestion (only when needed)
118
+
119
+ ## Ch 23: Modules
120
+ **Key topics:** Module items, `pub` visibility, module files, `path` attribute, functions and modules, `crate`/`super`/`self` keywords, legacy module model
121
+ **Idiom:** Organize by domain, not by type; keep `pub` surface minimal; use `pub(crate)` for internal-only APIs
122
+ **Priority:** Important
123
+
124
+ ---
125
+
126
+ ## Priority Summary
127
+
128
+ **Critical (understand deeply before writing any Rust)**
129
+ - Ch 8: Ownership and move semantics
130
+ - Ch 9: Lifetimes and elision
131
+ - Ch 10: Borrowing rules (one `&mut` OR many `&`)
132
+ - Ch 12: Error handling with Result, ?, custom errors
133
+ - Ch 17: Trait dispatch (impl vs dyn)
134
+ - Ch 19: Thread safety with Mutex/RwLock/Arc
135
+
136
+ **Important (apply consistently)**
137
+ - Ch 3: Immutability by default
138
+ - Ch 4: `&str` vs `String`
139
+ - Ch 6: Iterator-based loops
140
+ - Ch 11: Function design
141
+ - Ch 13: Structs and impl blocks
142
+ - Ch 14: Generics and bounds
143
+ - Ch 15: Exhaustive pattern matching
144
+ - Ch 16: Closures and move semantics
145
+ - Ch 18: Channels for concurrency
146
+ - Ch 20: Stack vs heap, RefCell
147
+ - Ch 23: Module visibility
148
+
149
+ **Suggestion (apply when relevant)**
150
+ - Ch 5: Formatting and Display/Debug
151
+ - Ch 21: Macros and derive
152
+ - Ch 22: FFI/interop