From 4bb3a4600abe35a1fdfffc3b6494c683bdcd44d1 Mon Sep 17 00:00:00 2001 From: Al Rifat Sabbir <150162343+alrifatsabbir@users.noreply.github.com> Date: Sun, 12 Apr 2026 15:30:00 +0600 Subject: [PATCH] docs: start Bengali (bn) translation (#3127) **This PR starts the Bengali (bn) translation for Comprehensive Rust.** - Initialized po/bn.po with translations for the summary and introduction. --------- Co-authored-by: Martin Geisler --- po/bn.po | 26502 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 20199 insertions(+), 6303 deletions(-) diff --git a/po/bn.po b/po/bn.po index f846d30d..4562ef80 100644 --- a/po/bn.po +++ b/po/bn.po @@ -1,16 +1,15 @@ msgid "" msgstr "" "Project-Id-Version: Comprehensive Rust đŸĻ€\n" -"POT-Creation-Date: 2024-03-03T20:37:57+05:30\n" -"PO-Revision-Date: \n" -"Last-Translator: Abhik Banerjee \n" -"Language-Team: abhik-99, noob_rasel\n" -"Language: bn\n" +"POT-Creation-Date: 2026-03-18T01:02:13+06:00\n" +"PO-Revision-Date: 2026-03-18 01:03+0600\n" +"Last-Translator: \n" +"Language-Team: Bengali <(nothing)>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n==0 || n==1);\n" -"X-Generator: Poedit 3.4.2\n" +"Language: bn\n" +"Plural-Forms: nplurals=1; plural=0;\n" #: src/SUMMARY.md src/index.md msgid "Welcome to Comprehensive Rust đŸĻ€" @@ -18,15 +17,15 @@ msgstr "Comprehensive Rust đŸĻ€ āĻ āφāĻĒāύāĻžāϕ⧇ āĻ¸ā§āĻŦāĻžāĻ—āϤāĻŽ" #: src/SUMMARY.md src/running-the-course.md msgid "Running the Course" -msgstr "āϕ⧋āĻ°ā§āϏ āϚāĻžāϞāĻžāύ⧋" +msgstr "āϕ⧋āĻ°ā§āϏāϟāĻŋ āĻĒāϰāĻŋāϚāĻžāϞāύāĻž" #: src/SUMMARY.md src/running-the-course/course-structure.md msgid "Course Structure" -msgstr "āϕ⧋āĻ°ā§āϏ āĻāϰ āĻ—āĻ āύ" +msgstr "āϕ⧋āĻ°ā§āϏ⧇āϰ āĻ—āĻ āύ" #: src/SUMMARY.md src/running-the-course/keyboard-shortcuts.md msgid "Keyboard Shortcuts" -msgstr "āĻ•āĻŋāĻŦā§‹āĻ°ā§āĻĄ āĻļāĻ°ā§āϟāĻ•āĻžāϟ" +msgstr "āϕ⧀āĻŦā§‹āĻ°ā§āĻĄ āĻļāĻ°ā§āϟāĻ•āĻžāϟ" #: src/SUMMARY.md src/running-the-course/translations.md msgid "Translations" @@ -38,1197 +37,2215 @@ msgstr "Cargo āĻŦā§āϝāĻŦāĻšāĻžāϰ" #: src/SUMMARY.md msgid "Rust Ecosystem" -msgstr "āϰāĻžāĻ¸ā§āϟ āχāϕ⧋āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽ" +msgstr "Rust āχāϕ⧋āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽ" #: src/SUMMARY.md msgid "Code Samples" -msgstr "āϕ⧋āĻĄ āύāĻŽā§āύāĻž" +msgstr "āϕ⧋āĻĄ āύāĻŽā§āύāĻžāϏāĻŽā§‚āĻš" #: src/SUMMARY.md msgid "Running Cargo Locally" -msgstr "Cargo Locally āϚāĻžāϞāĻžāύ⧋ āĻšāĻšā§āϛ⧇" +msgstr "āϞ⧋āĻ•āĻžāϞ āĻŽā§‡āĻļāĻŋāύ⧇ Cargo āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž" #: src/SUMMARY.md msgid "Day 1: Morning" msgstr "āĻĒā§āϰāĻĨāĻŽ āĻĻāĻŋāύāσ āϏāĻ•āĻžāϞ" -#: src/SUMMARY.md +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/welcome-day-1.md src/welcome-day-2.md src/welcome-day-3.md +#: src/welcome-day-4.md src/concurrency/welcome-async.md msgid "Welcome" msgstr "āĻ¸ā§āĻŦāĻžāĻ—āϤāĻŽ" -#: src/SUMMARY.md src/hello-world.md src/types-and-values/hello-world.md +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/welcome-day-1.md src/hello-world.md src/types-and-values.md +#: src/types-and-values/hello-world.md msgid "Hello, World" -msgstr "āĻšā§āϝāĻžāϞ⧋ āĻ“ā§ŸāĻžāĻ°ā§āĻ˛ā§āĻĄ" +msgstr "āĻšā§āϝāĻžāϞ⧋, āĻ“ā§ŸāĻžāĻ°ā§āĻ˛ā§āĻĄ" -#: src/SUMMARY.md src/hello-world/what-is-rust.md +#: src/SUMMARY.md src/hello-world.md src/hello-world/what-is-rust.md msgid "What is Rust?" -msgstr "āϰāĻžāĻ¸ā§āϟ āĻ•āĻŋ?" +msgstr "Rust āĻ•āĻŋ?" -#: src/SUMMARY.md src/hello-world/benefits.md +#: src/SUMMARY.md src/hello-world.md src/hello-world/benefits.md msgid "Benefits of Rust" -msgstr "āϰāĻžāĻ¸ā§āϟ āĻāϰ āϏ⧁āĻŦāĻŋāϧāĻž" +msgstr "Rust āĻāϰ āϏ⧁āĻŦāĻŋāϧāĻžāϏāĻŽā§‚āĻš" -#: src/SUMMARY.md src/hello-world/playground.md +#: src/SUMMARY.md src/hello-world.md src/hello-world/playground.md msgid "Playground" -msgstr "āĻĒā§āϞ⧇āĻ—ā§āϰāĻžāωāĻ¨ā§āĻĄ" +msgstr "āĻĒā§āϞ⧇āĻ—ā§āϰāĻžāωāĻ¨ā§āĻĄ (Playground)" -#: src/SUMMARY.md src/types-and-values.md +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/welcome-day-1.md src/types-and-values.md msgid "Types and Values" -msgstr "āϟāĻžāχāĻĒ āĻāĻŦāĻ‚ āĻŽāĻžāύ" +msgstr "" -#: src/SUMMARY.md src/types-and-values/variables.md +#: src/SUMMARY.md src/types-and-values.md src/types-and-values/variables.md msgid "Variables" -msgstr "āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ" +msgstr "" -#: src/SUMMARY.md src/types-and-values/values.md +#: src/SUMMARY.md src/types-and-values.md src/types-and-values/values.md msgid "Values" -msgstr "āĻŽāĻžāύ" +msgstr "" -#: src/SUMMARY.md src/types-and-values/arithmetic.md +#: src/SUMMARY.md src/types-and-values.md src/types-and-values/arithmetic.md msgid "Arithmetic" -msgstr "āĻ…āĻ™ā§āĻ•āĻļāĻžāĻ¸ā§āĻ¤ā§āϰ" +msgstr "" -#: src/SUMMARY.md src/types-and-values/strings.md -msgid "Strings" -msgstr "Strings" - -#: src/SUMMARY.md src/types-and-values/inference.md +#: src/SUMMARY.md src/types-and-values.md src/types-and-values/inference.md msgid "Type Inference" -msgstr "āϟāĻžāχāĻĒ āĻ…āύ⧁āĻŽāĻžāύ" +msgstr "" -#: src/SUMMARY.md src/types-and-values/exercise.md +#: src/SUMMARY.md src/types-and-values.md src/types-and-values/exercise.md msgid "Exercise: Fibonacci" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ⧀: āĻĢāĻŋāĻŦā§‹āύāĻžāĻšā§āϚāĻŋ" +msgstr "" #: src/SUMMARY.md src/types-and-values/solution.md #: src/control-flow-basics/solution.md src/tuples-and-arrays/solution.md #: src/references/solution.md src/user-defined-types/solution.md #: src/pattern-matching/solution.md src/methods-and-traits/solution.md -#: src/generics/solution.md src/std-types/solution.md +#: src/generics/solution.md src/closures/solution.md src/std-types/solution.md #: src/std-traits/solution.md src/memory-management/solution.md -#: src/smart-pointers/solution.md src/borrowing/solution.md -#: src/slices-and-lifetimes/solution.md src/iterators/solution.md -#: src/modules/solution.md src/testing/solution.md +#: src/smart-pointers/solution.md src/lifetimes/solution.md +#: src/iterators/solution.md src/modules/solution.md src/testing/solution.md #: src/error-handling/solution.md src/unsafe-rust/solution.md msgid "Solution" -msgstr "āϏāĻŽāĻžāϧāĻžāύ" +msgstr "" + +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/welcome-day-1.md src/control-flow-basics.md +msgid "Control Flow Basics" +msgstr "" #: src/SUMMARY.md src/control-flow-basics.md -msgid "Control Flow Basics" -msgstr "āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽā§‡āϰ āĻĒā§āϰāĻŦāĻžāĻš āύāĻŋāϝāĻŧāĻ¨ā§āĻ¤ā§āϰāϪ⧇āϰ āĻŽā§ŒāϞāĻŋāĻ• āĻŦāĻŋāώāϝāĻŧ" +#: src/control-flow-basics/blocks-and-scopes.md +msgid "Blocks and Scopes" +msgstr "" #: src/SUMMARY.md msgid "`if` Expressions" -msgstr "if āĻ…āĻ­āĻŋāĻŦā§āϝāĻ•ā§āϤāĻŋ" +msgstr "" -#: src/SUMMARY.md src/control-flow-basics/loops.md +#: src/SUMMARY.md src/control-flow-basics/match.md +msgid "`match` Expressions" +msgstr "" + +#: src/SUMMARY.md src/control-flow-basics.md src/control-flow-basics/loops.md msgid "Loops" -msgstr "āϞ⧁āĻĒā§āϏ" +msgstr "" #: src/SUMMARY.md src/control-flow-basics/loops/for.md msgid "`for`" -msgstr "`for`" +msgstr "" #: src/SUMMARY.md src/control-flow-basics/loops/loop.md msgid "`loop`" -msgstr "`loop`" +msgstr "" #: src/SUMMARY.md src/control-flow-basics/break-continue.md msgid "`break` and `continue`" -msgstr "`break` āĻāĻŦāĻ‚ `continue`" +msgstr "" #: src/SUMMARY.md src/control-flow-basics/break-continue/labels.md msgid "Labels" -msgstr "āϞ⧇āĻŦ⧇āϞ" +msgstr "" -#: src/SUMMARY.md src/control-flow-basics/blocks-and-scopes.md -msgid "Blocks and Scopes" -msgstr "āĻŦā§āϞāĻ• āĻāĻŦāĻ‚ āĻ¸ā§āϕ⧋āĻĒ" - -#: src/SUMMARY.md src/control-flow-basics/blocks-and-scopes/scopes.md -msgid "Scopes and Shadowing" -msgstr "āĻĒā§āϰāϏāĻžāϰ āĻāĻŦāĻ‚ āĻĒā§āϰāϤāĻŋāĻšā§āĻ›āĻžāϝāĻŧāĻž āĻ•āϰāĻž" - -#: src/SUMMARY.md src/control-flow-basics/functions.md +#: src/SUMMARY.md src/control-flow-basics.md +#: src/control-flow-basics/functions.md msgid "Functions" -msgstr "āĻĢāĻžāĻ‚āĻļāύ" +msgstr "" -#: src/SUMMARY.md src/control-flow-basics/macros.md +#: src/SUMMARY.md src/control-flow-basics.md src/control-flow-basics/macros.md msgid "Macros" -msgstr "āĻŽā§āϝāĻžāĻ•ā§āϰ⧋" +msgstr "" -#: src/SUMMARY.md src/control-flow-basics/exercise.md +#: src/SUMMARY.md src/control-flow-basics.md +#: src/control-flow-basics/exercise.md msgid "Exercise: Collatz Sequence" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ⧀: āĻ•āĻ˛ā§āϝāĻžāϟāϜ āĻāϰ āĻ•ā§āϰāĻŽ" +msgstr "" #: src/SUMMARY.md msgid "Day 1: Afternoon" -msgstr "āĻĒā§āϰāĻĨāĻŽ āĻĻāĻŋāύāσ āĻŦāĻŋāĻ•āĻžāϞ" +msgstr "" + +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/welcome-day-1-afternoon.md src/tuples-and-arrays.md +msgid "Tuples and Arrays" +msgstr "" + +#: src/SUMMARY.md src/tuples-and-arrays.md src/tuples-and-arrays/arrays.md +msgid "Arrays" +msgstr "" + +#: src/SUMMARY.md src/tuples-and-arrays.md src/tuples-and-arrays/tuples.md +msgid "Tuples" +msgstr "" + +#: src/SUMMARY.md src/tuples-and-arrays.md src/tuples-and-arrays/iteration.md +msgid "Array Iteration" +msgstr "" #: src/SUMMARY.md src/tuples-and-arrays.md -#: src/tuples-and-arrays/tuples-and-arrays.md -msgid "Tuples and Arrays" -msgstr "āϟāĻŋāωāĻĒāϞ āĻāĻŦāĻ‚ āĻ…ā§āϝāĻžāϰ⧇" - -#: src/SUMMARY.md src/tuples-and-arrays/iteration.md -msgid "Array Iteration" -msgstr "āĻ…ā§āϝāĻžāϰ⧇ āĻāϰ āĻĒ⧁āύāϰāĻžāĻŦ⧃āĻ¤ā§āϤāĻŋ" - -#: src/SUMMARY.md src/tuples-and-arrays/destructuring.md +#: src/tuples-and-arrays/destructuring.md msgid "Patterns and Destructuring" -msgstr "āĻĸāĻ•-āĻ āĻĢ⧇āϞāĻž āĻāĻŦāĻ‚ āĻĄāĻŋāĻ¸ā§āĻŸā§āϰāĻžāĻ•āϚāĻžāϰ āĻ•āϰāĻž" +msgstr "" -#: src/SUMMARY.md src/tuples-and-arrays/exercise.md +#: src/SUMMARY.md src/tuples-and-arrays.md src/tuples-and-arrays/exercise.md msgid "Exercise: Nested Arrays" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ⧀: āύ⧇āĻ¸ā§āĻŸā§‡āĻĄ āĻ…ā§āϝāĻžāϰ⧇" +msgstr "" -#: src/SUMMARY.md src/references.md +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/welcome-day-1-afternoon.md src/references.md msgid "References" -msgstr "āϰ⧇āĻĢāĻžāϰ⧇āĻ¨ā§āϏ" +msgstr "" -#: src/SUMMARY.md src/references/shared.md +#: src/SUMMARY.md src/references.md src/references/shared.md msgid "Shared References" -msgstr "āĻ­āĻžāĻ— āĻ•āϰāĻž āϰ⧇āĻĢāĻžāϰ⧇āĻ¨ā§āϏ" +msgstr "" -#: src/SUMMARY.md src/references/exclusive.md +#: src/SUMMARY.md src/references.md src/references/exclusive.md msgid "Exclusive References" -msgstr "āĻāĻ•āĻšā§‡āϟāĻŋāϝāĻŧāĻž āϰ⧇āĻĢāĻžāϰ⧇āĻ¨ā§āϏ" +msgstr "" -#: src/SUMMARY.md src/references/exercise.md +#: src/SUMMARY.md src/references.md src/references/slices.md +msgid "Slices" +msgstr "" + +#: src/SUMMARY.md src/references.md src/references/strings.md +msgid "Strings" +msgstr "" + +#: src/SUMMARY.md src/references.md src/references/dangling.md +msgid "Reference Validity" +msgstr "" + +#: src/SUMMARY.md src/references.md src/references/exercise.md msgid "Exercise: Geometry" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ⧀: āĻœā§āϝāĻžāĻŽāĻŋāϤāĻŋ" +msgstr "" + +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/welcome-day-1-afternoon.md src/user-defined-types.md +msgid "User-Defined Types" +msgstr "" #: src/SUMMARY.md src/user-defined-types.md -msgid "User-Defined Types" -msgstr "āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āĻĻā§āĻŦāĻžāϰāĻž āĻŦāĻ°ā§āĻŖāĻŋāϤ āϟāĻžāχāĻĒ" - -#: src/SUMMARY.md src/user-defined-types/named-structs.md +#: src/user-defined-types/named-structs.md msgid "Named Structs" -msgstr "āĻ…āĻ­āĻŋāĻšāĻŋāϤ Structs (āĻ—āĻ āύ)" +msgstr "" -#: src/SUMMARY.md src/user-defined-types/tuple-structs.md +#: src/SUMMARY.md src/user-defined-types.md +#: src/user-defined-types/tuple-structs.md msgid "Tuple Structs" -msgstr "Tuple Structs" +msgstr "" -#: src/SUMMARY.md src/user-defined-types/enums.md -#: src/pattern-matching/destructuring.md +#: src/SUMMARY.md src/user-defined-types.md src/user-defined-types/enums.md +#: src/pattern-matching/destructuring-enums.md msgid "Enums" -msgstr "Enums" +msgstr "" -#: src/SUMMARY.md src/user-defined-types/static-and-const.md -msgid "Static and Const" -msgstr "Static āĻāĻŦāĻ‚ Const" - -#: src/SUMMARY.md src/user-defined-types/aliases.md +#: src/SUMMARY.md src/user-defined-types.md src/user-defined-types/aliases.md msgid "Type Aliases" -msgstr "āϟāĻžāχāĻĒ āĻāϰ āωāĻĒāύāĻžāĻŽ" +msgstr "" -#: src/SUMMARY.md src/user-defined-types/exercise.md +#: src/SUMMARY.md src/user-defined-types.md +msgid "Const" +msgstr "" + +#: src/SUMMARY.md src/user-defined-types.md +msgid "Static" +msgstr "" + +#: src/SUMMARY.md src/user-defined-types.md src/user-defined-types/exercise.md msgid "Exercise: Elevator Events" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ⧀: āϞāĻŋāĻĢāϟ āĻāϰ āϘāϟāύāĻžāĻŦāϞ⧀" +msgstr "" #: src/SUMMARY.md msgid "Day 2: Morning" -msgstr "āĻĻā§āĻŦāĻŋāϤ⧀āϝāĻŧ āĻĻāĻŋāύāσ āϏāĻ•āĻžāϞ" +msgstr "" + +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/welcome-day-2.md src/pattern-matching.md +msgid "Pattern Matching" +msgstr "" + +#: src/SUMMARY.md src/pattern-matching.md src/pattern-matching/infallible.md +msgid "Irrefutable Patterns" +msgstr "" + +#: src/SUMMARY.md src/pattern-matching.md src/pattern-matching/match.md +msgid "Matching Values" +msgstr "" #: src/SUMMARY.md src/pattern-matching.md -msgid "Pattern Matching" -msgstr "āĻĒā§āϝāĻžāϟāĻžāĻ°ā§āύ āĻŽāĻŋāϞāĻžāύ⧋" +msgid "Destructuring Structs" +msgstr "" -#: src/SUMMARY.md src/pattern-matching/match.md -msgid "Matching Values" -msgstr "āĻŽāĻžāύ āĻŽā§‡āϞāĻžāύ⧋" +#: src/SUMMARY.md src/pattern-matching.md +msgid "Destructuring Enums" +msgstr "" -#: src/SUMMARY.md src/pattern-matching/destructuring.md -msgid "Destructuring" -msgstr "āĻĄāĻŋāĻ¸ā§āĻŸā§āϰāĻžāĻ•āϚāĻžāϰ āĻ•āϰāĻž" - -#: src/SUMMARY.md src/pattern-matching/let-control-flow.md +#: src/SUMMARY.md src/pattern-matching.md +#: src/pattern-matching/let-control-flow.md msgid "Let Control Flow" -msgstr "Let āĻāϰ āĻĒā§āϰāĻŦāĻžāĻš āύāĻŋāϝāĻŧāĻ¨ā§āĻ¤ā§āϰāĻŖ" +msgstr "" -#: src/SUMMARY.md src/pattern-matching/exercise.md -msgid "Exercise: Expression Evaluation" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ⧀: āĻ…āĻ­āĻŋāĻŦā§āϝāĻ•ā§āϤāĻŋ āĻŽā§‚āĻ˛ā§āϝāĻžāϝāĻŧāύ" +#: src/SUMMARY.md src/pattern-matching/let-control-flow/if-let.md +msgid "`if let` Expressions" +msgstr "" -#: src/SUMMARY.md src/methods-and-traits.md -msgid "Methods and Traits" -msgstr "āĻŽā§‡āĻĨāĻĄ āĻāĻŦāĻ‚ āĻŸā§āϰ⧇āχāϟ" - -#: src/SUMMARY.md src/methods-and-traits/methods.md -msgid "Methods" -msgstr "āĻŽā§‡āĻĨāĻĄāϏ" - -#: src/SUMMARY.md src/methods-and-traits/traits.md -msgid "Traits" -msgstr "āĻŸā§āϰ⧇āχāϟ" +#: src/SUMMARY.md src/pattern-matching/let-control-flow/while-let.md +msgid "`while let` Statements" +msgstr "" #: src/SUMMARY.md -msgid "Implmementing Traits" -msgstr "āĻŸā§āϰ⧇āχāϟ āĻŦāĻžāĻ¸ā§āϤāĻŦāĻžāϝāĻŧāύ āĻ•āϰāĻž" +msgid "`let else`" +msgstr "" + +#: src/SUMMARY.md src/pattern-matching.md src/pattern-matching/exercise.md +msgid "Exercise: Expression Evaluation" +msgstr "" + +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/welcome-day-2.md src/methods-and-traits.md +msgid "Methods and Traits" +msgstr "" + +#: src/SUMMARY.md src/methods-and-traits.md src/methods-and-traits/methods.md +msgid "Methods" +msgstr "" + +#: src/SUMMARY.md src/methods-and-traits.md src/methods-and-traits/traits.md +msgid "Traits" +msgstr "" + +#: src/SUMMARY.md src/methods-and-traits/traits/implementing.md +msgid "Implementing Traits" +msgstr "" + +#: src/SUMMARY.md src/methods-and-traits/traits/supertraits.md +msgid "Supertraits" +msgstr "" #: src/SUMMARY.md src/methods-and-traits/traits/associated-types.md msgid "Associated Types" -msgstr "āϝ⧁āĻ•ā§āϤ āϟāĻžāχāĻĒ" +msgstr "" -#: src/SUMMARY.md src/methods-and-traits/deriving.md +#: src/SUMMARY.md src/methods-and-traits.md src/methods-and-traits/deriving.md msgid "Deriving" -msgstr "āφāĻšāϰāĻŖ āĻ•āϰāĻž" +msgstr "" -#: src/SUMMARY.md src/methods-and-traits/exercise.md +#: src/SUMMARY.md src/methods-and-traits.md msgid "Exercise: Generic Logger" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ⧀: āĻœā§‡āύ⧇āϰāĻŋāĻ• āϤāĻĨā§āϝ āύāĻŋāĻ°ā§āĻŽāĻžāϤāĻž" +msgstr "" -#: src/SUMMARY.md src/generics.md +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/welcome-day-2.md src/generics.md msgid "Generics" -msgstr "āĻœā§‡āύ⧇āϰāĻŋāĻ•āϏ" +msgstr "" -#: src/SUMMARY.md src/generics/generic-functions.md +#: src/SUMMARY.md src/generics.md src/generics/generic-functions.md msgid "Generic Functions" -msgstr "āĻœā§‡āύ⧇āϰāĻŋāĻ• āĻĒāĻĻā§āϧāϤāĻŋ" +msgstr "" -#: src/SUMMARY.md src/generics/generic-data.md -msgid "Generic Data Types" -msgstr "āĻœā§‡āύ⧇āϰāĻŋāĻ• āĻĄā§‡āϟāĻž āϟāĻžāχāĻĒ" - -#: src/SUMMARY.md src/generics/trait-bounds.md +#: src/SUMMARY.md src/generics.md src/generics/trait-bounds.md msgid "Trait Bounds" -msgstr "āĻŸā§āϰ⧇āχāϟ āĻāϰ āϏ⧀āĻŽāĻžāύāĻž" +msgstr "" + +#: src/SUMMARY.md src/generics.md src/generics/generic-data.md +msgid "Generic Data Types" +msgstr "" + +#: src/SUMMARY.md src/generics.md src/generics/generic-traits.md +msgid "Generic Traits" +msgstr "" #: src/SUMMARY.md src/generics/impl-trait.md msgid "`impl Trait`" -msgstr "`impl Trait`" +msgstr "" + +#: src/SUMMARY.md src/generics/dyn-trait.md +msgid "`dyn Trait`" +msgstr "" #: src/SUMMARY.md src/generics/exercise.md msgid "Exercise: Generic `min`" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ⧀: āĻœā§‡āύ⧇āϰāĻŋāĻ• `min`" +msgstr "" #: src/SUMMARY.md msgid "Day 2: Afternoon" -msgstr "āĻĻā§āĻŦāĻŋāϤ⧀āϝāĻŧ āĻĻāĻŋāύāσ āĻŦāĻŋāĻ•āĻžāϞ" +msgstr "" -#: src/SUMMARY.md src/std-types.md +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/welcome-day-2-afternoon.md src/closures.md +msgid "Closures" +msgstr "" + +#: src/SUMMARY.md src/closures.md src/closures/syntax.md +msgid "Closure Syntax" +msgstr "" + +#: src/SUMMARY.md src/closures.md src/closures/capturing.md +msgid "Capturing" +msgstr "" + +#: src/SUMMARY.md src/closures.md +msgid "Closure Traits" +msgstr "" + +#: src/SUMMARY.md src/closures.md src/closures/exercise.md +msgid "Exercise: Log Filter" +msgstr "" + +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/welcome-day-2-afternoon.md src/std-types.md msgid "Standard Library Types" -msgstr "āĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄ āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋāϰ āϟāĻžāχāĻĒ" +msgstr "" -#: src/SUMMARY.md src/std-types/std.md +#: src/SUMMARY.md src/std-types.md src/std-types/std.md msgid "Standard Library" -msgstr "āĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄ āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋ" +msgstr "" -#: src/SUMMARY.md src/std-types/docs.md +#: src/SUMMARY.md src/std-types.md src/std-types/docs.md msgid "Documentation" -msgstr "āĻĻāϞāĻŋāϞ" +msgstr "" #: src/SUMMARY.md msgid "`Option`" -msgstr "`Option`" +msgstr "" -#: src/SUMMARY.md +#: src/SUMMARY.md src/error-handling/result.md msgid "`Result`" -msgstr "`Result`" +msgstr "" #: src/SUMMARY.md src/android/aidl/types/primitives.md #: src/android/interoperability/cpp/type-mapping.md msgid "`String`" -msgstr "`String`" +msgstr "" #: src/SUMMARY.md src/std-types/vec.md msgid "`Vec`" -msgstr "`Vec`" +msgstr "" #: src/SUMMARY.md src/std-types/hashmap.md src/bare-metal/no_std.md msgid "`HashMap`" -msgstr "`HashMap`" +msgstr "" -#: src/SUMMARY.md src/std-types/exercise.md +#: src/SUMMARY.md src/std-types.md src/std-types/exercise.md msgid "Exercise: Counter" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ: āϏāĻ‚āĻ–ā§āϝāĻžā§ŸāĻ•" +msgstr "" -#: src/SUMMARY.md src/std-traits.md +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/welcome-day-2-afternoon.md src/std-traits.md msgid "Standard Library Traits" -msgstr "āĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄ āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋāϰ āĻŸā§āϰ⧇āχāϟ" +msgstr "" -#: src/SUMMARY.md src/std-traits/comparisons.md src/async.md +#: src/SUMMARY.md src/std-traits.md src/std-traits/comparisons.md +#: src/concurrency/welcome-async.md msgid "Comparisons" -msgstr "āϤ⧁āϞāύāĻžāϏāĻŽā§‚āĻš" +msgstr "" -#: src/SUMMARY.md src/std-traits/operators.md +#: src/SUMMARY.md src/std-traits.md src/std-traits/operators.md msgid "Operators" -msgstr "āĻ•āĻžāĻ°ā§āϝāĻ•āĻžāϰāĻ•" +msgstr "" #: src/SUMMARY.md src/std-traits/from-and-into.md msgid "`From` and `Into`" -msgstr "`From` āĻāĻŦāĻ‚ `Into`" +msgstr "" -#: src/SUMMARY.md src/std-traits/casting.md +#: src/SUMMARY.md src/std-traits.md src/std-traits/casting.md msgid "Casting" -msgstr "āύāĻŋāĻ•ā§āώ⧇āĻĒāĻŖ āĻ•āϰāĻž" +msgstr "" #: src/SUMMARY.md src/std-traits/read-and-write.md msgid "`Read` and `Write`" -msgstr "`Read` āĻāĻŦāĻ‚ `Write`" +msgstr "" #: src/SUMMARY.md msgid "`Default`, struct update syntax" -msgstr "`Default`, āĻ¸ā§āĻŸā§āϰāĻžāĻ•ā§āĻŸā§‡āϰ āĻšāĻžāϞāύāĻžāĻ—āĻžāĻĻ āĻ•āϰāĻŦāĻžāϰ āĻŦāĻžāĻ•ā§āϝ āĻ—āĻ āύ" +msgstr "" -#: src/SUMMARY.md src/std-traits/closures.md -msgid "Closures" -msgstr "āĻ•ā§āϞ⧋āϜāĻžāϰ⧇āϏ (Closures)" - -#: src/SUMMARY.md src/std-traits/exercise.md +#: src/SUMMARY.md src/std-traits.md src/std-traits/exercise.md msgid "Exercise: ROT13" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ⧀: āϰ⧋.āĻ“.t ā§§ā§Š (ROT 13)" +msgstr "" #: src/SUMMARY.md msgid "Day 3: Morning" -msgstr "āϤ⧃āϤ⧀āϝāĻŧ āĻĻāĻŋāύāσ āϏāĻ•āĻžāϞ" +msgstr "" -#: src/SUMMARY.md src/memory-management.md +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/welcome-day-3.md src/memory-management.md msgid "Memory Management" -msgstr "āĻŽā§‡āĻŽā§‹āϰāĻŋ āĻŦā§āϝāĻŦāĻ¸ā§āĻĨāĻžāĻĒāύāĻž" +msgstr "" -#: src/SUMMARY.md src/memory-management/review.md +#: src/SUMMARY.md src/memory-management.md src/memory-management/review.md msgid "Review of Program Memory" -msgstr "āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽā§‡āϰ āĻ¸ā§āĻŽā§ƒāϤāĻŋāϰ (Memory) āĻŦā§āϝāĻžāĻĒāĻžāϰ⧇ āĻĒāĻ°ā§āϝāĻžāϞ⧋āϚāύāĻž" +msgstr "" -#: src/SUMMARY.md src/memory-management/approaches.md +#: src/SUMMARY.md src/memory-management.md src/memory-management/approaches.md msgid "Approaches to Memory Management" -msgstr "āĻŽā§‡āĻŽāϰāĻŋ āĻŦā§āϝāĻŦāĻ¸ā§āĻĨāĻžāĻĒāύāĻžāϰ āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āύ āĻĒāĻĻā§āϧāϤāĻŋ" +msgstr "" -#: src/SUMMARY.md src/memory-management/ownership.md +#: src/SUMMARY.md src/memory-management.md src/memory-management/ownership.md msgid "Ownership" -msgstr "āĻŽāĻžāϞāĻŋāĻ•āĻžāύāĻž" +msgstr "" -#: src/SUMMARY.md src/memory-management/move.md +#: src/SUMMARY.md src/memory-management.md src/memory-management/move.md msgid "Move Semantics" -msgstr "āĻŽā§āĻ­ āĻāϰ āĻļāĻŦā§āĻĻāĻžāĻ°ā§āĻĨāĻŦāĻŋāĻĻā§āϝāĻž" +msgstr "" #: src/SUMMARY.md msgid "`Clone`" -msgstr "`Clone`" +msgstr "" -#: src/SUMMARY.md src/memory-management/copy-types.md +#: src/SUMMARY.md src/memory-management.md src/memory-management/copy-types.md msgid "Copy Types" -msgstr "āĻ…āύ⧁āϞāĻŋāĻĒāĻŋ āϟāĻžāχāĻĒāϗ⧁āϞāĻŋ" +msgstr "" #: src/SUMMARY.md msgid "`Drop`" -msgstr "`Drop`" +msgstr "" -#: src/SUMMARY.md src/memory-management/exercise.md +#: src/SUMMARY.md src/memory-management.md src/memory-management/exercise.md msgid "Exercise: Builder Type" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ⧀: āϰāϚāύāĻžāĻ•āĻžāϰ⧀ āϟāĻžāχāĻĒ" +msgstr "" -#: src/SUMMARY.md src/smart-pointers.md +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/welcome-day-3.md src/smart-pointers.md msgid "Smart Pointers" -msgstr "āĻŦ⧁āĻĻā§āϧāĻŋāĻŽāĻžāύ āχāĻ™ā§āĻ—āĻŋāϤāĻ•āĻžāϰ⧀ (āĻ¸ā§āĻŽāĻžāĻ°ā§āϟ āĻĒā§Ÿā§‡āĻ¨ā§āϟāĻžāϰ)" +msgstr "" #: src/SUMMARY.md src/smart-pointers/box.md #: src/android/interoperability/cpp/type-mapping.md msgid "`Box`" -msgstr "`Box`" +msgstr "" #: src/SUMMARY.md src/smart-pointers/rc.md msgid "`Rc`" -msgstr "`Rc`" +msgstr "" -#: src/SUMMARY.md src/smart-pointers/trait-objects.md -msgid "Trait Objects" -msgstr "Trait Objects" +#: src/SUMMARY.md src/smart-pointers.md src/smart-pointers/trait-objects.md +msgid "Owned Trait Objects" +msgstr "" -#: src/SUMMARY.md src/smart-pointers/exercise.md +#: src/SUMMARY.md src/smart-pointers.md src/smart-pointers/exercise.md msgid "Exercise: Binary Tree" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ⧀: āĻĻ⧁āχ āϚāϞāĻŦāĻŋāĻļāĻŋāĻˇā§āϟ āϤāϰ⧂" +msgstr "" #: src/SUMMARY.md msgid "Day 3: Afternoon" -msgstr "āϤ⧃āϤ⧀āϝāĻŧ āĻĻāĻŋāύāσ āĻŦāĻŋāĻ•āĻžāϞ" +msgstr "" -#: src/SUMMARY.md src/borrowing.md +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/welcome-day-3-afternoon.md src/borrowing.md msgid "Borrowing" -msgstr "āϧāĻžāϰ āύ⧇āĻ“āϝāĻŧāĻž" +msgstr "" -#: src/SUMMARY.md src/borrowing/shared.md +#: src/SUMMARY.md src/borrowing.md src/borrowing/shared.md msgid "Borrowing a Value" -msgstr "āĻāĻ•āϟāĻŋ āĻŽā§āϝāĻžāύ āϧāĻžāϰ āύ⧇āĻ“ā§ŸāĻž" +msgstr "" -#: src/SUMMARY.md src/borrowing/borrowck.md +#: src/SUMMARY.md src/borrowing.md src/borrowing/borrowck.md msgid "Borrow Checking" -msgstr "āϧāĻžāϰ āύ⧇āĻ“ā§ŸāĻž āĻŽā§āϝāĻžāύ āĻĒāϰ⧀āĻ•ā§āώāĻž āĻ•āϰāĻž" +msgstr "" -#: src/SUMMARY.md src/borrowing/interior-mutability.md +#: src/SUMMARY.md src/borrowing.md src/borrowing/examples.md +msgid "Borrow Errors" +msgstr "" + +#: src/SUMMARY.md src/borrowing.md src/borrowing/interior-mutability.md msgid "Interior Mutability" -msgstr "āφāĻ¨ā§āϤāσāĻ•āĻžāĻ°ā§āϝāĻ•ā§āώāĻŽāϤāĻž" +msgstr "" -#: src/SUMMARY.md src/borrowing/exercise.md -msgid "Exercise: Health Statistics" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ⧀: āĻ¸ā§āĻŦāĻžāĻ¸ā§āĻĨā§āϝ āĻĒāϰāĻŋāϏāĻ‚āĻ–ā§āϝāĻžāύ" +#: src/SUMMARY.md src/borrowing/interior-mutability/cell.md +msgid "`Cell`" +msgstr "" -#: src/SUMMARY.md src/slices-and-lifetimes.md -msgid "Slices and Lifetimes" -msgstr "āϟ⧁āĻ•āϰāĻž āĻāĻŦāĻ‚ āĻœā§€āĻŦāύāĻ•āĻžāϞ" +#: src/SUMMARY.md src/borrowing/interior-mutability/refcell.md +msgid "`RefCell`" +msgstr "" -#: src/SUMMARY.md -msgid "Slices: `&[T]`" -msgstr "āϟ⧁āĻ•āϰāĻž: `&[T]`" +#: src/SUMMARY.md src/borrowing.md src/borrowing/exercise.md +msgid "Exercise: Wizard's Inventory" +msgstr "" -#: src/SUMMARY.md src/slices-and-lifetimes/str.md -msgid "String References" -msgstr "āĻ¸ā§āĻŸā§āϰāĻŋāĻ‚ āϰ⧇āĻĢāĻžāϰ⧇āĻ¨ā§āϏ" +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/welcome-day-3-afternoon.md src/lifetimes.md +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +msgid "Lifetimes" +msgstr "" -#: src/SUMMARY.md src/slices-and-lifetimes/lifetime-annotations.md -msgid "Lifetime Annotations" -msgstr "āĻœā§€āĻŦāύāĻ•āĻžāϞ⧇āϰ āĻŸā§€āĻ•āĻž" +#: src/SUMMARY.md src/lifetimes.md +msgid "Borrowing and Functions" +msgstr "" -#: src/SUMMARY.md +#: src/SUMMARY.md src/lifetimes.md src/lifetimes/returning-borrows.md +msgid "Returning Borrows" +msgstr "" + +#: src/SUMMARY.md src/lifetimes.md src/lifetimes/multiple-borrows.md +msgid "Multiple Borrows" +msgstr "" + +#: src/SUMMARY.md src/lifetimes.md src/lifetimes/borrow-both.md +msgid "Borrow Both" +msgstr "" + +#: src/SUMMARY.md src/lifetimes.md src/lifetimes/borrow-one.md +msgid "Borrow One" +msgstr "" + +#: src/SUMMARY.md src/lifetimes.md src/lifetimes/lifetime-elision.md msgid "Lifetime Elision" -msgstr "āĻœā§€āĻŦāύāĻ•āĻžāϞ⧇āϰ āϞ⧇āĻžāĻĒ" +msgstr "" -#: src/SUMMARY.md -msgid "Struct Lifetimes" -msgstr "āĻ¸ā§āĻŸā§āϰāĻžāĻ•ā§āĻŸā§‡āϰ āĻœā§€āĻŦāύāĻ•āĻžāϞ" +#: src/SUMMARY.md src/lifetimes.md src/lifetimes/struct-lifetimes.md +msgid "Lifetimes in Data Structures" +msgstr "" -#: src/SUMMARY.md src/slices-and-lifetimes/exercise.md +#: src/SUMMARY.md src/lifetimes.md src/lifetimes/exercise.md msgid "Exercise: Protobuf Parsing" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ⧀: āĻĒā§āϰ⧋āĻŸā§‹āĻŦāĻžāĻĢ āĻĒāĻĻāĻžāĻ¨ā§āĻŦāϝāĻŧ āĻ•āϰāĻž" +msgstr "" #: src/SUMMARY.md msgid "Day 4: Morning" -msgstr "āϚāĻĨ⧁āĻ°ā§āϤ āĻĻāĻŋāύ: āϏāĻ•āĻžāϞāĻŦ⧇āϞāĻž" +msgstr "" + +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/welcome-day-4.md src/iterators.md +msgid "Iterators" +msgstr "" #: src/SUMMARY.md src/iterators.md -msgid "Iterators" -msgstr "āĻĒ⧁āύāϰāĻžāĻŦ⧃āĻ¤ā§āϤāĻŋāĻ•āĻžāϰ⧀" +msgid "Motivation" +msgstr "" -#: src/SUMMARY.md src/iterators/iterator.md src/bare-metal/no_std.md -msgid "`Iterator`" -msgstr "`Iterator`" +#: src/SUMMARY.md src/iterators/iterator.md +msgid "`Iterator` Trait" +msgstr "" + +#: src/SUMMARY.md src/iterators/helpers.md +msgid "`Iterator` Helper Methods" +msgstr "" + +#: src/SUMMARY.md src/iterators/collect.md +msgid "`collect`" +msgstr "" #: src/SUMMARY.md src/iterators/intoiterator.md msgid "`IntoIterator`" -msgstr "`IntoIterator`" +msgstr "" -#: src/SUMMARY.md -msgid "`FromIterator`" -msgstr "`FromIterator`" - -#: src/SUMMARY.md src/iterators/exercise.md +#: src/SUMMARY.md src/iterators.md src/iterators/exercise.md msgid "Exercise: Iterator Method Chaining" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ⧀: āĻĒ⧁āύāϰāĻžāĻŦ⧃āĻ¤ā§āϤāĻŋāĻ•āĻžāϰ⧀ āĻŽāĻžāϞāĻžāĻŦāĻ¨ā§āϧāύ" +msgstr "" -#: src/SUMMARY.md src/modules.md src/modules/modules.md +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/welcome-day-4.md src/modules.md src/modules/modules.md msgid "Modules" -msgstr "Modules" +msgstr "" -#: src/SUMMARY.md src/modules/filesystem.md +#: src/SUMMARY.md src/modules.md src/modules/filesystem.md msgid "Filesystem Hierarchy" -msgstr "Filesystem Hierarchy" +msgstr "" -#: src/SUMMARY.md src/modules/visibility.md +#: src/SUMMARY.md src/modules.md src/modules/visibility.md msgid "Visibility" -msgstr "āĻĻ⧃āĻļā§āϝāĻŽāĻžāύāϤāĻž" +msgstr "" + +#: src/SUMMARY.md src/modules.md +msgid "Encapsulation" +msgstr "" #: src/SUMMARY.md msgid "`use`, `super`, `self`" -msgstr "`use`, `super`, `self`" +msgstr "" -#: src/SUMMARY.md src/modules/exercise.md +#: src/SUMMARY.md src/modules.md src/modules/exercise.md msgid "Exercise: Modules for a GUI Library" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ⧀: āĻāĻ•āϟāĻŋ āϜāĻŋ.āχāω.āφāχ āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋ āĻŦāĻžāύāĻžāĻŦāĻžāϰ āĻŽāĻĄāĻŋāωāϞ" +msgstr "" -#: src/SUMMARY.md src/testing.md src/chromium/testing.md +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/welcome-day-4.md src/testing.md src/chromium/testing.md msgid "Testing" -msgstr "āĻŸā§‡āĻ¸ā§āϟāĻŋāĻ‚" +msgstr "" -#: src/SUMMARY.md -msgid "Test Modules" -msgstr "āĻŸā§‡āĻ¸ā§āϟ āĻŽāĻĄāĻŋāωāϞ" +#: src/SUMMARY.md src/testing.md src/testing/unit-tests.md +msgid "Unit Tests" +msgstr "" -#: src/SUMMARY.md src/testing/other.md +#: src/SUMMARY.md src/testing.md src/testing/other.md msgid "Other Types of Tests" -msgstr "āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āϟāĻžāχāĻĒ⧇āϰ āĻĒāϰ⧀āĻ•ā§āώāĻž" +msgstr "" -#: src/SUMMARY.md src/testing/useful-crates.md -msgid "Useful Crates" -msgstr "āωāĻĒāĻ•āĻžāϰ⧀ āĻ•ā§āϰ⧇āϟāϏāĻŽā§‚āĻš" - -#: src/SUMMARY.md src/testing/googletest.md -msgid "GoogleTest" -msgstr "GoogleTest" - -#: src/SUMMARY.md src/testing/mocking.md -msgid "Mocking" -msgstr "āωāĻĒāĻšāĻžāϏ āĻ•āϰāĻž" - -#: src/SUMMARY.md src/testing/lints.md +#: src/SUMMARY.md src/testing.md src/testing/lints.md msgid "Compiler Lints and Clippy" -msgstr "āϏāĻ‚āĻ•āϞāύāĻ•āĻžāϰ⧀ (āĻ•āĻŽā§āĻĒāĻžāχāϞāĻžāϰ) āĻāϰ āϞāĻŋāĻ¨ā§āϟāϗ⧁āϞāĻŋ āĻāĻŦāĻ‚ āĻ•ā§āϞāĻŋāĻĒāĻŋ" +msgstr "" -#: src/SUMMARY.md src/testing/exercise.md +#: src/SUMMARY.md src/testing.md src/testing/exercise.md msgid "Exercise: Luhn Algorithm" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ⧀: āϞ⧁āύ āĻāϰ āĻ—āĻžāĻŖāĻŋāϤāĻŋāĻ• āĻĒāϰāĻŋāĻ­āĻžāώāĻž" +msgstr "" #: src/SUMMARY.md msgid "Day 4: Afternoon" -msgstr "āϚāϤ⧁āĻ°ā§āĻĨ āĻĻāĻŋāύ: āĻĻ⧁āĻĒ⧁āϰāĻŦ⧇āϞāĻž" +msgstr "" -#: src/SUMMARY.md src/error-handling.md +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/welcome-day-4-afternoon.md src/error-handling.md +#: src/idiomatic/welcome.md msgid "Error Handling" -msgstr "āĻ¤ā§āϰ⧁āϟāĻŋ āϏāĻžāĻŽāϞāĻžāύ⧋" +msgstr "" -#: src/SUMMARY.md src/error-handling/panics.md +#: src/SUMMARY.md src/error-handling.md src/error-handling/panics.md msgid "Panics" -msgstr "Panics-āĻĒā§āϝāĻžāύāĻŋāĻ•" +msgstr "" -#: src/SUMMARY.md src/error-handling/try.md +#: src/SUMMARY.md src/error-handling.md src/error-handling/try.md msgid "Try Operator" -msgstr "Try āĻ•āĻžāĻ°ā§āϝāĻ•āĻžāϰāĻ•" +msgstr "" -#: src/SUMMARY.md src/error-handling/try-conversions.md +#: src/SUMMARY.md src/error-handling.md src/error-handling/try-conversions.md msgid "Try Conversions" -msgstr "Try āϰ⧂āĻĒāĻžāĻ¨ā§āϤāϰ" +msgstr "" #: src/SUMMARY.md msgid "`Error` Trait" -msgstr "`Error` āĻŸā§āϰ⧇āχāϟ" +msgstr "" -#: src/SUMMARY.md src/error-handling/thiserror-and-anyhow.md -msgid "`thiserror` and `anyhow`" -msgstr "`thiserror` āĻāĻŦāĻ‚ `anyhow`" +#: src/SUMMARY.md src/error-handling/thiserror.md +msgid "`thiserror`" +msgstr "" + +#: src/SUMMARY.md src/error-handling/anyhow.md src/idiomatic/welcome.md +msgid "`anyhow`" +msgstr "" #: src/SUMMARY.md msgid "Exercise: Rewriting with `Result`" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ⧀: `Result` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āφāĻŦāĻžāϰ āϞ⧇āĻ–āĻž" +msgstr "" -#: src/SUMMARY.md src/unsafe-rust.md src/unsafe-rust/unsafe.md +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/welcome-day-4-afternoon.md src/unsafe-rust.md src/unsafe-rust/unsafe.md +#: src/unsafe-deep-dive/introduction/responsibility-shift.md msgid "Unsafe Rust" -msgstr "āĻ…āύāĻŋāϰāĻžāĻĒāĻĻ āϰāĻžāĻ¸ā§āϟ" +msgstr "" -#: src/SUMMARY.md +#: src/SUMMARY.md src/unsafe-rust.md msgid "Unsafe" -msgstr "āĻ…āύāĻŋāϰāĻžāĻĒāĻĻ" +msgstr "" -#: src/SUMMARY.md src/unsafe-rust/dereferencing.md +#: src/SUMMARY.md src/unsafe-rust.md src/unsafe-rust/dereferencing.md msgid "Dereferencing Raw Pointers" -msgstr "āϰ āĻĒāϝāĻŧ⧇āĻ¨ā§āϟāĻžāϰ āĻĄāĻŋ-āϰ⧇āĻĢāĻžāϰ⧇āĻ¨ā§āϏ āĻ•āϰāĻž" +msgstr "" -#: src/SUMMARY.md src/unsafe-rust/mutable-static.md +#: src/SUMMARY.md src/unsafe-rust.md src/unsafe-rust/mutable-static.md msgid "Mutable Static Variables" -msgstr "āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύāϝ⧋āĻ—ā§āϝ āĻ¸ā§āĻŸā§āϝāĻžāϟāĻŋāĻ• āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞāϏ" +msgstr "" -#: src/SUMMARY.md src/unsafe-rust/unions.md +#: src/SUMMARY.md src/unsafe-rust.md src/unsafe-rust/unions.md msgid "Unions" -msgstr "Unions" +msgstr "" -#: src/SUMMARY.md src/unsafe-rust/unsafe-functions.md +#: src/SUMMARY.md src/unsafe-rust.md src/unsafe-rust/unsafe-functions.md msgid "Unsafe Functions" -msgstr "āĻ…āύāĻŋāϰāĻžāĻĒāĻĻ āĻ•āĻžāϜāĻ•āĻ°ā§āĻŽ" +msgstr "" -#: src/SUMMARY.md +#: src/SUMMARY.md src/unsafe-rust/unsafe-functions/rust.md +msgid "Unsafe Rust Functions" +msgstr "" + +#: src/SUMMARY.md src/unsafe-rust/unsafe-functions/extern-c.md +msgid "Unsafe External Functions" +msgstr "" + +#: src/SUMMARY.md src/unsafe-rust/unsafe-functions/calling.md +msgid "Calling Unsafe Functions" +msgstr "" + +#: src/SUMMARY.md src/unsafe-rust.md msgid "Unsafe Traits" -msgstr "āύāĻžāύāĻžāύ āĻ…āύāĻŋāϰāĻžāĻĒāĻĻ āĻŸā§āϰ⧇āχāϟ" +msgstr "" + +#: src/SUMMARY.md src/unsafe-rust.md +msgid "Exercise: FFI Wrapper" +msgstr "" #: src/SUMMARY.md -msgid "Exercise: FFI Wrapper" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ⧀: āĻāĻĢ . āĻāĻĢ . āφāχ āĻŽā§‹āĻĄāĻŧāĻ•" - -#: src/SUMMARY.md src/bare-metal/android.md msgid "Android" -msgstr "Android" +msgstr "" #: src/SUMMARY.md src/android/setup.md src/chromium/setup.md msgid "Setup" -msgstr "āϏ⧇āϟāφāĻĒ" +msgstr "" #: src/SUMMARY.md src/android/build-rules.md msgid "Build Rules" -msgstr "āĻ—āĻ āύ⧇āϰ āύāĻŋāϝāĻŧāĻŽ" +msgstr "" #: src/SUMMARY.md msgid "Binary" -msgstr "āĻŦāĻžāχāύāĻžāϰāĻŋ" +msgstr "" #: src/SUMMARY.md msgid "Library" -msgstr "āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋ" +msgstr "" #: src/SUMMARY.md src/android/aidl.md msgid "AIDL" -msgstr "AIDL" +msgstr "" #: src/SUMMARY.md src/android/aidl/birthday-service.md msgid "Birthday Service Tutorial" -msgstr "āϜāĻ¨ā§āĻŽāĻĻāĻŋāύ⧇āϰ āϏ⧇āĻŦāĻžāϰ āϟāĻŋāωāĻŸā§‹āϰāĻŋāϝāĻŧāĻžāϞ" +msgstr "" #: src/SUMMARY.md msgid "Interface" -msgstr "āχāĻ¨ā§āϟāĻžāϰāĻĢ⧇āϏ" +msgstr "" #: src/SUMMARY.md msgid "Service API" -msgstr "āϏāĻžāĻ°ā§āĻ­āĻŋāϏ āĻ . āĻĒāĻŋ . āφāχ" +msgstr "" #: src/SUMMARY.md msgid "Service" -msgstr "āϏāĻžāĻ°ā§āĻ­āĻŋāϏ" +msgstr "" #: src/SUMMARY.md msgid "Server" -msgstr "āϏāĻžāĻ°ā§āĻ­āĻžāϰ" +msgstr "" #: src/SUMMARY.md src/android/aidl/example-service/deploy.md msgid "Deploy" -msgstr "āĻ¸ā§āĻĨāĻžāĻĒāύ" +msgstr "" #: src/SUMMARY.md msgid "Client" -msgstr "āĻ•ā§āϞāĻžāϝāĻŧ⧇āĻ¨ā§āϟ" +msgstr "" #: src/SUMMARY.md src/android/aidl/example-service/changing-definition.md msgid "Changing API" -msgstr "API āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ" +msgstr "" #: src/SUMMARY.md msgid "Updating Implementations" -msgstr "āĻŦāĻžāĻ¸ā§āϤāĻŦāĻžāϝāĻŧāύāϗ⧁āϞāĻŋāϰ āĻšāĻžāϞ āύāĻžāĻ—āĻžāĻĻ āĻ•āϰāĻž" +msgstr "" #: src/SUMMARY.md msgid "AIDL Types" -msgstr "āĻ.āφāχ.āĻĻāĻŋ.āĻāϞ āϟāĻžāχāĻĒ" +msgstr "" #: src/SUMMARY.md src/android/aidl/types/primitives.md msgid "Primitive Types" -msgstr "āĻŦāύāĻŋāϝāĻŧāĻžāĻĻāĻŋ āϟāĻžāχāĻĒ" +msgstr "" #: src/SUMMARY.md src/android/aidl/types/arrays.md msgid "Array Types" -msgstr "āĻ…ā§āϝāĻžāϰ⧇ āĻāϰ āϟāĻžāχāĻĒ" +msgstr "" #: src/SUMMARY.md src/android/aidl/types/objects.md msgid "Sending Objects" -msgstr "āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ āĻĒāĻžāĻ āĻžāύ⧋" +msgstr "" #: src/SUMMARY.md src/android/aidl/types/parcelables.md msgid "Parcelables" -msgstr "āĻĒāĻžāĻ°ā§āϏ⧇āϞāĻŦāϞ⧇āϏ (āĻĒ⧁āϞāĻŋāĻ¨ā§āĻĻāĻž āĻŦāĻžāύāĻžāύ⧋ āϝāĻžā§Ÿ āϝāĻžāϕ⧇)" +msgstr "" #: src/SUMMARY.md src/android/aidl/types/file-descriptor.md msgid "Sending Files" -msgstr "āĻāĻ•āĻžāϧāĻŋāĻ• āĻĢāĻžāχāϞ āĻĒāĻžāĻ āĻžāύ⧋" +msgstr "" + +#: src/SUMMARY.md src/android/testing/googletest.md +msgid "GoogleTest" +msgstr "" + +#: src/SUMMARY.md src/android/testing/mocking.md +msgid "Mocking" +msgstr "" #: src/SUMMARY.md src/android/logging.md src/bare-metal/aps/logging.md msgid "Logging" -msgstr "Logging" +msgstr "" #: src/SUMMARY.md src/android/interoperability.md msgid "Interoperability" -msgstr "āφāĻ¨ā§āϤāσāĻ•āĻžāĻ°ā§āϝāĻ•ā§āώāĻŽāϤāĻž" +msgstr "" #: src/SUMMARY.md msgid "With C" -msgstr "C āĻāϰ āϏāĻžāĻĨ⧇" +msgstr "" + +#: src/SUMMARY.md src/android/interoperability/with-c/c-library.md +msgid "A Simple C Library" +msgstr "" #: src/SUMMARY.md -msgid "Calling C with Bindgen" -msgstr "Bindgen āĻāϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ C āϕ⧇ āĻĄāĻžāĻ•āĻž" +msgid "Bindgen" +msgstr "" + +#: src/SUMMARY.md src/android/interoperability/with-c/run-our-binary.md +msgid "Running Our Binary" +msgstr "" + +#: src/SUMMARY.md src/android/interoperability/with-c/rust-library.md +msgid "A Simple Rust Library" +msgstr "" #: src/SUMMARY.md msgid "Calling Rust from C" -msgstr "C āĻĨ⧇āϕ⧇ āϰāĻžāĻ¸ā§āϟ āϕ⧇ āĻĄāĻžāĻ•āĻž" +msgstr "" #: src/SUMMARY.md src/android/interoperability/cpp.md msgid "With C++" -msgstr "C++āĻāϰ āϏāĻžāĻĨ⧇" +msgstr "" #: src/SUMMARY.md src/android/interoperability/cpp/bridge.md msgid "The Bridge Module" -msgstr "Bridge āĻŽāĻĄāĻŋāωāϞ" +msgstr "" #: src/SUMMARY.md msgid "Rust Bridge" -msgstr "āϰāĻžāĻ¸ā§āϟ Bridge" +msgstr "" #: src/SUMMARY.md src/android/interoperability/cpp/generated-cpp.md msgid "Generated C++" -msgstr "āωāĻ¤ā§āĻĒāĻ¨ā§āύ āĻšāĻ“ā§ŸāĻž C++ āϕ⧋āĻĄ" +msgstr "" #: src/SUMMARY.md msgid "C++ Bridge" -msgstr "C++ Bridge" +msgstr "" #: src/SUMMARY.md src/android/interoperability/cpp/shared-types.md msgid "Shared Types" -msgstr "āĻ…āĻ‚āĻļ⧇ āĻŽāĻžāϞāĻŋāĻ•āĻžāύāĻžāϧ⧀āύ āϟāĻžāχāĻĒāϗ⧁āϞāĻŋ" +msgstr "" #: src/SUMMARY.md src/android/interoperability/cpp/shared-enums.md msgid "Shared Enums" -msgstr "āĻ…āĻ‚āĻļ⧇ āĻŽāĻžāϞāĻŋāĻ•āĻžāύāĻžāϧ⧀āύ āĻ—āĻŖāύāĻžāĻ•āĻžāϰ⧀ (āĻļā§‡ā§ŸāĻžāĻ°ā§āĻĄ āχāύ⧁āĻŽā§āϏ)" +msgstr "" #: src/SUMMARY.md src/android/interoperability/cpp/rust-result.md msgid "Rust Error Handling" -msgstr "āϰāĻžāĻ¸ā§āϟ āĻāϰ āĻ¤ā§āϰ⧁āϟāĻŋ āĻĒāϰāĻŋāϚāĻžāϞāύāĻž" +msgstr "" #: src/SUMMARY.md src/android/interoperability/cpp/cpp-exception.md msgid "C++ Error Handling" -msgstr "C++ āĻāϰ āĻ¤ā§āϰ⧁āϟāĻŋ āĻĒāϰāĻŋāϚāĻžāϞāύāĻž" +msgstr "" #: src/SUMMARY.md src/android/interoperability/cpp/type-mapping.md msgid "Additional Types" -msgstr "āφāϰ⧋ āĻ•āĻŋāϛ⧁ āϟāĻžāχāĻĒ" - -#: src/SUMMARY.md -msgid "Building for Android: C++" -msgstr "āĻāĻ¨ā§āĻĄā§āϰ⧋āχāĻĄ āĻāϰ āϜāĻ¨ā§āϝ⧇ āĻŦāĻžāύāĻžāύ⧋: C++" +msgstr "" #: src/SUMMARY.md msgid "Building for Android: Genrules" -msgstr "āĻāĻ¨ā§āĻĄā§āϰ⧋āχāĻĄ āĻāϰ āϜāĻ¨ā§āϝ⧇ āĻŦāĻžāύāĻžāύ⧋: Genrules" +msgstr "" + +#: src/SUMMARY.md +msgid "Building for Android: C++" +msgstr "" #: src/SUMMARY.md msgid "Building for Android: Rust" -msgstr "āĻāĻ¨ā§āĻĄā§āϰ⧋āχāĻĄ āĻāϰ āϜāĻ¨ā§āϝ⧇ āĻŦāĻžāύāĻžāύ⧋: āϰāĻžāĻ¸ā§āϟ" +msgstr "" #: src/SUMMARY.md msgid "With Java" -msgstr "Java āĻāϰ āϏāĻžāĻĨ⧇" - -#: src/SUMMARY.md src/exercises/android/morning.md -#: src/exercises/bare-metal/morning.md src/exercises/bare-metal/afternoon.md -#: src/exercises/concurrency/morning.md src/exercises/concurrency/afternoon.md -msgid "Exercises" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ" +msgstr "" #: src/SUMMARY.md msgid "Chromium" -msgstr "Chromium" +msgstr "" #: src/SUMMARY.md src/chromium/cargo.md msgid "Comparing Chromium and Cargo Ecosystems" -msgstr "Chromium āĻāĻŦāĻ‚ Cargo āĻāϰ āĻŦāĻžāĻ¸ā§āϤ⧁āϤāĻ¨ā§āĻ¤ā§āϰāϗ⧁āϞāĻŋāϰ āĻŽāĻ§ā§āϝ⧇ āϤ⧁āϞāύāĻž" +msgstr "" #: src/SUMMARY.md msgid "Policy" -msgstr "āĻ•āĻ°ā§āĻŽāĻĒāĻ¨ā§āĻĨāĻž" +msgstr "" #: src/SUMMARY.md msgid "Unsafe Code" -msgstr "āĻ…āύāĻŋāϰāĻžāĻĒāĻĻ āϕ⧋āĻĄ" +msgstr "" #: src/SUMMARY.md src/chromium/build-rules/depending.md msgid "Depending on Rust Code from Chromium C++" -msgstr "āĻ•ā§āϰ⧋āĻŽāĻŋ⧟āĻŽ C++ āĻāϰ āĻĨ⧇āϕ⧇ āφāϏāĻž āϰāĻžāĻ¸ā§āϟ āϕ⧋āĻĄ āĻāϰ āĻ“āĻĒāϰ⧇ āύāĻŋāĻ°ā§āĻ­āϰ āĻ•āϰāϛ⧇" +msgstr "" #: src/SUMMARY.md src/chromium/build-rules/vscode.md msgid "Visual Studio Code" -msgstr "Visual Studio Code" +msgstr "" -#: src/SUMMARY.md src/exercises/chromium/third-party.md +#: src/SUMMARY.md src/lifetimes/exercise.md +#: src/exercises/chromium/third-party.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/exercise.md msgid "Exercise" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ⧀" +msgstr "" #: src/SUMMARY.md src/chromium/testing/rust-gtest-interop.md msgid "`rust_gtest_interop` Library" -msgstr "`rust_gtest_interop` āϕ⧋āĻĄ āϏāĻ‚āĻ—ā§āϰāĻš āĻŦāĻž āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋ" +msgstr "" #: src/SUMMARY.md src/chromium/testing/build-gn.md msgid "GN Rules for Rust Tests" -msgstr "āϰāĻžāĻ¸ā§āϟ āĻ āĻĒāϰ⧀āĻ•ā§āώāĻž-āύāĻŋāϰ⧀āĻ•ā§āώāĻž āĻ•āϰāĻŦāĻžāϰ āϜāĻ¨ā§āϝ⧇ āϜāĻŋ . āĻāύ āύāĻŋ⧟āĻŽāĻžāĻŦāϞ⧀" +msgstr "" #: src/SUMMARY.md src/chromium/testing/chromium-import-macro.md msgid "`chromium::import!` Macro" -msgstr "`chromium::import!` āĻŽā§āϝāĻžāĻ•ā§āϰ⧋" +msgstr "" #: src/SUMMARY.md src/chromium/interoperability-with-cpp.md msgid "Interoperability with C++" -msgstr "āϏāĻŋ++ āĻāϰ āϏāĻžāĻĨ⧇ āφāĻ¨ā§āϤāσāĻ•āĻžāĻ°ā§āϝāĻ•ā§āώāĻŽāϤāĻž" +msgstr "" #: src/SUMMARY.md src/chromium/interoperability-with-cpp/example-bindings.md msgid "Example Bindings" -msgstr "āωāĻĻāĻžāĻšāϰāĻŖ āĻŦāĻžāχāĻ¨ā§āĻĄāĻŋāĻ‚" +msgstr "" #: src/SUMMARY.md src/chromium/interoperability-with-cpp/limitations-of-cxx.md msgid "Limitations of CXX" -msgstr "āϏāĻŋ.āĻāĻ•ā§āϏ.āĻāĻ•ā§āϏ āĻāϰ āϏ⧀āĻŽāĻžāĻŦāĻĻā§āϧāϤāĻž" +msgstr "" #: src/SUMMARY.md src/chromium/interoperability-with-cpp/error-handling.md msgid "CXX Error Handling" -msgstr "āϏāĻŋ.āĻāĻ•ā§āϏ.āĻāĻ•ā§āϏ āĻ¤ā§āϰ⧁āϟāĻŋ āĻĒāϰāĻŋāϚāĻžāϞāύāĻž" +msgstr "" #: src/SUMMARY.md msgid "Error Handling: QR Example" -msgstr "āĻ¤ā§āϰ⧁āϟāĻŋ āĻĒāϰāĻŋāϚāĻžāϞāύāĻž: āĻ•āĻŋāω.āφāϰ āωāĻĻāĻžāĻšāϰāĻŖ" +msgstr "" #: src/SUMMARY.md msgid "Error Handling: PNG Example" -msgstr "āĻ¤ā§āϰ⧁āϟāĻŋ āĻĒāϰāĻŋāϚāĻžāϞāύāĻž: āĻĒāĻŋ.āĻāύ.āϜāĻŋ āωāĻĻāĻžāĻšāϰāĻŖ" +msgstr "" #: src/SUMMARY.md msgid "Using CXX in Chromium" -msgstr "āĻ•ā§āϰ⧋āĻŽāĻŋ⧟āĻŽ āĻ āϏāĻŋ.āĻāĻ•ā§āϏ.āĻāĻ•ā§āϏ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž" +msgstr "" #: src/SUMMARY.md src/chromium/adding-third-party-crates.md msgid "Adding Third Party Crates" -msgstr "āϤ⧃āĻ¤ā§€ā§Ÿ āĻĒāĻ•ā§āώ⧇āϰ āĻ•ā§āϰ⧇āϟ āĻœā§‹ā§œāĻž" +msgstr "" #: src/SUMMARY.md msgid "Configuring Cargo.toml" -msgstr "Cargo.toml āϏāĻœā§āϜāĻŋāϤ āĻ•āϰāĻž" +msgstr "" #: src/SUMMARY.md #: src/chromium/adding-third-party-crates/configuring-gnrt-config-toml.md msgid "Configuring `gnrt_config.toml`" -msgstr "`gnrt_config.toml` āϏāĻœā§āϜāĻŋāϤ āĻ•āϰāĻž" +msgstr "" #: src/SUMMARY.md src/chromium/adding-third-party-crates/downloading-crates.md msgid "Downloading Crates" -msgstr "āĻ•ā§āϰ⧇āϟ āĻĄāĻžāωāύāϞ⧋āĻĄ āĻ•āϰāĻž" +msgstr "" #: src/SUMMARY.md #: src/chromium/adding-third-party-crates/generating-gn-build-rules.md msgid "Generating `gn` Build Rules" -msgstr "`gn` āύāĻŋāĻ°ā§āĻŽāĻžāĻŖ āύāĻŋ⧟āĻŽāĻžāĻŦāϞ⧀ āωāĻ¤ā§āĻĒāĻžāĻĻāύ āĻ•āϰāĻž" +msgstr "" #: src/SUMMARY.md src/chromium/adding-third-party-crates/resolving-problems.md msgid "Resolving Problems" -msgstr "āϏāĻŽāĻ¸ā§āϝāĻž āϏāĻŽāĻžāϧāĻžāύ āĻ•āϰāĻž" +msgstr "" #: src/SUMMARY.md #: src/chromium/adding-third-party-crates/resolving-problems/build-scripts-which-generate-code.md msgid "Build Scripts Which Generate Code" -msgstr "āϕ⧋āĻĄ āĻ‰ā§ŽāĻĒāĻžāĻĻāύ āĻ•āϰ⧇ āĻāĻŽāύ āύāĻŋāĻ°ā§āĻŽāĻžāĻŖ āύāĻŋ⧟āĻŽāϏāĻŽā§‚āĻš" +msgstr "" #: src/SUMMARY.md #: src/chromium/adding-third-party-crates/resolving-problems/build-scripts-which-take-arbitrary-actions.md msgid "Build Scripts Which Build C++ or Take Arbitrary Actions" -msgstr "āύāĻŋāĻ°ā§āĻŽāĻžāĻŖ āύāĻŋ⧟āĻŽāϏāĻŽā§‚āĻš āϝāĻž C++ āύāĻŋāĻ°ā§āĻŽāĻžāĻŖ āĻ•āϰ⧇ āĻŦāĻž āϕ⧋āύ⧋ āχāĻšā§āĻ›āĻžāĻŽāϤ āĻ•āĻžāϜ āĻ•āϰ⧇" +msgstr "" #: src/SUMMARY.md #: src/chromium/adding-third-party-crates/depending-on-a-crate.md msgid "Depending on a Crate" -msgstr "āĻ•ā§āϰ⧇āϟ āĻāϰ āĻ“āĻĒāϰ⧇ āύāĻŋāĻ°ā§āĻ­āϰ āĻ•āϰ⧇ āϝ⧇" +msgstr "" #: src/SUMMARY.md msgid "Reviews and Audits" -msgstr "āĻĒāĻ°ā§āϝāĻžāϞ⧋āϚāύāĻž āĻāĻŦāĻ‚ āύāĻŋāϰ⧀āĻ•ā§āώāĻž" +msgstr "" #: src/SUMMARY.md msgid "Checking into Chromium Source Code" -msgstr "Chromium āĻāϰ āĻŽā§‚āϞ āϕ⧋āĻĄ āĻ āĻĸā§‹āĻ•āĻž" +msgstr "" #: src/SUMMARY.md src/chromium/adding-third-party-crates/keeping-up-to-date.md msgid "Keeping Crates Up to Date" -msgstr "āĻ•ā§āϰ⧇āϟāϗ⧁āϞāĻŋ āĻ…āĻŦāĻžāϧ āϰāĻžāĻ–āĻž" +msgstr "" #: src/SUMMARY.md msgid "Bringing It Together - Exercise" -msgstr "āϏāĻŦāĻ•āĻŋāϛ⧁ āĻāĻ•āϏāĻžāĻĨ⧇ āĻāύ⧇ āĻ•āĻŋāϛ⧁ āĻŦāĻžāύāĻžāύ⧋ - āĻ…āύ⧁āĻļā§€āϞāύ⧀" +msgstr "" #: src/SUMMARY.md src/exercises/chromium/solutions.md msgid "Exercise Solutions" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ⧀āϰ āϏāĻŽāĻžāϧāĻžāύāϏāĻŽā§‚āĻš" +msgstr "" #: src/SUMMARY.md msgid "Bare Metal: Morning" -msgstr "Bare Metal: āϏāĻ•āĻžāϞ" +msgstr "" #: src/SUMMARY.md src/bare-metal/no_std.md msgid "`no_std`" -msgstr "`no_std`" +msgstr "" #: src/SUMMARY.md msgid "A Minimal Example" -msgstr "āĻāĻ•āϟāĻŋ āĻ¨ā§āϝ⧂āύāϤāĻŽ āωāĻĻāĻžāĻšāϰāĻŖ" +msgstr "" #: src/SUMMARY.md src/bare-metal/no_std.md src/bare-metal/alloc.md msgid "`alloc`" -msgstr "`alloc`" +msgstr "" #: src/SUMMARY.md src/bare-metal/microcontrollers.md msgid "Microcontrollers" -msgstr "āĻŽāĻžāχāĻ•ā§āϰ⧋āĻ•āĻ¨ā§āĻŸā§āϰ⧋āϞāĻžāϰ" +msgstr "" #: src/SUMMARY.md src/bare-metal/microcontrollers/mmio.md msgid "Raw MMIO" -msgstr "āĻ…āĻĒāĻ•ā§āĻŦ āĻāĻŽ . āĻāĻŽ . āφāχ . āĻ“" +msgstr "" #: src/SUMMARY.md msgid "PACs" -msgstr "āĻĒāĻŋ . āĻ . āϏāĻŋ" +msgstr "" #: src/SUMMARY.md msgid "HAL Crates" -msgstr "HAL Crates" +msgstr "" #: src/SUMMARY.md msgid "Board Support Crates" -msgstr "Board Support Crates" +msgstr "" #: src/SUMMARY.md msgid "The Type State Pattern" -msgstr "āϟāĻžāχāĻĒ āĻāϰ āĻ…āĻŦāĻ¸ā§āĻĨāĻž āĻŦāĻŋāĻŦ⧇āϚāύāĻž āĻ•āϰ⧇ āĻāĻŽāύ āĻĒā§āϝāĻžāϟāĻžāĻ°ā§āύ" +msgstr "" #: src/SUMMARY.md src/bare-metal/microcontrollers/embedded-hal.md msgid "`embedded-hal`" -msgstr "`embedded-hal`" +msgstr "" #: src/SUMMARY.md src/bare-metal/microcontrollers/probe-rs.md msgid "`probe-rs` and `cargo-embed`" -msgstr "`probe-rs` āĻāĻŦāĻ‚ `cargo-embed`" +msgstr "" #: src/SUMMARY.md src/bare-metal/microcontrollers/debugging.md msgid "Debugging" -msgstr "āĻĄāĻŋāĻŦāĻžāĻ—āĻŋāĻ‚" +msgstr "" #: src/SUMMARY.md msgid "Other Projects" -msgstr "āφāϰāĻ“ āĻĒā§āϰāĻ•āĻ˛ā§āĻĒāϗ⧁āϞāĻŋ" +msgstr "" + +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/exercises/bare-metal/morning.md src/exercises/bare-metal/afternoon.md +#: src/concurrency/welcome.md src/concurrency/sync-exercises.md +#: src/concurrency/welcome-async.md src/concurrency/async-exercises.md +msgid "Exercises" +msgstr "" #: src/SUMMARY.md src/exercises/bare-metal/compass.md #: src/exercises/bare-metal/solutions-morning.md msgid "Compass" -msgstr "āĻ•āĻŽā§āĻĒāĻžāϏ" +msgstr "" -#: src/SUMMARY.md +#: src/SUMMARY.md src/concurrency/sync-exercises.md +#: src/concurrency/sync-exercises/solutions.md +#: src/concurrency/async-exercises.md +#: src/concurrency/async-exercises/solutions.md msgid "Solutions" -msgstr "āϏāĻŽāĻžāϧāĻžāύāϏāĻŽā§‚āĻš" +msgstr "" #: src/SUMMARY.md msgid "Bare Metal: Afternoon" -msgstr "āĻŦā§‡ā§ŸāĻžāϰ āĻŽā§‡āϟāĻžāϞ: āĻĻ⧁āĻĒ⧁āϰāĻŦ⧇āϞāĻž" +msgstr "" #: src/SUMMARY.md msgid "Application Processors" -msgstr "āĻāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āĻĒā§āϰāϏ⧇āϏāϰ" +msgstr "" #: src/SUMMARY.md src/bare-metal/aps/entry-point.md msgid "Getting Ready to Rust" -msgstr "āϰāĻžāĻ¸ā§āĻŸā§‡āϰ āϜāĻ¨ā§āϝ⧇ āĻĒā§āϰāĻ¸ā§āϤ⧁āϤ āĻšāĻ“ā§ŸāĻž" +msgstr "" #: src/SUMMARY.md msgid "Inline Assembly" -msgstr "Inline Assembly" +msgstr "" #: src/SUMMARY.md msgid "MMIO" -msgstr "MMIO" +msgstr "" #: src/SUMMARY.md msgid "Let's Write a UART Driver" -msgstr "āϚāϞ⧁āύ āĻāĻ•āϟāĻŋ UART Driver āϞāĻŋāĻ–āĻŋ" +msgstr "" #: src/SUMMARY.md msgid "More Traits" -msgstr "āφāϰāĻ“ Traits" +msgstr "" + +#: src/SUMMARY.md src/bare-metal/aps/safemmio/using.md +msgid "Using It" +msgstr "" #: src/SUMMARY.md msgid "A Better UART Driver" -msgstr "āĻāĻ•āϟāĻŋ āωāĻ¨ā§āύāϤāϰ UART āĻĄā§āϰāĻžāχāĻ­āĻžāϰ" +msgstr "" #: src/SUMMARY.md src/bare-metal/aps/better-uart/bitflags.md msgid "Bitflags" -msgstr "Bitflags" +msgstr "" #: src/SUMMARY.md msgid "Multiple Registers" -msgstr "āĻāĻ•āĻžāϧāĻŋāĻ• āϰ⧇āϜāĻŋāĻ¸ā§āϟāĻžāϰāϏ" +msgstr "" #: src/SUMMARY.md src/bare-metal/aps/better-uart/driver.md +#: src/bare-metal/aps/safemmio/driver.md msgid "Driver" -msgstr "āϚāĻžāϞāĻ• āĻŦāĻž āĻĄā§āϰāĻžāχāĻ­āĻžāϰ" +msgstr "" + +#: src/SUMMARY.md src/bare-metal/aps/safemmio/registers.md +msgid "safe-mmio" +msgstr "" + +#: src/SUMMARY.md src/error-handling/result.md src/bare-metal/aps/exceptions.md +#: src/bare-metal/aps/aarch64-rt/exceptions.md +msgid "Exceptions" +msgstr "" + +#: src/SUMMARY.md src/bare-metal/aps/aarch64-rt.md +msgid "aarch64-rt" +msgstr "" #: src/SUMMARY.md -msgid "Using It" -msgstr "āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž" - -#: src/SUMMARY.md src/bare-metal/aps/exceptions.md -msgid "Exceptions" -msgstr "āĻŦā§āϝāϤāĻŋāĻ•ā§āϰāĻŽ" +msgid "Useful Crates" +msgstr "" #: src/SUMMARY.md src/bare-metal/useful-crates/zerocopy.md msgid "`zerocopy`" -msgstr "`zerocopy`" +msgstr "" #: src/SUMMARY.md src/bare-metal/useful-crates/aarch64-paging.md msgid "`aarch64-paging`" -msgstr "`aarch64-paging`" +msgstr "" #: src/SUMMARY.md src/bare-metal/useful-crates/buddy_system_allocator.md msgid "`buddy_system_allocator`" -msgstr "`buddy_system_allocator`" +msgstr "" #: src/SUMMARY.md src/bare-metal/useful-crates/tinyvec.md msgid "`tinyvec`" -msgstr "`tinyvec`" +msgstr "" #: src/SUMMARY.md src/bare-metal/useful-crates/spin.md msgid "`spin`" -msgstr "`spin`" +msgstr "" + +#: src/SUMMARY.md src/bare-metal/android.md +msgid "Bare-Metal on Android" +msgstr "" #: src/SUMMARY.md msgid "`vmbase`" -msgstr "`vmbase`" +msgstr "" #: src/SUMMARY.md msgid "RTC Driver" -msgstr "RTC Driver" +msgstr "" #: src/SUMMARY.md msgid "Concurrency: Morning" -msgstr "Concurrency: āϏāĻ•āĻžāϞ" +msgstr "" -#: src/SUMMARY.md src/concurrency/threads.md +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/concurrency/welcome.md src/concurrency/threads.md msgid "Threads" -msgstr "āϏāĻŽā§āĻĒāĻžāĻĻāύāĻžāϰ āϏ⧁āϤ⧋" +msgstr "" -#: src/SUMMARY.md src/concurrency/scoped-threads.md +#: src/SUMMARY.md src/concurrency/threads.md src/concurrency/threads/plain.md +msgid "Plain Threads" +msgstr "" + +#: src/SUMMARY.md src/concurrency/threads.md src/concurrency/threads/scoped.md msgid "Scoped Threads" -msgstr "āĻ¸ā§āϕ⧋āĻĒāĻĄ Threads" +msgstr "" + +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/concurrency/welcome.md src/concurrency/channels.md +msgid "Channels" +msgstr "" #: src/SUMMARY.md src/concurrency/channels.md -msgid "Channels" -msgstr "āύāĻžāϞāĻž āĻŦāĻž āĻšā§āϝāĻžāύ⧇āϞ" +#: src/concurrency/channels/senders-receivers.md +msgid "Senders and Receivers" +msgstr "" -#: src/SUMMARY.md src/concurrency/channels/unbounded.md +#: src/SUMMARY.md src/concurrency/channels.md +#: src/concurrency/channels/unbounded.md msgid "Unbounded Channels" -msgstr "āϏ⧀āĻŽāĻžāĻšā§€āύ āĻšā§āϝāĻžāύ⧇āϞ" +msgstr "" -#: src/SUMMARY.md src/concurrency/channels/bounded.md +#: src/SUMMARY.md src/concurrency/channels.md +#: src/concurrency/channels/bounded.md msgid "Bounded Channels" -msgstr "āφāĻŦāĻĻā§āϧ āĻšā§āϝāĻžāύ⧇āϞ" +msgstr "" #: src/SUMMARY.md src/concurrency/send-sync.md msgid "`Send` and `Sync`" -msgstr "`Send` āĻāĻŦāĻ‚ `Sync`" +msgstr "" + +#: src/SUMMARY.md src/concurrency/send-sync.md +#: src/concurrency/send-sync/marker-traits.md +msgid "Marker Traits" +msgstr "" #: src/SUMMARY.md src/concurrency/send-sync/send.md msgid "`Send`" -msgstr "`Send`" +msgstr "" #: src/SUMMARY.md src/concurrency/send-sync/sync.md msgid "`Sync`" -msgstr "`Sync`" +msgstr "" -#: src/SUMMARY.md src/concurrency/send-sync/examples.md +#: src/SUMMARY.md src/concurrency/send-sync.md +#: src/concurrency/send-sync/examples.md msgid "Examples" -msgstr "āωāĻĻāĻžāĻšāϰāĻŖāϏāĻŽā§‚āĻš" +msgstr "" -#: src/SUMMARY.md src/concurrency/shared_state.md +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/concurrency/welcome.md src/concurrency/shared-state.md msgid "Shared State" -msgstr "āĻ…āĻ‚āĻļāĻŋāĻĻāĻžāϰ⧀ āĻŽāĻžāϞāĻŋāĻ•āĻžāύāĻž āĻŦāĻŋāĻ­āĻžāϜāĻŋāϤ āĻ…āĻŦāĻ¸ā§āĻĨāĻž āĻŦāĻž āĻ¸ā§āĻŸā§‡āϟ" +msgstr "" -#: src/SUMMARY.md src/concurrency/shared_state/arc.md +#: src/SUMMARY.md src/concurrency/shared-state/arc.md msgid "`Arc`" -msgstr "`Arc`" +msgstr "" -#: src/SUMMARY.md src/concurrency/shared_state/mutex.md +#: src/SUMMARY.md src/concurrency/shared-state/mutex.md msgid "`Mutex`" -msgstr "`Mutex`" +msgstr "" #: src/SUMMARY.md src/memory-management/review.md -#: src/error-handling/try-conversions.md -#: src/concurrency/shared_state/example.md +#: src/error-handling/try-conversions.md src/concurrency/shared-state.md +#: src/concurrency/shared-state/example.md msgid "Example" -msgstr "āωāĻĻāĻžāĻšāϰāĻŖ" +msgstr "" -#: src/SUMMARY.md src/exercises/concurrency/dining-philosophers.md -#: src/exercises/concurrency/solutions-morning.md +#: src/SUMMARY.md src/concurrency/sync-exercises.md +#: src/concurrency/sync-exercises/dining-philosophers.md +#: src/concurrency/sync-exercises/solutions.md +#: src/concurrency/async-exercises.md msgid "Dining Philosophers" -msgstr "Dining āĻĻāĻžāĻ°ā§āĻļāύāĻŋāĻ•" +msgstr "" -#: src/SUMMARY.md src/exercises/concurrency/link-checker.md +#: src/SUMMARY.md src/concurrency/sync-exercises.md +#: src/concurrency/sync-exercises/link-checker.md msgid "Multi-threaded Link Checker" -msgstr "āĻŽāĻžāĻ˛ā§āϟāĻŋ āĻĨā§āϰ⧇āĻĄā§‡āĻĄ āϞāĻŋāĻ™ā§āĻ• āĻšā§‡āĻ•āĻžāϰ" +msgstr "" #: src/SUMMARY.md msgid "Concurrency: Afternoon" -msgstr "āϏāĻŽāĻŦāĻ°ā§āϤ⧀āĻļā§€āϞāϤāĻž: āĻĻ⧁āĻĒ⧁āϰāĻŦ⧇āϞāĻž" +msgstr "" -#: src/SUMMARY.md +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/concurrency/welcome-async.md src/concurrency/async.md msgid "Async Basics" -msgstr "Async Basics" +msgstr "" -#: src/SUMMARY.md src/async/async-await.md +#: src/SUMMARY.md src/concurrency/async/async-await.md msgid "`async`/`await`" -msgstr "`async`/`await`" +msgstr "" -#: src/SUMMARY.md src/async/futures.md +#: src/SUMMARY.md src/concurrency/async.md src/concurrency/async/futures.md msgid "Futures" -msgstr "āĻ­āĻŦāĻŋāĻˇā§āĻ¯ā§Ž" +msgstr "" -#: src/SUMMARY.md src/async/runtimes.md +#: src/SUMMARY.md src/concurrency/async.md +#: src/concurrency/async/state-machine.md +msgid "State Machine" +msgstr "" + +#: src/SUMMARY.md src/concurrency/async.md src/concurrency/async/runtimes.md msgid "Runtimes" -msgstr "āϰāĻžāύāϟāĻžāχāĻŽ" +msgstr "" -#: src/SUMMARY.md src/async/runtimes/tokio.md +#: src/SUMMARY.md src/concurrency/async/runtimes/tokio.md msgid "Tokio" -msgstr "Tokio" +msgstr "" -#: src/SUMMARY.md src/exercises/concurrency/link-checker.md src/async/tasks.md -#: src/exercises/concurrency/chat-app.md +#: src/SUMMARY.md src/concurrency/sync-exercises/link-checker.md +#: src/concurrency/async.md src/concurrency/async/tasks.md +#: src/concurrency/async-exercises/chat-app.md msgid "Tasks" -msgstr "Tasks-āĻ•āĻ°ā§āĻŽ" +msgstr "" -#: src/SUMMARY.md src/async/channels.md +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/concurrency/welcome-async.md src/concurrency/async-control-flow.md +msgid "Channels and Control Flow" +msgstr "" + +#: src/SUMMARY.md src/concurrency/async-control-flow.md +#: src/concurrency/async-control-flow/channels.md msgid "Async Channels" -msgstr "āĻ…āϏāĻŽāύāĻŋāϝāĻŧāϤ āĻšā§āϝāĻžāύ⧇āϞ" +msgstr "" -#: src/SUMMARY.md -msgid "Control Flow" -msgstr "āĻĒā§āϰāĻŦāĻžāĻš āύāĻŋāϝāĻŧāĻ¨ā§āĻ¤ā§āϰāĻŖ" - -#: src/SUMMARY.md src/async/control-flow/join.md +#: src/SUMMARY.md src/concurrency/async-control-flow.md +#: src/concurrency/async-control-flow/join.md msgid "Join" -msgstr "āĻœā§‹ā§œāĻž" +msgstr "" -#: src/SUMMARY.md src/async/control-flow/select.md +#: src/SUMMARY.md src/concurrency/async-control-flow.md +#: src/concurrency/async-control-flow/select.md msgid "Select" -msgstr "āύāĻŋāĻ°ā§āĻŦāĻžāϚāύ āĻ•āϰāĻž" +msgstr "" -#: src/SUMMARY.md +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/concurrency/welcome-async.md src/concurrency/async-pitfalls.md msgid "Pitfalls" -msgstr "āĻ•ā§āώāϤāĻŋ" +msgstr "" + +#: src/SUMMARY.md src/concurrency/async-pitfalls.md +msgid "Blocking the Executor" +msgstr "" + +#: src/SUMMARY.md src/concurrency/async-pitfalls/pin.md +msgid "`Pin`" +msgstr "" + +#: src/SUMMARY.md src/concurrency/async-pitfalls.md +#: src/concurrency/async-pitfalls/async-traits.md +msgid "Async Traits" +msgstr "" + +#: src/SUMMARY.md src/concurrency/async-pitfalls.md +#: src/concurrency/async-pitfalls/cancellation.md +msgid "Cancellation" +msgstr "" + +#: src/SUMMARY.md src/concurrency/async-exercises.md +#: src/concurrency/async-exercises/chat-app.md +#: src/concurrency/async-exercises/solutions.md +msgid "Broadcast Chat Application" +msgstr "" + +#: src/SUMMARY.md src/running-the-course/course-structure.md +msgid "Idiomatic Rust" +msgstr "" + +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/idiomatic/welcome.md src/idiomatic/foundations-api-design.md +msgid "Foundations of API Design" +msgstr "" + +#: src/SUMMARY.md src/idiomatic/foundations-api-design.md +#: src/idiomatic/foundations-api-design/meaningful-doc-comments.md +msgid "Meaningful Doc Comments" +msgstr "" #: src/SUMMARY.md -msgid "Blocking the Executor" -msgstr "āĻāĻ•ā§āϏāĻŋāĻ•āĻŋāωāϟāϰ āĻŦā§āϞāĻ• āĻ•āϰāĻž" +msgid "Who Are You Writing For?" +msgstr "" -#: src/SUMMARY.md src/async/pitfalls/pin.md -msgid "`Pin`" -msgstr "`Pin`" +#: src/SUMMARY.md +msgid "Library vs Application docs" +msgstr "" -#: src/SUMMARY.md src/async/pitfalls/async-traits.md -msgid "Async Traits" -msgstr "Async Traits" +#: src/SUMMARY.md +msgid "Anatomy of a Doc Comment" +msgstr "" -#: src/SUMMARY.md src/async/pitfalls/cancellation.md -msgid "Cancellation" -msgstr "āĻŦāĻžāϤāĻŋāϞāĻ•āϰāĻŖ" +#: src/SUMMARY.md +msgid "Name Drop and Signpost" +msgstr "" -#: src/SUMMARY.md src/exercises/concurrency/chat-app.md -#: src/exercises/concurrency/solutions-afternoon.md -msgid "Broadcast Chat Application" -msgstr "āϏāĻŽā§āĻĒā§āϰāϚāĻžāϰ āĻ•āϰ⧇ āĻ•āĻĨā§‹āĻĒāĻ•āĻĨāύ āĻ•āϰāĻžāϰ āĻāĻĒā§āϞāĻŋāϕ⧇āĻļāύ" +#: src/SUMMARY.md +msgid "Avoid Redundancy" +msgstr "" + +#: src/SUMMARY.md +msgid "Name and Signature are Not Enough" +msgstr "" + +#: src/SUMMARY.md +msgid "What and Why, not How and Where" +msgstr "" + +#: src/SUMMARY.md src/idiomatic/foundations-api-design.md +#: src/idiomatic/foundations-api-design/predictable-api.md +msgid "Predictable API" +msgstr "" + +#: src/SUMMARY.md +msgid "Naming conventions" +msgstr "" + +#: src/SUMMARY.md +msgid "New" +msgstr "" + +#: src/SUMMARY.md +msgid "Get" +msgstr "" + +#: src/SUMMARY.md +msgid "Push" +msgstr "" + +#: src/SUMMARY.md +msgid "Is" +msgstr "" + +#: src/SUMMARY.md +msgid "Mut" +msgstr "" + +#: src/SUMMARY.md +msgid "With: Constructor" +msgstr "" + +#: src/SUMMARY.md +msgid "With: Copy-and-change" +msgstr "" + +#: src/SUMMARY.md +msgid "With: Closures" +msgstr "" + +#: src/SUMMARY.md +msgid "With in normal use" +msgstr "" + +#: src/SUMMARY.md +msgid "Try" +msgstr "" + +#: src/SUMMARY.md +msgid "From" +msgstr "" + +#: src/SUMMARY.md +msgid "Into" +msgstr "" + +#: src/SUMMARY.md +msgid "Into inner" +msgstr "" + +#: src/SUMMARY.md +msgid "By" +msgstr "" + +#: src/SUMMARY.md +msgid "Unchecked" +msgstr "" + +#: src/SUMMARY.md +msgid "To" +msgstr "" + +#: src/SUMMARY.md +msgid "As and Ref" +msgstr "" + +#: src/SUMMARY.md +msgid "Raw parts" +msgstr "" + +#: src/SUMMARY.md +msgid "Implementing Common Traits" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/debug.md +msgid "Debug" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialeq-eq.md +msgid "PartialEq and Eq" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialord-ord.md +msgid "PartialOrd and Ord" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/hash.md +msgid "Hash" +msgstr "" + +#: src/SUMMARY.md src/memory-management.md src/memory-management/clone.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/clone.md +msgid "Clone" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/copy.md +msgid "Copy" +msgstr "" + +#: src/SUMMARY.md +msgid "Serialize and Deserialize" +msgstr "" + +#: src/SUMMARY.md src/std-traits.md +msgid "From and Into" +msgstr "" + +#: src/SUMMARY.md +msgid "TryFrom and TryInto" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/display.md +msgid "Display" +msgstr "" + +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/idiomatic/welcome.md src/idiomatic/leveraging-the-type-system.md +msgid "Leveraging the Type System" +msgstr "" + +#: src/SUMMARY.md src/idiomatic/leveraging-the-type-system.md +#: src/idiomatic/leveraging-the-type-system/newtype-pattern.md +msgid "Newtype Pattern" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/semantic-confusion.md +msgid "Semantic Confusion" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/parse-don-t-validate.md +msgid "Parse, Don't Validate" +msgstr "" + +#: src/SUMMARY.md +msgid "Is It Encapsulated?" +msgstr "" + +#: src/SUMMARY.md src/idiomatic/leveraging-the-type-system.md +msgid "RAII" +msgstr "" + +#: src/SUMMARY.md +msgid "Drop Skipped" +msgstr "" + +#: src/SUMMARY.md src/concurrency/shared-state.md +msgid "Mutex" +msgstr "" + +#: src/SUMMARY.md src/idiomatic/leveraging-the-type-system/raii/drop_guards.md +msgid "Drop Guards" +msgstr "" + +#: src/SUMMARY.md +msgid "Drop Bomb" +msgstr "" + +#: src/SUMMARY.md +msgid "Drop Bomb Forget" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/leveraging-the-type-system/raii/forget_and_drop.md +msgid "forget and drop functions" +msgstr "" + +#: src/SUMMARY.md +msgid "Scope Guard" +msgstr "" + +#: src/SUMMARY.md +msgid "Drop Option" +msgstr "" + +#: src/SUMMARY.md src/idiomatic/leveraging-the-type-system.md +#: src/idiomatic/leveraging-the-type-system/extension-traits.md +msgid "Extension Traits" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-foreign-types.md +msgid "Extending Foreign Types" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/leveraging-the-type-system/extension-traits/method-resolution-conflicts.md +msgid "Method Resolution Conflicts" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/leveraging-the-type-system/extension-traits/trait-method-conflicts.md +msgid "Trait Method Conflicts" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "Extending Other Traits" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/leveraging-the-type-system/extension-traits/should-i-define-an-extension-trait.md +msgid "Should I Define An Extension Trait?" +msgstr "" + +#: src/SUMMARY.md src/idiomatic/leveraging-the-type-system.md +msgid "Typestate Pattern" +msgstr "" + +#: src/SUMMARY.md +msgid "Typestate Pattern Example" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-advanced.md +msgid "Beyond Simple Typestate" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics.md +msgid "Typestate Pattern with Generics" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/root.md +msgid "Serializer: implement Root" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/struct.md +msgid "Serializer: implement Struct" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/property.md +msgid "Serializer: implement Property" +msgstr "" + +#: src/SUMMARY.md +msgid "Serializer: Complete implementation" +msgstr "" + +#: src/SUMMARY.md src/idiomatic/leveraging-the-type-system.md +msgid "Borrow checking invariants" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md +msgid "Lifetimes and Borrows: the Abstract Rules" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +msgid "Single-use values" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "Mutually Exclusive References / \"Aliasing XOR Mutability\"" +msgstr "" + +#: src/SUMMARY.md +msgid "PhantomData and Types" +msgstr "" + +#: src/SUMMARY.md +msgid "PhantomData and Types (implementation)" +msgstr "" + +#: src/SUMMARY.md +msgid "PhantomData: Lifetimes for External Resources" +msgstr "" + +#: src/SUMMARY.md +msgid "PhantomData: OwnedFd & BorrowedFd" +msgstr "" + +#: src/SUMMARY.md src/idiomatic/leveraging-the-type-system.md +#: src/idiomatic/leveraging-the-type-system/token-types.md +msgid "Token Types" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/leveraging-the-type-system/token-types/permission-tokens.md +msgid "Permission Tokens" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/leveraging-the-type-system/token-types/mutex-guard.md +msgid "Token Types with Data: Mutex Guards" +msgstr "" + +#: src/SUMMARY.md +msgid "Branded pt 1: Variable-specific tokens" +msgstr "" + +#: src/SUMMARY.md +msgid "Branded pt 2: `PhantomData` and Lifetime Subtyping" +msgstr "" + +#: src/SUMMARY.md +msgid "Branded pt 3: Implementation" +msgstr "" + +#: src/SUMMARY.md +msgid "Branded pt 4: Branded types in action." +msgstr "" + +#: src/SUMMARY.md src/running-the-course/course-structure.md +#: src/idiomatic/welcome.md src/idiomatic/polymorphism.md +msgid "Polymorphism" +msgstr "" + +#: src/SUMMARY.md src/idiomatic/polymorphism/refresher.md +msgid "Refresher" +msgstr "" + +#: src/SUMMARY.md src/idiomatic/polymorphism/refresher/deriving-traits.md +msgid "Deriving Traits" +msgstr "" + +#: src/SUMMARY.md +msgid "Default Implementations" +msgstr "" + +#: src/SUMMARY.md +msgid "Blanket Implementations" +msgstr "" + +#: src/SUMMARY.md +msgid "Conditional Methods" +msgstr "" + +#: src/SUMMARY.md src/idiomatic/polymorphism/refresher/orphan-rule.md +msgid "Orphan Rule" +msgstr "" + +#: src/SUMMARY.md +msgid "Statically Sized and Dynamically Sized types" +msgstr "" + +#: src/SUMMARY.md src/idiomatic/polymorphism/refresher/monomorphization.md +msgid "Monomorphization and Binary Size" +msgstr "" + +#: src/SUMMARY.md +msgid "From OOP to Rust" +msgstr "" + +#: src/SUMMARY.md +msgid "Inheritance" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/polymorphism/from-oop-to-rust/why-no-inheritance.md +msgid "Why no Inheritance in Rust?" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/polymorphism/from-oop-to-rust/switch-perspective.md +msgid "Inheritance from Rust's Perspective" +msgstr "" + +#: src/SUMMARY.md +msgid "\"Inheritance\" in Rust and Supertraits" +msgstr "" + +#: src/SUMMARY.md src/idiomatic/polymorphism/from-oop-to-rust/composition.md +msgid "Composition over Inheritance" +msgstr "" + +#: src/SUMMARY.md +msgid "Trait Objects and Dynamic Dispatch" +msgstr "" + +#: src/SUMMARY.md +msgid "Dyn Compatibility" +msgstr "" + +#: src/SUMMARY.md +msgid "Generics vs Trait Objects" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/limits.md +msgid "Limits of Trait Objects" +msgstr "" + +#: src/SUMMARY.md +msgid "Heterogeneous Collections" +msgstr "" + +#: src/SUMMARY.md +msgid "The `Any` Trait" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/pitfalls.md +msgid "Pitfall: Reaching too quickly for `dyn Trait`" +msgstr "" + +#: src/SUMMARY.md +msgid "Sealed Traits" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/polymorphism/from-oop-to-rust/sealing-with-enums.md +msgid "Sealing with Enums" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/polymorphism/from-oop-to-rust/sticking-with-traits.md +msgid "Traits for Polymorphism users can extend" +msgstr "" + +#: src/SUMMARY.md +#: src/idiomatic/polymorphism/from-oop-to-rust/problem-solving.md +msgid "Problem solving: Break Down the Problem" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/introduction.md +msgid "Introduction" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/introduction.md +#: src/unsafe-deep-dive/introduction/definition.md +msgid "Defining Unsafe Rust" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/introduction.md +msgid "Purpose of the unsafe keyword" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/introduction.md +msgid "Two roles of the unsafe keyword" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/introduction.md +msgid "Warm Up Examples" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/introduction/warm-up/unsafe-block.md +msgid "Using an unsafe block" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/introduction/warm-up/unsafe-fn.md +msgid "Defining an unsafe function" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/introduction/warm-up/unsafe-impl.md +msgid "Implementing an unsafe trait" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/introduction/warm-up/unsafe-trait.md +msgid "Defining an unsafe trait" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/introduction.md +msgid "Characteristics of Unsafe Rust" +msgstr "" + +#: src/SUMMARY.md +msgid "Dangerous" +msgstr "" + +#: src/SUMMARY.md +msgid "Sometimes necessary" +msgstr "" + +#: src/SUMMARY.md +msgid "Sometimes useful" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/introduction.md +msgid "Responsibility shift" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/introduction.md +msgid "Stronger development workflow required" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/introduction.md +msgid "Example: may_overflow" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/safety-preconditions.md +msgid "Safety Preconditions" +msgstr "" + +#: src/SUMMARY.md +msgid "Common Preconditions" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/safety-preconditions/getter.md +msgid "Getter example" +msgstr "" + +#: src/SUMMARY.md +#: src/unsafe-deep-dive/safety-preconditions/semantic-preconditions.md +msgid "Semantic preconditions" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/safety-preconditions/u8-to-bool.md +msgid "Example: u8 to bool" +msgstr "" + +#: src/SUMMARY.md +msgid "Determining preconditions" +msgstr "" + +#: src/SUMMARY.md +msgid "Example: references" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/safety-preconditions/defining.md +msgid "Defining your own preconditions" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/safety-preconditions/ascii.md +msgid "Example: ASCII Type" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/rules-of-the-game.md +msgid "Rules of the game" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/rules-of-the-game/rust-is-sound.md +msgid "Rust is sound" +msgstr "" + +#: src/SUMMARY.md +msgid "Copying memory" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/introduction/responsibility-shift.md +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/safe.md +msgid "Safe Rust" +msgstr "" + +#: src/SUMMARY.md +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/encapsulated-unsafe.md +msgid "Encapsulated Unsafe Rust" +msgstr "" + +#: src/SUMMARY.md +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +msgid "Exposed Unsafe Rust" +msgstr "" + +#: src/SUMMARY.md +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/documented-safety-preconditions.md +msgid "Documented safety preconditions" +msgstr "" + +#: src/SUMMARY.md +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/crying-wolf.md +msgid "Crying Wolf" +msgstr "" + +#: src/SUMMARY.md +msgid "3 shapes of sound Rust" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/rules-of-the-game/soundness-proof.md +msgid "Soundness Proof" +msgstr "" + +#: src/SUMMARY.md +#: src/unsafe-deep-dive/rules-of-the-game/soundness-proof/soundness.md +msgid "Soundness" +msgstr "" + +#: src/SUMMARY.md +msgid "Corollary" +msgstr "" + +#: src/SUMMARY.md +#: src/unsafe-deep-dive/rules-of-the-game/soundness-proof/unsoundness.md +msgid "Unsoundness" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/memory-lifecycle.md +msgid "Memory Lifecycle" +msgstr "" + +#: src/SUMMARY.md +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +#: src/unsafe-deep-dive/initialization.md +msgid "Initialization" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/initialization/maybeuninit.md +msgid "MaybeUninit" +msgstr "" + +#: src/SUMMARY.md +msgid "Arrays of uninit" +msgstr "" + +#: src/SUMMARY.md +#: src/unsafe-deep-dive/initialization/maybeuninit/zeroed-method.md +msgid "MaybeUninit::zeroed()" +msgstr "" + +#: src/SUMMARY.md +msgid "ptr::write vs assignment" +msgstr "" + +#: src/SUMMARY.md +msgid "How to initialize memory" +msgstr "" + +#: src/SUMMARY.md +msgid "Partial initialization" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/pinning.md +msgid "Pinning" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/pinning.md +#: src/unsafe-deep-dive/pinning/what-pinning-is.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer.md +msgid "What pinning is" +msgstr "" + +#: src/SUMMARY.md +msgid "What a move is" +msgstr "" + +#: src/SUMMARY.md +msgid "Definition of Pin" +msgstr "" + +#: src/SUMMARY.md +msgid "Why it's difficult" +msgstr "" + +#: src/SUMMARY.md +msgid "`Unpin` trait" +msgstr "" + +#: src/SUMMARY.md +msgid "`PhantomPinned`" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/pinning.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer.md +msgid "Self-Referential Buffer Example" +msgstr "" + +#: src/SUMMARY.md +msgid "C++ implementation" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/pinning/self-referential-buffer/rust.md +msgid "Modeled in Rust" +msgstr "" + +#: src/SUMMARY.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust-raw-pointers.md +msgid "With a raw pointer" +msgstr "" + +#: src/SUMMARY.md +msgid "With an integer offset" +msgstr "" + +#: src/SUMMARY.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust-pin.md +msgid "With `Pin`" +msgstr "" + +#: src/SUMMARY.md +msgid "`Pin` and `Drop`" +msgstr "" + +#: src/SUMMARY.md +msgid "Worked Example" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/ffi.md +msgid "FFI" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/ffi/language-interop.md +msgid "Language Interop" +msgstr "" + +#: src/SUMMARY.md +msgid "Strategies" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/ffi/type-safety.md +msgid "Consideration: Type Safety" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/ffi/language-differences.md +msgid "Language differences" +msgstr "" + +#: src/SUMMARY.md +#: src/unsafe-deep-dive/ffi/language-differences/representations.md +msgid "Different representations" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/ffi/language-differences/semantics.md +msgid "Different semantics" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "Rust ↔ C" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/ffi/language-differences/cpp-and-c.md +msgid "C++ ↔ C" +msgstr "" + +#: src/SUMMARY.md src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "Rust ↔ C++" +msgstr "" + +#: src/SUMMARY.md +msgid "`abs(3)`" +msgstr "" + +#: src/SUMMARY.md +msgid "`rand(3)`" +msgstr "" + +#: src/SUMMARY.md +msgid "Exercise:C library" +msgstr "" + +#: src/SUMMARY.md +msgid "Exercise: C++ library" +msgstr "" #: src/SUMMARY.md msgid "Final Words" -msgstr "āĻšā§‚āĻĄāĻŧāĻžāĻ¨ā§āϤ āĻ•āĻŋāϛ⧁ āĻ•āĻĨāĻž" +msgstr "" #: src/SUMMARY.md src/thanks.md msgid "Thanks!" -msgstr "āϧāĻ¨ā§āϝāĻŦāĻžāĻĻ!" +msgstr "" +#. Please keep { #glossary } untranslated. #: src/SUMMARY.md src/glossary.md msgid "Glossary" -msgstr "āĻļāĻŦā§āĻĻāϕ⧋āώ" +msgstr "" #: src/SUMMARY.md msgid "Other Resources" -msgstr "āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āĻ‰ā§ŽāϏāϏāĻŽā§‚āĻš" +msgstr "" #: src/SUMMARY.md src/credits.md msgid "Credits" -msgstr "āĻ•ā§āϰ⧇āĻĄāĻŋāϟāϏ" +msgstr "" #: src/index.md msgid "" @@ -1241,14 +2258,6 @@ msgid "" "io/github/stars/google/comprehensive-rust?style=flat-square)](https://github." "com/google/comprehensive-rust/stargazers)" msgstr "" -"[![Build workflow](https://img.shields.io/github/actions/workflow/status/" -"google/comprehensive-rust/build.yml?style=flat-square)](https://github.com/" -"google/comprehensive-rust/actions/workflows/build.yml?query=branch%3Amain) [!" -"[GitHub contributors](https://img.shields.io/github/contributors/google/" -"comprehensive-rust?style=flat-square)](https://github.com/google/" -"comprehensive-rust/graphs/contributors) [![GitHub stars](https://img.shields." -"io/github/stars/google/comprehensive-rust?style=flat-square)](https://github." -"com/google/comprehensive-rust/stargazers)" #: src/index.md msgid "" @@ -1256,9 +2265,6 @@ msgid "" "course covers the full spectrum of Rust, from basic syntax to advanced " "topics like generics and error handling." msgstr "" -"āĻāϟāĻŋ Google āĻāϰ āĻ…ā§āϝāĻžāĻ¨ā§āĻĄā§āϰāϝāĻŧ⧇āĻĄ āϟāĻŋāĻŽ āĻĻā§āĻŦāĻžāϰāĻž āϤ⧈āϰāĻŋ āĻāĻ•āϟāĻŋ āϚāĻžāϰ āĻĻāĻŋāύ⧇āϰ āϰāĻžāĻ¸ā§āϟāĻļāĻŋāĻ–āĻŦāĻžāϰ āϕ⧋āĻ°ā§āϏ āϝāĻž " -"āϰāĻžāĻ¸ā§āϟ-āĻāϰ āϏāĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻ¸ā§āĻĒ⧇āĻ•āĻŸā§āϰāĻžāĻŽ, āĻŽā§ŒāϞāĻŋāĻ• āϏāĻŋāύāĻŸā§āϝāĻžāĻ•ā§āϏ āĻĨ⧇āϕ⧇ āĻļ⧁āϰ⧁ āĻ•āϰ⧇ āĻœā§‡āύ⧇āϰāĻŋāĻ• āĻāĻŦāĻ‚ āĻ¤ā§āϰ⧁āϟāĻŋ " -"āĻĒāϰāĻŋāϚāĻžāϞāύāĻžāϰ āĻŽāϤ⧋ āωāĻ¨ā§āύāϤ āĻŦāĻŋāώ⧟ āĻļāĻŋāĻ–āϤ⧇ āϏāĻžāĻšāĻžāĻ¯ā§āϝ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤" #: src/index.md msgid "" @@ -1266,64 +2272,57 @@ msgid "" "comprehensive-rust/>. If you are reading somewhere else, please check there " "for updates." msgstr "" -"āĻāχ āϕ⧋āĻ°ā§āϏ āĻāϰ āϏāĻŦāĻšā§‡ā§Ÿā§‡ āύāϤ⧁āύ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ " -"- āĻāĻ–āĻžāύ⧇ āĻĒāĻžāĻ“ā§ŸāĻž āϝāĻžāĻŦ⧇āĨ¤ āϝāĻĻāĻŋ āĻ…āĻ¨ā§āϝ āϕ⧋āĻĨāĻžāĻ“ āĻĨ⧇āϕ⧇ āφāĻĒāύāĻŋ āĻĒ⧜āϛ⧇āύ āϤāĻžāĻšāϞ⧇ āĻāχāĻ–āĻžāύ⧇ āĻāĻ•āĻŦāĻžāϰ āĻĻ⧇āϖ⧇ " -"āĻ¨ā§‡ā§ŸāĻž āĻ­āĻžāϞ⧋āĨ¤" + +#: src/index.md +msgid "" +"The course is available in other languages. Select your preferred language " +"in the top right corner of the page or check the [Translations](running-the-" +"course/translations.md) page for a list of all available translations." +msgstr "" #: src/index.md msgid "The course is also available [as a PDF](comprehensive-rust.pdf)." -msgstr "āĻāχ āϕ⧋āĻ°ā§āϏāϟāĻŋ āĻĒāĻŋ.āĻĄāĻŋ.āĻāĻĢ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡āĻ“ āωāĻĒāϞāĻŦā§āϧ āφāϛ⧇ (comprehensive-rust.pdf)āĨ¤" +msgstr "" #: src/index.md msgid "" "The goal of the course is to teach you Rust. We assume you don't know " "anything about Rust and hope to:" msgstr "" -"āϕ⧋āĻ°ā§āϏ⧇āϰ āϞāĻ•ā§āĻˇā§āϝ āĻšāϞ āφāĻĒāύāĻžāϕ⧇ āϰāĻžāĻ¸ā§āϟ āĻļ⧇āĻ–āĻžāύ⧋āĨ¤ āφāĻŽāϰāĻž āϧāϰ⧇ āύāĻŋāϞāĻžāĻŽ āφāĻĒāύāĻŋ āĻ•āĻŋāϛ⧁āχ āϜāĻžāύ⧇āύ āύāĻž āϰāĻžāĻ¸ā§āϟ " -"āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āĻāĻŦāĻ‚ āφāĻļāĻž āĻ•āϰāĻŋ:" #: src/index.md msgid "Give you a comprehensive understanding of the Rust syntax and language." -msgstr "āφāĻĒāύāĻžāϕ⧇ āϰāĻžāĻ¸ā§āϟ āϏāĻŋāύāĻŸā§āϝāĻžāĻ•ā§āϏ āĻāĻŦāĻ‚ āĻ­āĻžāώāĻž āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āĻāĻ•āϟāĻŋ āĻŦāĻŋāĻ¸ā§āϤāĻžāϰāĻŋāϤ āĻŦā§‹āĻāĻžāϝāĻŧ" +msgstr "" #: src/index.md msgid "Enable you to modify existing programs and write new programs in Rust." msgstr "" -"āφāĻĒāύāĻžāϕ⧇ āĻŦāĻŋāĻĻā§āϝāĻŽāĻžāύ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāϗ⧁āϞāĻŋ āϏāĻ‚āĻļā§‹āϧāύ āĻ•āϰāϤ⧇ āĻāĻŦāĻ‚ āϰāĻžāĻ¸ā§āϟ āĻ āύāϤ⧁āύ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽ āϞāĻŋāĻ–āϤ⧇ āϏāĻ•ā§āώāĻŽ āĻ•āϰ⧇āĨ¤" #: src/index.md msgid "Show you common Rust idioms." -msgstr "āφāĻĒāύāĻžāϕ⧇ āϏāĻžāϧāĻžāϰāĻŖ āϰāĻžāĻ¸ā§āϟ āχāĻĄāĻŋāϝāĻŧāĻŽāϏ āĻĻ⧇āĻ–āĻžāϝāĻŧāĨ¤" +msgstr "" #: src/index.md msgid "We call the first four course days Rust Fundamentals." -msgstr "āφāĻŽāϰāĻž āϕ⧋āĻ°ā§āϏ⧇āϰ āĻĒā§āϰāĻĨāĻŽ āϚāĻžāϰāϟāĻŋ āĻĻāĻŋāύāϕ⧇ āϰāĻžāĻ¸ā§āϟ āĻĢāĻžāĻ¨ā§āĻĄāĻžāĻŽā§‡āĻ¨ā§āϟāĻžāϞ āĻŦāϞāĻŋāĨ¤" +msgstr "" #: src/index.md msgid "" "Building on this, you're invited to dive into one or more specialized topics:" msgstr "" -"āĻāϟāĻŋāϰ āωāĻĒāϰ āĻ­āĻŋāĻ¤ā§āϤāĻŋ āĻ•āϰ⧇, āφāĻĒāύāĻžāϕ⧇ āĻāĻ• āĻŦāĻž āĻāĻ•āĻžāϧāĻŋāĻ• āĻŦāĻŋāĻļ⧇āώ āĻŦāĻŋāώāϝāĻŧāϗ⧁āϞāĻŋāϤ⧇ āĻĄā§āĻŦ āĻĻ⧇āĻ“ā§ŸāĻžāϰ āϜāĻ¨ā§āϝ " -"āφāĻŽāĻ¨ā§āĻ¤ā§āϰāĻŋāϤāĨ¤" #: src/index.md msgid "" "[Android](android.md): a half-day course on using Rust for Android platform " "development (AOSP). This includes interoperability with C, C++, and Java." msgstr "" -"[Android](android.md): āĻ…ā§āϝāĻžāĻ¨ā§āĻĄā§āϰāϝāĻŧ⧇āĻĄ āĻĒā§āĻ˛ā§āϝāĻžāϟāĻĢāĻ°ā§āĻŽā§‡āϰ āĻĄā§‡āϭ⧇āϞāĻĒāĻŽā§‡āĻ¨ā§āϟ (AOSP) āĻāϰ āϜāĻ¨ā§āϝ āϰāĻžāĻ¸ā§āϟ " -"āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻžāϰ āĻāĻ•āϟāĻŋ āĻ…āĻ°ā§āϧ-āĻĻāĻŋāύ⧇āϰ āϕ⧋āĻ°ā§āϏāĨ¤ āĻāϰ āĻŽāĻ§ā§āϝ⧇ C, C++ āĻāĻŦāĻ‚ Java āϏāĻš āφāĻ¨ā§āϤāσāĻ•āĻžāĻ°ā§āϝāϝ⧋āĻ—ā§āϝāϤāĻž " -"āĻ…āĻ¨ā§āϤāĻ°ā§āϭ⧁āĻ•ā§āϤ āϰāϝāĻŧ⧇āϛ⧇āĨ¤" #: src/index.md msgid "" -"[Chromium](chromium.md): a half-day course on using Rust within Chromium " -"based browsers. This includes interoperability with C++ and how to include " -"third-party crates in Chromium." +"[Chromium](chromium.md): a half-day course on using Rust in Chromium-based " +"browsers. This includes interoperability with C++ and how to include third-" +"party crates in Chromium." msgstr "" -"[Chromium][chromium.md): āĻāĻ•āϟāĻŋ āφāϧāĻž āĻĻāĻŋāύ⧇āϰ āϕ⧋āĻ°ā§āϏ āϝ⧇āĻ–āĻžāύ⧇ āĻ•āĻŋāĻ­āĻžāĻŦ⧇ Chromium āϝ⧁āĻ•ā§āϤ " -"āĻŦā§āϰāĻžāωāϏāĻžāϰ āĻ āϰāĻžāĻ¸ā§āϟ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āϝ⧇āϤ⧇ āĻĒāĻžāϰ⧇ āĻāϟāĻž āĻļ⧇āĻ–āĻžāύ⧋ āĻšā§Ÿā§‡āϛ⧇āĨ¤ āĻāϤ⧇ C++ āφāĻ¨ā§āϤāσāĻ•āĻžāĻ°ā§āϝāĻ•ā§āώāĻŽāϤāĻž " -"āϏāĻš āϤ⧃āĻ¤ā§€ā§Ÿ āĻĒāĻ•ā§āώ⧇āϰ āĻ•ā§āϰ⧇āϟ āĻ•āĻŋāĻ­āĻžāĻŦ⧇ Chromium āĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āϝ⧇āϤ⧇ āĻĒāĻžāϰ⧇ āĻāϟāĻžāĻ“ āĻĻ⧇āĻ–āĻžāύ⧋ āĻšā§Ÿā§‡āϛ⧇āĨ¤" #: src/index.md msgid "" @@ -1331,47 +2330,35 @@ msgid "" "(embedded) development. Both microcontrollers and application processors are " "covered." msgstr "" -"[āĻŦā§‡ā§ŸāĻžāϰ-āĻŽā§‡āϟāĻžāϞ](bare-metal.md): āϰāĻžāĻ¸ā§āϟ āĻ•āĻŋāĻ­āĻžāĻŦ⧇ āĻāĻŽāĻŦ⧇āĻĄā§‡āĻĄ āĻĄā§‡āϭ⧇āϞāĻĒāĻŽā§‡āĻ¨ā§āϟ āĻ āϞāĻžāĻ—āϤ⧇ āĻĒāĻžāϰ⧇ āĻāχ " -"āĻŦāĻŋāĻˇā§Ÿā§‡āϰ āĻ“āĻĒāϰ⧇ āĻāĻ•āϟāĻž āĻĒ⧁āϰ⧋ āĻĻāĻŋāύ⧇āϰ āĻ•ā§āϞāĻžāϏāĨ¤ āĻŽāĻžāχāĻ•ā§āϰ⧋āĻ•āĻ¨ā§āĻŸā§āϰ⧋āϞ⧇āϰāϏ āĻāĻŦāĻ‚ āĻāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āĻĒā§āϰāϏ⧇āϏāϏāĻ°ā§āϏ āĻāχ " -"āĻĻ⧁āĻŸā§‹ āĻŦāĻŋāώ⧟āϗ⧁āϞāĻŋāϰ āϚāĻ°ā§āϚāĻž āĻ•āϰāĻž āĻšā§Ÿā§‡āϛ⧇ āĻāĻ–āĻžāύ⧇āĨ¤" #: src/index.md msgid "" -"[Concurrency](concurrency.md): a whole-day class on concurrency in Rust. We " -"cover both classical concurrency (preemptively scheduling using threads and " -"mutexes) and async/await concurrency (cooperative multitasking using " -"futures)." +"[Concurrency](concurrency/welcome.md): a whole-day class on concurrency in " +"Rust. We cover both classical concurrency (preemptively scheduling using " +"threads and mutexes) and async/await concurrency (cooperative multitasking " +"using futures)." msgstr "" -"[āϏāĻŽāĻŦāĻ°ā§āϤ⧀ āĻ—āĻŖāύāĻž](concurrency.md): āϰāĻžāĻ¸ā§āϟ āĻ āϏāĻŽāĻŦāĻ°ā§āϤ⧀ āĻ—āĻŖāύāĻžāϰ āĻ“āĻĒāϰ⧇ āĻāĻ•āϟāĻž āĻĒ⧁āϰ⧋ āĻĻāĻŋāύ⧇āϰ āĻ•ā§āϞāĻžāϏ " -"āĨ¤ āĻāĻ–āĻžāύ⧇ āĻ•ā§āϞāĻžāϏāĻŋāĻ•āĻžāϞ āϏāĻŽāĻŦāĻ°ā§āϤ⧀ (āĻĨā§āϰ⧇āĻĄ āĻāĻŦāĻ‚ mutexes āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āĻ…āĻ—ā§āϰāĻ•ā§āϰ⧟āĻžāϧāĻŋāĻ•āĻžāϰ-āϏāĻ‚āĻ•ā§āϰāĻžāĻ¨ā§āϤ " -"āϏāĻŽāϝāĻŧāϏ⧂āĻšā§€ āĻŦāĻžāύāĻžāύ⧋) āĻ—āĻŖāύāĻž āĻāĻŦāĻ‚ async/await āϏāĻŽāĻŦāĻ°ā§āϤ⧀ āĻ—āĻŖāύāĻž (āĻĢāĻŋāωāϚāĻžāϰ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āϏāĻŽāĻŦāĻžāϝāĻŧ " -"āĻŽāĻžāĻ˛ā§āϟāĻŋāϟāĻžāĻ¸ā§āĻ•āĻŋāĻ‚)-āĻāχ āĻĻ⧁āχ āϧāϰāϪ⧇āϰ āύāĻŋā§Ÿā§‡ āϚāĻ°ā§āϚāĻž āĻ•āϰāĻž āĻšā§Ÿā§‡āϛ⧇āĨ¤" #: src/index.md msgid "Non-Goals" -msgstr "āϝāĻž āϞāĻ•ā§āĻˇā§āϝ⧇āϰ āĻŽāĻ§ā§āϝ⧇ āĻĒāĻĄāĻŧ⧇ āύāĻž" +msgstr "" #: src/index.md msgid "" "Rust is a large language and we won't be able to cover all of it in a few " "days. Some non-goals of this course are:" msgstr "" -"āϰāĻžāĻ¸ā§āϟ āĻāĻ•āϟāĻŋ āĻŦ⧃āĻšā§Ž āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāĻŋāĻ‚ āĻ˛ā§āϝāĻžāĻ‚āϗ⧁āϝāĻŧ⧇āϜ āĻāĻŦāĻ‚ āφāĻŽāϰāĻž āĻ•āϝāĻŧ⧇āĻ• āĻĻāĻŋāύ⧇āϰ āĻŽāĻ§ā§āϝ⧇ āĻāϟāĻŋāϕ⧇ āĻ•āĻ­āĻžāϰ āĻ•āϰāϤ⧇ " -"āϏāĻ•ā§āώāĻŽ āĻšāĻŦ āύāĻžāĨ¤ āĻāχ āϕ⧋āĻ°ā§āϏ⧇āϰ āĻ•āĻŋāϛ⧁ āĻ…-āϞāĻ•ā§āĻˇā§āϝ āĻšāϞāσ" #: src/index.md msgid "" -"Learning how to develop macros: please see [Chapter 19.5 in the Rust Book]" -"(https://doc.rust-lang.org/book/ch19-06-macros.html) and [Rust by Example]" -"(https://doc.rust-lang.org/rust-by-example/macros.html) instead." +"Learning how to develop macros: please see [the Rust Book](https://doc.rust-" +"lang.org/book/) and [Rust by Example](https://doc.rust-lang.org/rust-by-" +"example/macros.html) instead." msgstr "" -"āĻŽā§āϝāĻžāĻ•ā§āϰ⧋ āĻ•āĻŋāĻ­āĻžāĻŦ⧇ āĻŦāĻžāύāĻžāύ⧋ āϝ⧇āϤ⧇ āĻĒāĻžāϰ⧇: āĻāϰ āϜāĻ¨ā§āϝ⧇ [āϰāĻžāĻ¸ā§āϟ āĻŦāχ āĻāϰ āĻ…āĻ§ā§āϝāĻžāϝāĻŧ ⧧⧝.ā§Ģ](https://doc." -"rust-lang.org/book/ch19-06-macros.html) āĻāĻŦāĻ‚ [āωāĻĻāĻžāĻšāϰāĻŖ āĻĻā§āĻŦāĻžāϰāĻž Rust](https://doc." -"rust-lang.org/rust-by-example/macros.html) āĻĻ⧇āϖ⧁āύāĨ¤" #: src/index.md msgid "Assumptions" -msgstr "\\##āϧ⧃āĻˇā§āϟāϤāĻžāϏāĻŽā§‚āĻš" +msgstr "" #: src/index.md msgid "" @@ -1379,17 +2366,12 @@ msgid "" "statically-typed language and we will sometimes make comparisons with C and " "C++ to better explain or contrast the Rust approach." msgstr "" -"āϕ⧋āĻ°ā§āϏāϟāĻŋ āĻ…āύ⧁āĻŽāĻžāύ āĻ•āϰ⧇ āϝ⧇ āφāĻĒāύāĻŋ āχāϤāĻŋāĻŽāĻ§ā§āϝ⧇āχ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽ āĻ•āϰāϤ⧇ āϜāĻžāύ⧇āύāĨ¤ āϰāĻžāĻ¸ā§āϟ āĻāĻ•āϟāĻŋ āĻ¸ā§āĻŸā§āϝāĻžāϟāĻŋāĻ•āĻžāϞāĻŋ " -"āϟāĻžāχāĻĒāĻĄ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāĻŋāĻ‚ āĻ˛ā§āϝāĻžāĻ‚āϗ⧁āϝāĻŧ⧇āϜ āĻāĻŦāĻ‚ āφāĻŽāϰāĻž āĻ•āĻ–āύāĻ“ āĻ•āĻ–āύāĻ“ C āĻāĻŦāĻ‚ C++ āĻāϰ āϏāĻžāĻĨ⧇ āϤ⧁āϞāύāĻž āĻ•āϰāĻŦ " -"āĻ­āĻžāϞ⧋āĻ­āĻžāĻŦ āĻŦā§āϝāĻžāĻ–āĻž āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āĻ…āĻĨāĻŦāĻž āĻŦāĻŋāĻĒāϰ⧀āϤ āϰāĻžāĻ¸ā§āϟ āĻĒāĻĻā§āϧāϤāĻŋāĨ¤" #: src/index.md msgid "" "If you know how to program in a dynamically-typed language such as Python or " "JavaScript, then you will be able to follow along just fine too." msgstr "" -"āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āϜāĻžāύ⧇āύ āĻ•āĻŋāĻ­āĻžāĻŦ⧇ āĻāĻ•āϟāĻŋ āĻĄāĻžāχāύāĻžāĻŽāĻŋāĻ•ā§āϝāĻžāϞāĻŋ āϟāĻžāχāĻĒāĻĄ āĻ­āĻžāώāĻžāϝāĻŧ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽ āĻ•āϰāϤ⧇ āĻšāϝāĻŧ āϝ⧇āĻŽāύ " -"āĻĒāĻžāχāĻĨāύ āĻŦāĻž āϜāĻžāĻ­āĻžāĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ, āϤāĻžāĻšāϞ⧇ āφāĻĒāύāĻŋ āϖ⧁āĻŦ āĻ­āĻžāϞ āĻ…āύ⧁āϏāϰāĻŖ āĻ•āϰāϤ⧇ āϏāĻ•ā§āώāĻŽ āĻšāĻŦ⧇āύāĨ¤" #: src/index.md msgid "" @@ -1397,21 +2379,16 @@ msgid "" "information to the slides. This could be key points which the instructor " "should cover as well as answers to typical questions which come up in class." msgstr "" -"āĻāϟāĻŋ āĻāĻ•āϟāĻŋ _speaker note_ āĻāϰ āωāĻĻāĻžāĻšāϰāĻŖāĨ¤ āφāĻŽāϰāĻž āĻ…āϤāĻŋāϰāĻŋāĻ•ā§āϤ āϤāĻĨā§āϝ āĻ¸ā§āϞāĻžāχāĻĄā§‡ āϝ⧋āĻ— āĻ•āϰāϤ⧇ āĻāχāϗ⧁āϞ⧋ " -"āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻŦā§‹āĨ¤ āĻāϟāĻŋ āĻĒā§āϰāϧāĻžāύ āĻĒāϝāĻŧ⧇āĻ¨ā§āϟ āĻšāϤ⧇ āĻĒāĻžāϰ⧇ āϝāĻž āĻĒā§āϰāĻļāĻŋāĻ•ā§āώāϕ⧇āϰ āωāϚāĻŋāϤ āĻ•āĻ­āĻžāϰ⧇āϰ āĻĒāĻžāĻļāĻžāĻĒāĻžāĻļāĻŋ " -"āĻ•ā§āϞāĻžāϏ⧇ āφāϏāĻž āϏāĻžāϧāĻžāϰāĻŖ āĻĒā§āϰāĻļā§āύ⧇āϰ āωāĻ¤ā§āϤāϰ āĻĻ⧇āĻ“āϝāĻŧāĻžāĨ¤" #: src/running-the-course.md src/running-the-course/course-structure.md msgid "This page is for the course instructor." -msgstr "āĻāχ āĻĒ⧃āĻˇā§āĻ āĻžāϟāĻŋ āϕ⧋āĻ°ā§āϏ āĻĒā§āϰāĻļāĻŋāĻ•ā§āώāϕ⧇āϰ āϜāĻ¨ā§āϝāĨ¤" +msgstr "" #: src/running-the-course.md msgid "" "Here is a bit of background information about how we've been running the " "course internally at Google." msgstr "" -"āφāĻŽāϰāĻž āϕ⧀āĻ­āĻžāĻŦ⧇ āϕ⧋āĻ°ā§āϏāϟāĻŋ āϚāĻžāϞāĻžāĻšā§āĻ›āĻŋ āϏ⧇ āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āĻāĻ–āĻžāύ⧇ āĻ•āĻŋāϛ⧁ āĻĒāϟāĻ­ā§‚āĻŽāĻŋāϰ āϗ⧁āĻ—āϞ⧇ āĻ…āĻ­ā§āϝāĻ¨ā§āϤāϰ⧀āĻŖāĻ­āĻžāĻŦ⧇ āϤāĻĨā§āϝ " -"āϰāϝāĻŧ⧇āϛ⧇āĨ¤" #: src/running-the-course.md msgid "" @@ -1420,13 +2397,10 @@ msgid "" "afternoon class. Both sessions contain multiple breaks and time for students " "to work on exercises." msgstr "" -"āϏāĻžāϧāĻžāϰāĻŖāϤ āφāĻŽāϰāĻž āϏāĻ•āĻžāϞ ⧝.ā§Ļā§Ļ āĻĨ⧇āϕ⧇ āĻŦāĻŋāϕ⧇āϞ ā§Ē.ā§Ļā§Ļ (āĻŽāĻžāĻā§‡ ā§§ āϘāĻ¨ā§āϟāĻžāϰ āĻŦāĻŋāϰāϤāĻŋāϏāĻš) āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āĻ•ā§āϞāĻžāϏ āĻ•āϰ⧇ " -"āĻĨāĻžāĻ•āĻŋāĨ¤ āĻāχ āϜāĻ¨ā§āϝ⧇ āϏāĻ•āĻžāϞ⧇ ā§Š āϘāĻ¨ā§āϟāĻž āĻāĻŦāĻ‚ āĻĻ⧁āĻĒ⧁āϰ⧇ ā§Š āϘāĻ¨ā§āϟāĻž āϏāĻŽā§Ÿā§‡ āĻĨāĻžāϕ⧇ āĻ•ā§āϞāĻžāϏ āĻāϰ āϜāĻ¨ā§āϝ⧇āĨ¤ āĻĻ⧁āϟāĻŋ āĻ­āĻžāϗ⧇āχ " -"āĻļāĻŋāĻ•ā§āώāĻžāĻ°ā§āĻĨā§€ āĻĻ⧇āϰ āϜāĻ¨ā§āϝ⧇ āĻŦāĻŋāϰāϤāĻŋ āĻāĻŦāĻ‚ āĻ…āύ⧁āĻļā§€āϞāύ⧀āϰ āĻ•āĻžāĻœā§‡āϰ āϏāĻŽā§Ÿā§‡ āϝ⧁āĻ•ā§āϤ āĻĨāĻžāϕ⧇āĨ¤" #: src/running-the-course.md msgid "Before you run the course, you will want to:" -msgstr "āφāĻĒāύāĻŋ āϕ⧋āĻ°ā§āϏ āϚāĻžāϞāĻžāύ⧋āϰ āφāϗ⧇, āφāĻĒāύāĻŋ āϚāĻžāχāĻŦ⧇āύ:" +msgstr "" #: src/running-the-course.md msgid "" @@ -1436,11 +2410,6 @@ msgid "" "notes in a popup (click the link with a little arrow next to \"Speaker " "Notes\"). This way you have a clean screen to present to the class." msgstr "" -"āϕ⧋āĻ°ā§āϏ⧇āϰ āωāĻĒāĻžāĻĻāĻžāύ⧇āϰ āϏāĻžāĻĨ⧇ āύāĻŋāĻœā§‡āϕ⧇ āĻĒāϰāĻŋāϚāĻŋāϤ āĻ•āϰ⧁āύāĨ¤ āφāĻŽāϰāĻž āĻ¸ā§āĻĒāĻŋāĻ•āĻžāϰ āύ⧋āϟ āĻ…āĻ¨ā§āϤāĻ°ā§āϭ⧁āĻ•ā§āϤ āĻ•āϰ⧇āĻ›āĻŋ āĻŽā§‚āϞ " -"āĻĒāϝāĻŧ⧇āĻ¨ā§āϟāϗ⧁āϞāĻŋ āĻšāĻžāχāϞāĻžāχāϟ āĻ•āϰāϤ⧇ āϏāĻžāĻšāĻžāĻ¯ā§āϝ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ (āĻ…āύ⧁āĻ—ā§āϰāĻš āĻ•āϰ⧇ āφāϰāĻ“ āĻ¸ā§āĻĒāĻŋāĻ•āĻžāϰ āύ⧋āϟ āĻ…āĻŦāĻĻāĻžāύ āϰ⧇āϖ⧇ " -"āφāĻŽāĻžāĻĻ⧇āϰ āϏāĻžāĻšāĻžāĻ¯ā§āϝ āĻ•āϰ⧁āύ !)āĨ¤ āωāĻĒāĻ¸ā§āĻĨāĻžāĻĒāύ āĻ•āϰāĻžāϰ āϏāĻŽāϝāĻŧ, āφāĻĒāύāĻŋ āĻāĻ•āϟāĻŋ āĻ¸ā§āĻĒāĻŋāĻ•āĻžāϰ āύ⧋āϟ āĻĒāĻĒāφāĻĒ āĻ āϖ⧁āϞāϤ⧇ " -"āϭ⧁āϞāĻŦ⧇āύ āύāĻž (\"āĻ¸ā§āĻĒā§€āĻ•āĻžāϰ āύ⧋āϟāϏ\" āĻāϰ āĻĒāĻžāĻļ⧇ āĻāĻ•āϟāĻŋ āϛ⧋āϟ āϤ⧀āϰ āϏāĻš āϞāĻŋāĻ™ā§āϕ⧇ āĻ•ā§āϞāĻŋāĻ• āĻ•āϰ⧁āύ)āĨ¤ āĻāχ āĻĒāĻĨ⧇ " -"āĻ•ā§āϞāĻžāϏ⧇ āωāĻĒāĻ¸ā§āĻĨāĻžāĻĒāύ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āφāĻĒāύāĻžāϰ āĻ•āĻžāϛ⧇ āĻāĻ•āϟāĻŋ āĻĒāϰāĻŋāĻˇā§āĻ•āĻžāϰ āĻĒāĻ°ā§āĻĻāĻž āϰāϝāĻŧ⧇āϛ⧇āĨ¤" #: src/running-the-course.md msgid "" @@ -1449,10 +2418,6 @@ msgid "" "find it helpful to have a gap in the course since it helps them process all " "the information we give them." msgstr "" -"āϤāĻŋāĻĨāĻŋāϰ āĻ“āĻĒāϰ⧇ āφāϗ⧇ āĻĨ⧇āϕ⧇ āϏāĻŋāĻĻā§āϧāĻžāĻ¨ā§āϤ āύāĻŋā§Ÿā§‡ āĻ¨ā§‡ā§ŸāĻž āĻ­āĻžāϞ⧋āĨ¤ āϝ⧇āĻšā§‡āϤ⧁ āĻāχ āϕ⧋āĻ°ā§āϏāϟāĻŋ ā§Ē-āĻĻāĻŋāύ āĻāϰ āϏ⧇āĻšā§‡āϤ⧁ " -"āφāĻŽāĻžāĻĻ⧇āϰ āϤāϰāĻĢ āĻĨ⧇āϕ⧇ āĻĒāϰāĻžāĻŽāĻ°ā§āĻļ āĻĨāĻžāĻ•āĻŦ⧇ āϝ⧇ āϤāĻŋāĻĨāĻŋāϗ⧁āϞāĻŋ āĻĻ⧁āχ āϏāĻĒā§āϤāĻž āϧāϰ⧇ āĻ›ā§œāĻŋā§Ÿā§‡ āϰāĻžāĻ–āĻŦāĻžāĨ¤ āφāϗ⧇āϰ " -"āĻ…āĻ‚āĻļāĻ—ā§āϰāĻšāĻŖāĻ•āĻžāϰ⧀āĻĻ⧇āϰ āĻĒā§āϰāϤāĻŋāĻ•ā§āϰāĻŋāϝāĻŧāĻž āĻĨ⧇āϕ⧇ āĻāχ āĻĒāĻžāĻ“ā§ŸāĻž āϗ⧇āϛ⧇ āϝ⧇ āĻāϰāĻŽ āĻ•āϰ⧇ āĻāĻ•āĻžāϧāĻŋāĻ• āϏāĻĒā§āϤāĻž āϧāϰ⧇ " -"āϕ⧋āĻ°ā§āϏāϟāĻŋ āĻ•āϰāĻžāϞ⧇ āϤāĻžāϰāĻž āφāϰāĻ“ āĻ­āĻžāϞ⧋ āĻŦā§‹āĻā§‡āĨ¤" #: src/running-the-course.md msgid "" @@ -1461,15 +2426,9 @@ msgid "" "asking questions --- it's also small enough that one instructor will have " "time to answer the questions. Make sure the room has _desks_ for yourself " "and for the students: you will all need to be able to sit and work with your " -"laptops. In particular, you will be doing a lot of live-coding as an " +"laptops. In particular, you will be doing significant live-coding as an " "instructor, so a lectern won't be very helpful for you." msgstr "" -"āφāĻĒāύāĻžāϰ āĻŦā§āϝāĻ•ā§āϤāĻŋāĻ—āϤ āĻ…āĻ‚āĻļāĻ—ā§āϰāĻšāύ⧇āϰ āϜāĻ¨ā§āϝ āϝāĻĨ⧇āĻˇā§āϟ āĻŦāĻĄāĻŧ āĻāĻ•āϟāĻŋ āϰ⧁āĻŽ āϖ⧁āρāϜ⧁āύāĨ¤ āφāĻŽāϰāĻž āϏ⧁āĻĒāĻžāϰāĻŋāĻļ āĻ•āϰāĻŋ 15-25 āϜāύ⧇āϰ " -"āϏāĻžāχāĻœā§‡āϰ āĻ•ā§āϞāĻžāϏāĨ¤ āĻāϟāĻŋ āϝāĻĨ⧇āĻˇā§āϟ āϛ⧋āϟ āϝ⧇ āĻŽāĻžāύ⧁āώ āφāϰāĻžāĻŽāĻĻāĻžāϝāĻŧāĻ• āĻ…āύ⧁āĻ­āĻŦ āĻ•āϰ⧇ āĻĒā§āϰāĻļā§āύ āϜāĻŋāĻœā§āĻžāĻžāϏāĻž āĻ•āϰāϤ⧇--- " -"āĻāϟāĻŋ āϝāĻĨ⧇āĻˇā§āϟ āϛ⧋āϟ āϝ⧇ āĻāĻ•āϜāύ āĻĒā§āϰāĻļāĻŋāĻ•ā§āώāĻ• āĻāϰ āϏāĻŽāϝāĻŧ āĻĨāĻžāĻ•āĻŦ⧇ āĻĒā§āϰāĻļā§āύ⧇āϰ āωāĻ¤ā§āϤāϰ āĻĻ⧇āĻ“āϝāĻŧāĻžāϰ āϜāĻ¨ā§āϝāĨ¤ āύāĻŋāĻļā§āϚāĻŋāϤ " -"āĻ•āϰ⧁āύ āϝ⧇ āϘāϰ⧇ āφāĻĒāύāĻžāϰ āϜāĻ¨ā§āϝ āĻāĻŦāĻ‚ āĻ›āĻžāĻ¤ā§āϰāĻĻ⧇āϰ āϜāĻ¨ā§āϝ _desks_ āφāϛ⧇ : āφāĻĒāύāĻžā§āĻĻ⧇āϰ āϏāĻ•āϞāϕ⧇ āφāĻĒāύāĻžāĻĻ⧇āϰ " -"āĻ˛ā§āϝāĻžāĻĒāϟāĻĒ⧇āϰ āϏāĻžāĻĨ⧇ āĻŦāϏ⧇ āĻ•āĻžāϜ āĻ•āϰāϤ⧇ āϏāĻ•ā§āώāĻŽ āĻšāϤ⧇ āĻšāĻŦ⧇āĨ¤ āĻŦāĻŋāĻļ⧇āώ āĻ•āϰ⧇, āφāĻĒāύāĻŋ āĻāĻ•āϜāύ āĻĒā§āϰāĻļāĻŋāĻ•ā§āώāĻ• āĻšāĻŋāϏāĻžāĻŦ⧇ " -"āĻĒā§āϰāϚ⧁āϰ āϞāĻžāχāĻ­-āϕ⧋āĻĄāĻŋāĻ‚ āĻ•āϰāĻŦ⧇āύ, āϤāĻžāχ lecturn āφāĻĒāύāĻžāϰ āϜāĻ¨ā§āϝ āϖ⧁āĻŦ āϏāĻšāĻžāϝāĻŧāĻ• āĻšāĻŦ⧇ āύāĻžāĨ¤" #: src/running-the-course.md msgid "" @@ -1480,12 +2439,6 @@ msgid "" "as you change pages. Using your laptop will also allow you to fix typos as " "you or the course participants spot them." msgstr "" -"āφāĻĒāύāĻžāϰ āϕ⧋āĻ°ā§āϏ⧇āϰ āĻĻāĻŋāύ, āϜāĻŋāύāĻŋāϏāϗ⧁āϞāĻŋ āϏ⧇āϟ āĻ•āϰāϤ⧇ āĻāĻ•āϟ⧁ āϤāĻžāĻĄāĻŧāĻžāϤāĻžāĻĄāĻŧāĻŋ āĻ•āϰ⧁āύ āφāĻŽāϰāĻž āφāĻĒāύāĻžāϰ āĻ˛ā§āϝāĻžāĻĒāϟāĻĒ⧇ " -"āϚāϞāĻŽāĻžāύ `mdbook serve` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āϏāϰāĻžāϏāϰāĻŋ āωāĻĒāĻ¸ā§āĻĨāĻžāĻĒāύ āĻ•āϰāĻžāϰ āĻĒāϰāĻžāĻŽāĻ°ā§āĻļ āĻĻāĻŋāχ (āĻĻ⧇āϖ⧁āύ " -"\\[āχāύāĻ¸ā§āϟāϞ⧇āĻļāύ āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻžāĻŦāϞ⧀\\] [3](https://github.com/google/comprehensive-" -"rust#building))āĨ¤ āφāĻĒāύāĻŋ āĻĒ⧃āĻˇā§āĻ āĻžāϗ⧁āϞāĻŋ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāĻžāϰ āϏāĻžāĻĨ⧇ āϏāĻžāĻĨ⧇ āĻāϟāĻŋ āϕ⧋āύāĻ“ āĻ˛ā§āϝāĻžāĻ— āĻ›āĻžāĻĄāĻŧāĻžāχ " -"āϏāĻ°ā§āĻŦā§‹āĻ¤ā§āϤāĻŽ āĻ•āĻžāĻ°ā§āϝāĻ•ā§āώāĻŽāϤāĻž āύāĻŋāĻļā§āϚāĻŋāϤ āĻ•āϰ⧇āĨ¤ āφāĻĒāύāĻžāϰ āĻ˛ā§āϝāĻžāĻĒāϟāĻĒ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϞ⧇ āφāĻĒāύāĻŋ āφāĻĒāύāĻžāϰ āĻŦāĻž āϕ⧋āĻ°ā§āϏ⧇āϰ " -"āĻŽāϤ⧋ āϟāĻžāχāĻĒ āϭ⧁āϞ āĻ āĻŋāĻ• āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŦ⧇āύ āĻ…āĻ‚āĻļāĻ—ā§āϰāĻšāĻŖāĻ•āĻžāϰ⧀āϰāĻž āϤāĻžāĻĻ⧇āϰ āϖ⧁āρāĻœā§‡ āĻŦ⧇āϰ āĻ•āϰ⧇āĨ¤" #: src/running-the-course.md msgid "" @@ -1497,20 +2450,12 @@ msgid "" "offer a solution, e.g., by showing people where to find the relevant " "information in the standard library." msgstr "" -"āϤāĻžāĻĻ⧇āϰāϕ⧇ āĻāĻ•āĻž āĻāĻ•āĻž āĻŦāĻž āϛ⧋āϟ āĻĻāϞ⧇ āĻ…āύ⧁āĻļā§€āϞāύ⧇āϰ āϏāĻŽāĻžāϧāĻžāύ āĻ•āϰāϤ⧇ āĻĻāĻŋāύāĨ¤ āφāĻŽāϰāĻž āϏāĻžāϧāĻžāϰāĻŖāϤ āϏāĻ•āĻžāϞ⧇ āĻāĻŦāĻ‚ " -"āĻŦāĻŋāϕ⧇āϞ⧇ āĻŦā§āϝāĻžāϝāĻŧāĻžāĻŽā§‡āϰ āϜāĻ¨ā§āϝ 30-45 āĻŽāĻŋāύāĻŋāϟ āĻŦā§āϝāϝāĻŧ āĻ•āϰāĻŋ (āϏāĻŽāĻžāϧāĻžāύāϗ⧁āϞāĻŋ āĻĒāĻ°ā§āϝāĻžāϞ⧋āϚāύāĻž āĻ•āϰāĻžāϰ āϏāĻŽāϝāĻŧ āϏāĻš)āĨ¤ " -"āύāĻŋāĻļā§āϚāĻŋāϤ āĻ•āϰ⧁āύ āϞ⧋āϕ⧇āĻĻ⧇āϰ āϜāĻŋāĻœā§āĻžāĻžāϏāĻž āĻ•āϰ⧁āύ āϤāĻžāϰāĻž āφāϟāϕ⧇ āφāϛ⧇ āĻ•āĻŋāύāĻž āĻŦāĻž āφāĻĒāύāĻŋ āϏāĻžāĻšāĻžāĻ¯ā§āϝ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ " -"āĻāĻŽāύ āĻ•āĻŋāϛ⧁ āφāϛ⧇ āĻ•āĻŋāύāĻžāĨ¤ āϝāĻ–āύ āφāĻĒāύāĻŋ āĻĻ⧇āĻ–āϤ⧇ āĻĒāĻžāĻšā§āϛ⧇āύ āϝ⧇ āĻŦ⧇āĻļ āĻ•āϝāĻŧ⧇āĻ•āϜāύ⧇āϰ āĻāĻ•āχ āϏāĻŽāĻ¸ā§āϝāĻž āϰāϝāĻŧ⧇āϛ⧇, " -"āĻāϟāĻŋāϕ⧇ āĻ•ā§āϞāĻžāϏ⧇ āĻ•āϞ āĻ•āϰ⧁āύ āĻāĻŦāĻ‚ āĻāĻ•āϟāĻŋ āϏāĻŽāĻžāϧāĻžāύ āĻ…āĻĢāĻžāϰ āĻ•āϰ⧁āύ, āϝ⧇āĻŽāύ, āĻĒā§āϰāĻžāϏāĻ™ā§āĻ—āĻŋāĻ• āϤāĻĨā§āϝāϟāĻŋ āĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄ " -"āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋāϤ⧇ āϕ⧋āĻĨāĻžāϝāĻŧ āĻĒāĻžāĻ“āϝāĻŧāĻž āϝāĻžāĻŦ⧇ āϤāĻž āϞ⧋āϕ⧇āĻĻ⧇āϰ āĻĻ⧇āĻ–āĻŋāϝāĻŧ⧇ āĻĻāĻŋāύāĨ¤" #: src/running-the-course.md msgid "" "That is all, good luck running the course! We hope it will be as much fun " "for you as it has been for us!" msgstr "" -"āĻāχāϏāĻŦ āϝ⧇, āϕ⧋āĻ°ā§āϏāϟāĻŋ āϚāĻžāϞāĻžāύ⧋āϰ āϜāĻ¨ā§āϝ āĻļ⧁āĻ­āĻ•āĻžāĻŽāύāĻžāĨ¤ āφāĻŽāϰāĻž āφāĻļāĻž āĻ•āϰāĻŋ āĻāϟāĻž āϤāϤāϟāĻžāχ āĻŽāϜāĻžāϰ āĻšāĻŦ⧇ āφāĻĒāύāĻžāϰ " -"āϜāĻ¨ā§āϝ āϝāϤāϟāĻž āĻšāϝāĻŧ⧇āĻ›āĻŋāϞ⧋ āφāĻŽāĻžāĻĻ⧇āϰ āĻ•āĻžāϛ⧇āĨ¤" #: src/running-the-course.md msgid "" @@ -1520,173 +2465,237 @@ msgid "" "Your students are also very welcome to [send us feedback](https://github.com/" "google/comprehensive-rust/discussions/100)!" msgstr "" -"āĻ…āύ⧁āĻ—ā§āϰāĻš āĻ•āϰ⧇ \\[āĻĒā§āϰāϤāĻŋāĻ•ā§āϰāĻŋāϝāĻŧāĻž āĻĒā§āϰāĻĻāĻžāύ āĻ•āϰ⧁āύ\\] [1](https://github.com/google/" -"comprehensive-rust/discussions/86) āĻĒāϰ⧇ āϝāĻžāϤ⧇ āφāĻŽāϰāĻž āωāĻ¨ā§āύāϤāĻŋ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŋāĨ¤ āĻ…āĻŦāĻļā§āϝāχ " -"āφāĻĒāύāĻžāϰ āϜāĻ¨ā§āϝ āϕ⧀ āĻ­āĻžāϞ āĻ•āĻžāϜ āĻ•āϰ⧇āϛ⧇ āĻāĻŦāĻ‚ āωāĻ¤ā§āϤāĻŽ āϕ⧀ āϤ⧈āϰāĻŋ āĻ•āϰāĻž āϝ⧇āϤ⧇ āĻĒāĻžāϰ⧇ āϤāĻž āφāĻŽāϰāĻž āĻļ⧁āύāϤ⧇ āϚāĻžāχāĨ¤" -"āφāĻĒāύāĻžāϰ āĻ›āĻžāĻ¤ā§āϰāĻĻ⧇āϰāĻ“ \\[āφāĻŽāĻžāĻĻ⧇āϰ āĻĒā§āϰāϤāĻŋāĻ•ā§āϰāĻŋāϝāĻŧāĻž āĻĒāĻžāĻ āĻžāϤ⧇\\] āϖ⧁āĻŦ āĻ¸ā§āĻŦāĻžāĻ—āϤ āϜāĻžāύāĻžāχ[2](https://" -"github.com/google/comprehensive-rust/discussions/100)" + +#: src/running-the-course.md +msgid "Instructor Preparation" +msgstr "" + +#: src/running-the-course.md +msgid "" +"**Go through all the material:** Before teaching the course, make sure you " +"have gone through all the slides and exercises yourself. This will help you " +"anticipate questions and potential difficulties." +msgstr "" + +#: src/running-the-course.md +msgid "" +"**Prepare for live coding:** The course involves significant live coding. " +"Practice the examples and exercises beforehand to ensure you can type them " +"out smoothly during the class. Have the solutions ready in case you get " +"stuck." +msgstr "" + +#: src/running-the-course.md +msgid "" +"**Familiarize yourself with `mdbook`:** The course is presented using " +"`mdbook`. Knowing how to navigate, search, and use its features will make " +"the presentation smoother." +msgstr "" + +#: src/running-the-course.md +msgid "" +"**Slice size helper:** Press Ctrl + Alt + B " +"to toggle a visual guide showing the amount of space available when " +"presenting. Expect any content outside of the red box to be hidden " +"initially. Use this as a guide when editing slides. You can also [enable it " +"via this link](?show-red-box=true)." +msgstr "" + +#: src/running-the-course.md +msgid "Creating a Good Learning Environment" +msgstr "" + +#: src/running-the-course.md +msgid "" +"**Encourage questions:** Reiterate that there are no \"stupid\" questions. A " +"welcoming atmosphere for questions is crucial for learning." +msgstr "" + +#: src/running-the-course.md +msgid "" +"**Manage time effectively:** Keep an eye on the schedule, but be flexible. " +"It's more important that students understand the concepts than sticking " +"rigidly to the timeline." +msgstr "" + +#: src/running-the-course.md +msgid "" +"**Facilitate group work:** During exercises, encourage students to work " +"together. This can help them learn from each other and feel less stuck." +msgstr "" #: src/running-the-course/course-structure.md msgid "Rust Fundamentals" -msgstr "āϰāĻžāĻ¸ā§āϟ āĻāϰ āĻ­āĻŋāĻ¤ā§āϤāĻŋ āĻœā§āĻžāĻžāύ " +msgstr "" #: src/running-the-course/course-structure.md msgid "" "The first four days make up [Rust Fundamentals](../welcome-day-1.md). The " -"days are fast paced and we cover a lot of ground!" +"days are fast-paced and we cover a broad range of topics!" msgstr "" -"āĻĒā§āϰāĻĨāĻŽ āϚāĻžāϰ āĻĻāĻŋāύ āϧāϰ⧇ [āϰāĻžāĻ¸ā§āϟ āĻāϰ āĻŽā§‚āϞāϏ⧂āĻ¤ā§āϰāϗ⧁āϞāĻŋ](../welcome-day-1.md) āϏ⧇āĻ–āĻžāύ āĻšāĻŦ⧇āĨ¤ āĻāχ " -"āĻ…āĻ§ā§āϝāĻžāϝāĻŧāϗ⧁āϞāĻŋ āĻĻā§āϰ⧁āϤ āĻ—āϤāĻŋāϰ āĻšāϝāĻŧ āĻāĻŦāĻ‚ āφāĻŽāϰāĻž āĻ…āύ⧇āĻ•āϟāĻž āĻāĻ•āϏāĻžāĻĨ⧇ āĻļāĻŋāĻ–āĻŦāĻžāϰ āĻšā§‡āĻˇā§āϟāĻž āĻ•āϰāĻžāĻŦā§‹āĨ¤" #: src/running-the-course/course-structure.md msgid "Course schedule:" -msgstr "āϕ⧋āĻ°ā§āϏ āĻāϰ āϏāĻŽāϝāĻŧāϏ⧂āĻšā§€" +msgstr "" #: src/running-the-course/course-structure.md msgid "Day 1 Morning (2 hours and 10 minutes, including breaks)" -msgstr "āĻĒā§āϰāĻĨāĻŽ āĻĻāĻŋāύ⧇āϰ āϏāĻ•āĻžāϞ (āĻŦāĻŋāϰāϤāĻŋāϏāĻš ⧍ āϘāĻ¨ā§āϟāĻž ā§§ā§Ļ āĻŽāĻŋāύāĻŋāϟ)" +msgstr "" + +#: src/running-the-course/course-structure.md src/welcome-day-1.md +#: src/welcome-day-1-afternoon.md src/welcome-day-2.md +#: src/welcome-day-2-afternoon.md src/welcome-day-3.md +#: src/welcome-day-3-afternoon.md src/welcome-day-4.md +#: src/welcome-day-4-afternoon.md src/concurrency/welcome.md +#: src/concurrency/welcome-async.md src/idiomatic/welcome.md +msgid "Segment" +msgstr "" + +#: src/running-the-course/course-structure.md src/welcome-day-1.md +#: src/hello-world.md src/types-and-values.md src/control-flow-basics.md +#: src/welcome-day-1-afternoon.md src/tuples-and-arrays.md src/references.md +#: src/user-defined-types.md src/welcome-day-2.md src/pattern-matching.md +#: src/methods-and-traits.md src/generics.md src/welcome-day-2-afternoon.md +#: src/closures.md src/std-types.md src/std-traits.md src/welcome-day-3.md +#: src/memory-management.md src/smart-pointers.md +#: src/welcome-day-3-afternoon.md src/borrowing.md src/lifetimes.md +#: src/welcome-day-4.md src/iterators.md src/modules.md src/testing.md +#: src/welcome-day-4-afternoon.md src/error-handling.md src/unsafe-rust.md +#: src/concurrency/welcome.md src/concurrency/threads.md +#: src/concurrency/channels.md src/concurrency/send-sync.md +#: src/concurrency/shared-state.md src/concurrency/sync-exercises.md +#: src/concurrency/welcome-async.md src/concurrency/async.md +#: src/concurrency/async-control-flow.md src/concurrency/async-pitfalls.md +#: src/concurrency/async-exercises.md src/idiomatic/welcome.md +#: src/idiomatic/foundations-api-design.md +#: src/idiomatic/leveraging-the-type-system.md +#: src/unsafe-deep-dive/introduction.md src/unsafe-deep-dive/pinning.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer.md +msgid "Duration" +msgstr "" + +#: src/running-the-course/course-structure.md src/welcome-day-1.md +#: src/types-and-values.md src/control-flow-basics.md src/tuples-and-arrays.md +#: src/references.md src/user-defined-types.md src/pattern-matching.md +#: src/generics.md src/closures.md src/std-types.md src/std-traits.md +#: src/memory-management.md src/smart-pointers.md src/lifetimes.md +#: src/iterators.md src/modules.md src/testing.md src/error-handling.md +#: src/unsafe-rust.md src/concurrency/shared-state.md +#: src/concurrency/async-control-flow.md src/concurrency/async-pitfalls.md +#: src/idiomatic/leveraging-the-type-system.md +#: src/unsafe-deep-dive/introduction.md src/unsafe-deep-dive/pinning.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer.md +msgid "5 minutes" +msgstr "" + +#: src/running-the-course/course-structure.md src/welcome-day-1.md +#: src/types-and-values.md src/control-flow-basics.md src/tuples-and-arrays.md +#: src/user-defined-types.md src/pattern-matching.md src/methods-and-traits.md +#: src/modules.md src/unsafe-rust.md src/concurrency/welcome.md +#: src/concurrency/threads.md src/concurrency/shared-state.md +#: src/unsafe-deep-dive/introduction.md src/unsafe-deep-dive/pinning.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer.md +msgid "15 minutes" +msgstr "" + +#: src/running-the-course/course-structure.md src/welcome-day-1.md +#: src/borrowing.md src/concurrency/welcome-async.md +msgid "40 minutes" +msgstr "" + +#: src/running-the-course/course-structure.md src/welcome-day-1.md +#: src/welcome-day-2.md src/welcome-day-4.md +msgid "45 minutes" +msgstr "" #: src/running-the-course/course-structure.md -msgid "[Welcome](../welcome-day-1.md) (5 minutes)" -msgstr "[āĻ¸ā§āĻŦāĻžāĻ—āϤ](../welcome-day-1.md) (ā§Ģ āĻŽāĻŋāύāĻŋāϟ)" +msgid "Day 1 Afternoon (2 hours and 45 minutes, including breaks)" +msgstr "" -#: src/running-the-course/course-structure.md -msgid "[Hello, World](../hello-world.md) (15 minutes)" -msgstr "[āĻšā§āϝāĻžāϞ⧋, āĻ“ā§ŸāĻžāĻ°ā§āĻ˛ā§āĻĄ](../hello-world.md) (ā§§ā§Ģ āĻŽāĻŋāύāĻŋāϟ )" +#: src/running-the-course/course-structure.md src/welcome-day-1-afternoon.md +msgid "35 minutes" +msgstr "" -#: src/running-the-course/course-structure.md -msgid "[Types and Values](../types-and-values.md) (45 minutes)" -msgstr "[āϟāĻžāχāĻĒ āĻāĻŦāĻ‚ āĻŽāĻžāύ](../types-and-values.md) (ā§Ēā§Ģ āĻŽāĻŋāύāĻŋāϟ)" +#: src/running-the-course/course-structure.md src/welcome-day-1-afternoon.md +#: src/welcome-day-3.md src/welcome-day-4.md src/welcome-day-4-afternoon.md +#: src/concurrency/welcome-async.md +msgid "55 minutes" +msgstr "" -#: src/running-the-course/course-structure.md -msgid "[Control Flow Basics](../control-flow-basics.md) (40 minutes)" -msgstr "[āύāĻŋāϝāĻŧāĻ¨ā§āĻ¤ā§āϰāĻŖ āĻĒā§āϰāĻŦāĻžāĻšāϰ āĻĒā§āϰāĻžāĻĨāĻŽāĻŋāĻ• āĻœā§āĻžāĻžāύ](../control-flow-basics.md) (ā§Ēā§Ļ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/running-the-course/course-structure.md -msgid "Day 1 Afternoon (2 hours and 15 minutes, including breaks)" -msgstr "āĻĒā§āϰāĻĨāĻŽ āĻĻāĻŋāύ⧇āϰ āĻĻ⧁āĻĒ⧁āϰ (āĻŦāĻŋāϰāϤāĻŋāϏāĻš ⧍ āϘāĻ¨ā§āϟāĻž ā§§ā§Ļ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/running-the-course/course-structure.md -msgid "[Tuples and Arrays](../tuples-and-arrays.md) (35 minutes)" -msgstr "[āϟāĻŋāωāĻĒāϞ āĻāĻŦāĻ‚ āĻ…ā§āϝāĻžāϰ⧇](../tuples-and-arrays.md) (ā§Šā§Ģ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/running-the-course/course-structure.md -msgid "[References](../references.md) (35 minutes)" -msgstr "[āϰ⧇āĻĢāĻžāϰ⧇āĻ¨ā§āϏ](../references.md) (ā§Šā§Ģ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/running-the-course/course-structure.md -msgid "[User-Defined Types](../user-defined-types.md) (50 minutes)" -msgstr "[āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āĻĻā§āĻŦāĻžāϰāĻž āϏāĻ‚āĻœā§āĻžāĻžāϝāĻŧāĻŋāϤ āϟāĻžāχāĻĒ](../user-defined-types.md) (ā§Ģā§Ļ āĻŽāĻŋāύāĻŋāϟ)" +#: src/running-the-course/course-structure.md src/welcome-day-1-afternoon.md +#: src/welcome-day-2-afternoon.md src/welcome-day-3.md +msgid "1 hour" +msgstr "" #: src/running-the-course/course-structure.md msgid "Day 2 Morning (2 hours and 50 minutes, including breaks)" -msgstr "āĻĻā§āĻŦāĻŋāĻ¤ā§€ā§Ÿ āĻĻāĻŋāύ⧇āϰ āϏāĻ•āĻžāϞ (āĻŦāĻŋāϰāϤāĻŋāϏāĻš ⧍ āϘāĻ¨ā§āϟāĻž ā§Ģā§Ļ āĻŽāĻŋāύāĻŋāϟ)" +msgstr "" + +#: src/running-the-course/course-structure.md src/hello-world.md +#: src/types-and-values.md src/control-flow-basics.md src/tuples-and-arrays.md +#: src/references.md src/welcome-day-2.md src/methods-and-traits.md +#: src/closures.md src/std-types.md src/welcome-day-3.md src/borrowing.md +#: src/lifetimes.md src/welcome-day-4.md src/iterators.md src/modules.md +#: src/testing.md src/error-handling.md src/unsafe-deep-dive/introduction.md +msgid "3 minutes" +msgstr "" + +#: src/running-the-course/course-structure.md src/welcome-day-2.md +#: src/unsafe-deep-dive/pinning.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer.md +msgid "50 minutes" +msgstr "" #: src/running-the-course/course-structure.md -msgid "[Welcome](../welcome-day-2.md) (3 minutes)" -msgstr "[āĻ¸ā§āĻŦāĻžāĻ—āϤāĻŽ](../welcome-day-2.md) (ā§Š āĻŽāĻŋāύāĻŋāϟ)" +msgid "Day 2 Afternoon (2 hours and 50 minutes, including breaks)" +msgstr "" -#: src/running-the-course/course-structure.md -msgid "[Pattern Matching](../pattern-matching.md) (1 hour)" -msgstr "[āĻĒā§āϝāĻžāϟāĻžāĻ°ā§āύ āĻŽā§āϝāĻžāϚāĻŋāĻ‚](../pattern-matching.md) (ā§§ āϘāĻ¨ā§āϟāĻž)" - -#: src/running-the-course/course-structure.md -msgid "[Methods and Traits](../methods-and-traits.md) (45 minutes)" -msgstr "[āĻĒā§āϰāĻŖāĻžāϞ⧀ āĻāĻŦāĻ‚ āĻŸā§āϰ⧇āχāϟ](../methods-and-traits.md) (ā§Ēā§Ģ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/running-the-course/course-structure.md -msgid "[Generics](../generics.md) (40 minutes)" -msgstr "[āĻœā§‡āύ⧇āϰāĻŋāĻ•ā§āϏ\\](../generics.md) (ā§Ēā§Ļ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/running-the-course/course-structure.md -msgid "Day 2 Afternoon (3 hours and 10 minutes, including breaks)" -msgstr "āĻĻā§āĻŦāĻŋāĻ¤ā§€ā§Ÿ āĻĻāĻŋāύ⧇āϰ āĻĻ⧁āĻĒ⧁āϰāĻŦ⧇āϞāĻž (āĻŦāĻŋāϰāϤāĻŋāϏāĻš ā§Š āϘāĻ¨ā§āϟāĻž ā§§ā§Ļ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/running-the-course/course-structure.md -msgid "[Standard Library Types](../std-types.md) (1 hour and 20 minutes)" -msgstr "[āĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄ āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋāϰ āϟāĻžāχāĻĒāϗ⧁āϞāĻŋ](../std-types.md) (ā§§ āϘāĻ¨ā§āϟāĻž āĻŸā§‹ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/running-the-course/course-structure.md -msgid "[Standard Library Traits](../std-traits.md) (1 hour and 40 minutes)" -msgstr "[āĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄ āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋāϰ āĻŸā§āϰ⧇āχāϟ](../std-traits.md) (ā§§ āϘāĻ¨ā§āϟāĻž āĻŸā§‹ āĻŽāĻŋāύāĻŋāϟ)" +#: src/running-the-course/course-structure.md src/welcome-day-2-afternoon.md +#: src/std-traits.md src/smart-pointers.md src/lifetimes.md src/iterators.md +#: src/testing.md src/unsafe-rust.md src/concurrency/welcome.md +#: src/concurrency/sync-exercises.md src/concurrency/async-exercises.md +msgid "30 minutes" +msgstr "" #: src/running-the-course/course-structure.md msgid "Day 3 Morning (2 hours and 20 minutes, including breaks)" -msgstr "āϤ⧃āĻ¤ā§€ā§Ÿ āĻĻāĻŋāύ⧇āϰ āϏāĻ•āĻžāϞāĻŦ⧇āϞāĻž (āĻŦāĻŋāϰāϤāĻŋāϏāĻš ⧍ āϘāĻ¨ā§āϟāĻž ⧍ā§Ļ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/running-the-course/course-structure.md -msgid "[Welcome](../welcome-day-3.md) (3 minutes)" -msgstr "[āĻ¸ā§āĻŦāĻžāĻ—āϤāĻŽ](../welcome-day-3.md) (ā§Š āĻŽāĻŋāύāĻŋāϟ)" - -#: src/running-the-course/course-structure.md -msgid "[Memory Management](../memory-management.md) (1 hour)" -msgstr "[āĻŽā§‡āĻŽāϰāĻŋ āĻŦā§āϝāĻŦāĻ¸ā§āĻĨāĻžāĻĒāύāĻž](../memory-management.md) (ā§§ āϘāĻ¨ā§āϟāĻž)" - -#: src/running-the-course/course-structure.md -msgid "[Smart Pointers](../smart-pointers.md) (55 minutes)" -msgstr "[āĻŦ⧁āĻĻā§āϧāĻŋāĻŽāĻžāύ āχāĻ™ā§āĻ—āĻŋāϤāĻ•āĻžāϰ⧀ āĻŦāĻž āĻ¸ā§āĻŽāĻžāĻ°ā§āϟ āĻĒā§Ÿā§‡āĻ¨ā§āϟāĻžāϰ](../smart-pointers.md) (ā§Ģā§Ģ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/running-the-course/course-structure.md -msgid "Day 3 Afternoon (2 hours and 10 minutes, including breaks)" -msgstr "āϤ⧃āĻ¤ā§€ā§Ÿ āĻĻāĻŋāύ⧇āϰ āĻĻ⧁āĻĒ⧁āϰāĻŦ⧇āϞāĻž (āĻŦāĻŋāϰāϤāĻŋāϏāĻš ⧍ āϘāĻ¨ā§āϟāĻž ā§§ā§Ļ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/running-the-course/course-structure.md -msgid "[Borrowing](../borrowing.md) (50 minutes)" -msgstr "[āϧāĻžāϰ āύ⧇āĻ“ā§ŸāĻž āĻŦāĻž āĻŦāĻ°ā§‹ā§ŸāĻŋāĻ‚](../borrowing.md) (ā§Ģā§Ļ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/running-the-course/course-structure.md -msgid "" -"[Slices and Lifetimes](../slices-and-lifetimes.md) (1 hour and 10 minutes)" msgstr "" -"[āϟ⧁āĻ•āϰāĻž āĻŦāĻž āĻ¸ā§āϞāĻžāχāϏ⧇āϏ āĻāĻŦāĻ‚ āĻœā§€āĻŦāύāĻ•āĻžāϞ ](../slices-and-lifetimes.md) (ā§§ āϘāĻ¨ā§āϟāĻž ā§§ā§Ļ āĻŽāĻŋāύāĻŋāϟ)" + +#: src/running-the-course/course-structure.md +msgid "Day 3 Afternoon (2 hours and 30 minutes, including breaks)" +msgstr "" + +#: src/running-the-course/course-structure.md src/welcome-day-3-afternoon.md +#: src/welcome-day-4-afternoon.md +msgid "1 hour and 15 minutes" +msgstr "" + +#: src/running-the-course/course-structure.md src/welcome-day-3-afternoon.md +#: src/idiomatic/leveraging-the-type-system.md +msgid "1 hour and 5 minutes" +msgstr "" #: src/running-the-course/course-structure.md msgid "Day 4 Morning (2 hours and 50 minutes, including breaks)" -msgstr "āϚāϤ⧁āĻ°ā§āĻĨ āĻĻāĻŋāύ⧇āϰ āϏāĻ•āĻžāϞāĻŦ⧇āϞāĻž (āĻŦāĻŋāϰāϤāĻŋāϏāĻš ⧍āϘāĻ¨ā§āϟāĻž ā§Ģā§Ļ āĻŽāĻŋāύāĻŋāϟ)" +msgstr "" #: src/running-the-course/course-structure.md -msgid "[Welcome](../welcome-day-4.md) (3 minutes)" -msgstr "[āĻ¸ā§āĻŦāĻžāĻ—āϤāĻŽ](../welcome-day-4.md) (ā§Š āĻŽāĻŋāύāĻŋāϟ)" - -#: src/running-the-course/course-structure.md -msgid "[Iterators](../iterators.md) (45 minutes)" -msgstr "[āĻĒ⧁āύāϰāĻžāĻŦ⧃āĻ¤ā§āϤāĻŋāĻ•āĻžāϰ⧀ āĻŦāĻž āχāϟāĻžāϰ⧇āϟāĻ°ā§āϏ](../iterators.md) (ā§Ēā§Ģ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/running-the-course/course-structure.md -msgid "[Modules](../modules.md) (40 minutes)" -msgstr "[āĻŽāĻĄāĻŋāωāϞ](../modules.md) (ā§Ēā§Ļ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/running-the-course/course-structure.md -msgid "[Testing](../testing.md) (1 hour)" -msgstr "[āĻĒāϰ⧀āĻ•ā§āώāĻž āĻ•āϰāĻž](../testing.md) (ā§§ āϘāĻ¨ā§āϟāĻž)" - -#: src/running-the-course/course-structure.md -msgid "Day 4 Afternoon (2 hours and 10 minutes, including breaks)" -msgstr "āϚāϤ⧁āĻ°ā§āĻĨ āĻĻāĻŋāύ⧇āϰ āĻĻ⧁āĻĒ⧁āϰāĻŦ⧇āϞāĻž (āĻŦāĻŋāϰāϤāĻŋāϏāĻš ⧍ āϘāĻ¨ā§āϟāĻž ā§§ā§Ļ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/running-the-course/course-structure.md -msgid "[Error Handling](../error-handling.md) (55 minutes)" -msgstr "[āĻ¤ā§āϰ⧁āϟāĻŋ āĻĒāϰāĻŋāϚāĻžāϞāύāĻž](../error-handling.md) (ā§Ģā§Ģ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/running-the-course/course-structure.md -msgid "[Unsafe Rust](../unsafe-rust.md) (1 hour and 5 minutes)" -msgstr "[āĻ…āύāĻŋāϰāĻžāĻĒāĻĻ āϰāĻžāĻ¸ā§āϟ](../unsafe-rust.md) (ā§§ āϘāĻ¨ā§āϟāĻž ā§Ģ āĻŽāĻŋāύāĻŋāϟ)" +msgid "Day 4 Afternoon (2 hours and 20 minutes, including breaks)" +msgstr "" #: src/running-the-course/course-structure.md msgid "Deep Dives" -msgstr "āĻ—āĻ­ā§€āϰ āĻĄā§āĻŦ" +msgstr "" #: src/running-the-course/course-structure.md msgid "" "In addition to the 4-day class on Rust Fundamentals, we cover some more " "specialized topics:" msgstr "" -"āϰāĻžāĻ¸ā§āĻŸā§‡āϰ āĻŽā§‚āϞ āĻŦāĻŋāĻˇā§Ÿā§‡āϰ āĻ“āĻĒāϰ⧇ ā§Ē āĻĻāĻŋāύ⧇āϰ āĻ•ā§āϞāĻžāϏ āĻ›āĻžāĻĄāĻŧāĻžāĻ“, āĻāĻ–āĻžāύ⧇ āφāϰāĻ“ āĻ•āĻŋāϛ⧁ āĻŦāĻŋāĻļ⧇āώ āĻŦāĻŋāώāϝāĻŧ āϚāĻ°ā§āϚāĻž āĻ•āϰāĻž " -"āĻšā§Ÿā§‡āϛ⧇ āϝ⧇āĻŽāύ:" #: src/running-the-course/course-structure.md msgid "Rust in Android" -msgstr "āĻ…ā§āϝāĻžāĻ¨ā§āĻĄā§āϰāϝāĻŧ⧇āĻĄā§‡ āϰāĻžāĻ¸ā§āϟ" +msgstr "" #: src/running-the-course/course-structure.md msgid "" @@ -1694,9 +2703,6 @@ msgid "" "Rust for Android platform development. This includes interoperability with " "C, C++, and Java." msgstr "" -"[āĻ…ā§āϝāĻžāĻ¨ā§āĻĄā§āϰāϝāĻŧ⧇āĻĄā§‡ āϰāĻžāĻ¸ā§āϟ](../android.md) āĻšāϞ āĻ…ā§āϝāĻžāĻ¨ā§āĻĄā§āϰāϝāĻŧ⧇āĻĄ āĻĒā§āĻ˛ā§āϝāĻžāϟāĻĢāĻ°ā§āĻŽ āĻĄā§‡āϭ⧇āϞāĻĒāĻŽā§‡āĻ¨ā§āϟ āĻāϰ āϜāĻ¨ā§āϝ " -"āϰāĻžāĻ¸ā§āϟ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻžāϰ āĻāĻ•āϟāĻŋ āĻ…āĻ°ā§āϧ-āĻĻāĻŋāύ⧇āϰ āϕ⧋āĻ°ā§āϏāĨ¤ āĻāϰ āĻŽāĻ§ā§āϝ⧇ āϰāϝāĻŧ⧇āϛ⧇ C, C++, āĻāĻŦāĻ‚ Java āĻāϰ āϏāĻžāĻĨ⧇ " -"āφāĻ¨ā§āϤāσāĻ•āĻžāĻ°ā§āϝāϝ⧋āĻ—ā§āϝāϤāĻžāĨ¤" #: src/running-the-course/course-structure.md msgid "" @@ -1706,11 +2712,6 @@ msgid "" "android/` directory into the root of your AOSP checkout. This will ensure " "that the Android build system sees the `Android.bp` files in `src/android/`." msgstr "" -"āφāĻĒāύāĻžāϰ āĻāĻ•āϟāĻŋ \\[AOSP āĻšā§‡āĻ•āφāωāϟ\\] āĻĒā§āϰāϝāĻŧā§‹āϜāύ āĻšāĻŦ⧇ [1](https://source.android.com/docs/" -"setup/download/downloading)āĨ¤ āĻāĻ•āϟāĻŋ āĻšā§‡āĻ•āφāωāϟ āĻ•āϰ⧁āύ \\[āϕ⧋āĻ°ā§āϏ āϰāĻŋāĻĒā§‹āϜāĻŋāϟāϰāĻŋ [2](https://" -"github.com/google/comprehensive-rust) āĻāĻ•āχ āĻŽā§‡āĻļāĻŋāύ⧇ āĻāĻŦāĻ‚ `src/android/` āĻĄāĻŋāϰ⧇āĻ•ā§āϟāϰāĻŋ " -"āϏāϰāĻžāύ āφāĻĒāύāĻžāϰ AOSP āĻšā§‡āĻ•āφāωāĻŸā§‡āϰ āĻŽā§‚āϞ āĻĄāĻŋāϰ⧇āĻ•ā§āϟāϰāĻŋāϤ⧇āĨ¤ āĻāϟāĻŋ āĻ…ā§āϝāĻžāĻ¨ā§āĻĄā§āϰāϝāĻŧ⧇āĻĄ āĻŦāĻŋāĻ˛ā§āĻĄ āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽ āύāĻŋāĻļā§āϚāĻŋāϤ " -"āĻ•āϰāĻŦ⧇ `src/android/`\\-āĻ `Android.bp` āĻĢāĻžāχāϞāϗ⧁āϞāĻŋ āĻĻ⧇āϖ⧁āύāĨ¤" #: src/running-the-course/course-structure.md msgid "" @@ -1718,14 +2719,10 @@ msgid "" "all Android examples using `src/android/build_all.sh`. Read the script to " "see the commands it runs and make sure they work when you run them by hand." msgstr "" -"āύāĻŋāĻļā§āϚāĻŋāϤ āĻ•āϰ⧁āύ āϝ⧇ `adb āϏāĻŋāĻ™ā§āĻ•` āφāĻĒāύāĻžāϰ āĻāĻŽā§āϞ⧇āϟāϰ āĻŦāĻž āĻŦāĻžāĻ¸ā§āϤāĻŦ āĻĄāĻŋāĻ­āĻžāχāϏ⧇āϰ āϏāĻžāĻĨ⧇ āĻ•āĻžāϜ āĻ•āϰ⧇ āĻāĻŦāĻ‚ " -"Android āωāĻĻāĻžāĻšāϰāĻŖāϗ⧁āϞ⧋ āĻĒā§āϰāĻŋ-āĻŦāĻŋāĻ˛ā§āĻĄ āĻ•āϰ⧁āύ `src/android/build_all.sh` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇āĨ¤āĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āϟ " -"āĻĒāĻĄāĻŧ⧁āύ āĻ•āĻŽāĻžāĻ¨ā§āĻĄ āĻĻ⧇āĻ–āϤ⧇ āϝ⧇āϗ⧁āϞ⧋ āĻāϟāĻŋ āϚāĻžāϞāĻžāϝāĻŧ āĻāĻŦāĻ‚ āύāĻŋāĻļā§āϚāĻŋāϤ āĻ•āϰ⧁āύ āϝ⧇ āφāĻĒāύāĻŋ āϝāĻ–āύ āϤāĻžāĻĻ⧇āϰ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇āύ " -"āϤāĻ–āύ āϤāĻžāϰāĻž āĻ•āĻžāϜ āĻ•āϰ⧇āĨ¤" #: src/running-the-course/course-structure.md msgid "Rust in Chromium" -msgstr "āĻ•ā§āϰ⧋āĻŽāĻŋ⧟āĻŽā§‡ āϰāĻžāĻ¸ā§āϟ" +msgstr "" #: src/running-the-course/course-structure.md msgid "" @@ -1734,11 +2731,6 @@ msgid "" "Chromium's `gn` build system, bringing in third-party libraries (\"crates\") " "and C++ interoperability." msgstr "" -"āĻ•ā§āϰ⧋āĻŽāĻŋ⧟āĻŽ āĻŦā§āϰāĻžāωāϏāĻžāϰ āĻāϰ āϜāĻ¨ā§āϝ⧇ āϰāĻžāĻ¸ā§āϟ āĻ•āĻŋāĻ­āĻžāĻŦ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āϝāĻžā§Ÿ āĻāϰ āĻ“āĻĒāϰ⧇ āĻ…āĻ°ā§āϧ⧇āĻ• āĻĻāĻŋāύ⧇āϰ āϜāĻ¨ā§āϝ⧇ " -"āĻ—āĻ­ā§€āϰ āĻ­āĻžāĻŦ⧇ āϚāĻ°ā§āϚāĻž āĻ•āϰāĻž āĻšā§Ÿā§‡āϛ⧇ āĻāĻ–āĻžāύ⧇ - [āĻ•ā§āϰ⧋āĻŽāĻŋ⧟āĻŽ āĻāϰ āϜāĻ¨ā§āϝ⧇ āϰāĻžāĻ¸ā§āϟ](../chromium.md)āĨ¤ " -"āĻ•ā§āϰ⧋āĻŽāĻŋ⧟āĻŽ āĻāϰ `gn` āύāĻŋāĻ°ā§āĻŽāĻžāĻŖ āĻĒāĻĻā§āϧāϤāĻŋāϤ⧇ āĻ•āĻŋāĻ­āĻžāĻŦ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āϝ⧇āϤ⧇ āĻĒāĻžāϰ⧇, āϤ⧃āϤ⧀āϝāĻŧ āĻĒāĻ•ā§āώ⧇āϰ " -"āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋ (āϝāĻžāϕ⧇ āĻ•ā§āϰ⧇āϟ āĻŦāϞāĻž āĻšā§Ÿā§‡ Rust āĻ) āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āĻāĻŦāĻ‚ C++ āφāĻ¨ā§āϤāσ-āĻ•āĻžāĻ°ā§āϝāĻ•ā§āώāĻŽāϤāĻž āĻāχ " -"āĻŦāĻŋāĻˇā§Ÿā§‡ āϗ⧁āϞāĻŋāϰ āĻ—āĻ­ā§€āϰ āϚāĻ°ā§āϚāĻž āĻ•āϰāĻž āĻšā§Ÿā§‡āϛ⧇āĨ¤" #: src/running-the-course/course-structure.md msgid "" @@ -1746,14 +2738,10 @@ msgid "" "[recommended](../chromium/setup.md) for speed but any build will work. " "Ensure that you can run the Chromium browser that you've built." msgstr "" -"āĻāϰ āϜāĻ¨ā§āϝ⧇ āφāĻĒāύāĻžāϰ āĻ•ā§āϰ⧋āĻŽāĻŋ⧟āĻŽ āύāĻŋāĻ°ā§āĻŽāĻžāĻŖ āĻ•āϰāĻŦāĻžāϰ āĻ•ā§āώāĻŽāϤāĻž āĻĨāĻžāϕ⧇ āĻĻāϰāĻ•āĻžāϰāĨ¤ āϝāĻĻāĻŋāĻ“ āϝ⧇āϕ⧋āύ⧋ āύāĻŋāĻ°ā§āĻŽāĻŋāϤ " -"āĻ•ā§āϰ⧋āĻŽāĻŋ⧟āĻŽ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āϝāĻžāĻŦ⧇, āϤāĻŦ⧁āĻ“ āϤāĻžā§œāĻžāϤāĻžā§œāĻŋ āĻ•āĻžāϜ āĻ•āϰāĻŦāĻžāϰ āϜāĻ¨ā§āϝ⧇ āφāĻŽāϰāĻž āĻāĻ•āϟāĻŋ āĻĄāĻŋāĻŦāĻžāĻ— āĻĒāĻĻā§āϧāϤāĻŋāϤ⧇ " -"āύāĻŋāĻ°ā§āĻŽāĻŋāϤ āĻ•ā§āϰ⧋āĻŽāĻŋ⧟āĻŽ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻŦāĻžāϰ [āĻĒāϰāĻžāĻŽāĻ°ā§āĻļ](../chromium/setup.md) āĻĻ⧇āĻŦāĨ¤ āύāĻŋāĻ°ā§āĻŽāĻŋāϤ " -"āĻ•ā§āϰ⧋āĻŽāĻŋ⧟āĻŽ āϝ⧇āύ āφāĻĒāύāĻžāϰ āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽā§‡ āϚāϞāϤ⧇ āĻĒāĻžāϰ⧇ āĻāϟāĻžāĻ“ āĻŽāĻžāĻĨāĻžā§Ÿ āϰāĻžāĻ–āĻž āĻĻāϰāĻ•āĻžāϰāĨ¤ " #: src/running-the-course/course-structure.md msgid "Bare-Metal Rust" -msgstr "Bare-Metal āϰāĻžāĻ¸ā§āϟ" +msgstr "" #: src/running-the-course/course-structure.md msgid "" @@ -1761,9 +2749,6 @@ msgid "" "using Rust for bare-metal (embedded) development. Both microcontrollers and " "application processors are covered." msgstr "" -"[Bare-Metal āϰāĻžāĻ¸ā§āϟ](../bare-metal.md): āϰāĻžāĻ¸ā§āϟ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ bare-metal (embedded) " -"āĻĄā§‡āϭ⧇āϞāĻĒāĻŽā§‡āĻ¨ā§āϟ āĻāϰ āϜāĻ¨ā§āϝ āĻāĻ•āϟāĻŋ āĻĒ⧁āϰ⧋ āĻĻāĻŋāύ⧇āϰ āĻ•ā§āϞāĻžāϏāĨ¤ āĻŽāĻžāχāĻ•ā§āϰ⧋āĻ•āĻ¨ā§āĻŸā§āϰ⧋āϞāĻžāϰ āĻāĻŦāĻ‚ āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āĻĒā§āϰāϏ⧇āϏāϰ " -"āωāĻ­āϝāĻŧāχ āĻ•āĻ­āĻžāϰ āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇āĨ¤" #: src/running-the-course/course-structure.md msgid "" @@ -1772,21 +2757,16 @@ msgid "" "need to install a number of packages as described on the [welcome page](../" "bare-metal.md)." msgstr "" -"āĻŽāĻžāχāĻ•ā§āϰ⧋āĻ•āĻ¨ā§āĻŸā§āϰ⧋āϞāĻžāϰ āĻ…āĻ‚āĻļ⧇āϰ āϜāĻ¨ā§āϝ, āφāĻĒāύāĻžāϕ⧇ āϏāĻŽāϝāĻŧ⧇āϰ āφāϗ⧇ āĻ•āĻŋāύāϤ⧇ āĻšāĻŦ⧇ [BBC micro:bit](https://" -"microbit.org/) v2 āωāĻ¨ā§āύāϝāĻŧāύ āĻŦā§‹āĻ°ā§āĻĄāĨ¤ āϏāĻŦāĻžāχāϕ⧇ [welcome page](../bare-metal.md) āĻ " -"āĻŦāĻ°ā§āĻŖāĻŋāϤ āĻĒā§āϝāĻžāϕ⧇āϜāϗ⧁āϞāĻŋāϰ āĻāĻ•āϟāĻŋ āϏāĻ‚āĻ–ā§āϝāĻž āχāύāĻ¸ā§āϟāϞ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇āĨ¤" #: src/running-the-course/course-structure.md msgid "Concurrency in Rust" -msgstr "Concurrency in āϰāĻžāĻ¸ā§āϟ" +msgstr "" #: src/running-the-course/course-structure.md msgid "" -"The [Concurrency in Rust](../concurrency.md) deep dive is a full day class " -"on classical as well as `async`/`await` concurrency." +"The [Concurrency in Rust](../concurrency/welcome.md) deep dive is a full day " +"class on classical as well as `async`/`await` concurrency." msgstr "" -"[Concurrency in Rust](../concurrency.md) āĻĄāĻŋāĻĒ āĻĄāĻžāχāĻ­ āĻ•ā§āϞāĻžāϏāĻŋāĻ•ā§āϝāĻžāϞ⧇āϰ āωāĻĒāϰ āĻĒ⧁āϰ⧋ āĻĻāĻŋāύ⧇āϰ " -"āĻāĻ•āϟāĻŋ āĻ•ā§āϞāĻžāϏ āϏ⧇āχāϏāĻžāĻĨ⧇ `async`/`await` concurrency." #: src/running-the-course/course-structure.md msgid "" @@ -1794,63 +2774,136 @@ msgid "" "to go. You can then copy/paste the examples into `src/main.rs` to experiment " "with them:" msgstr "" -"āφāĻĒāύāĻžāϰ āĻĒā§āϰāϝāĻŧā§‹āϜāύ āĻšāĻŦ⧇ āĻāĻ•āϟāĻŋ āύāϤ⧁āύ āĻ•ā§āϰ⧇āϟ āϏ⧇āϟ āφāĻĒ āĻāĻŦāĻ‚ āύāĻŋāĻ°ā§āĻ­āϰāϤāĻž āĻĄāĻžāωāύāϞ⧋āĻĄ āĻ•āϰāĻž āĻāĻŦāĻ‚ āĻĒā§āϰāĻ¸ā§āϤ⧁āϤ " -"āĻšāĻ“āϝāĻŧāĻžāĨ¤ āϤāĻžāϰāĻĒāϰ āφāĻĒāύāĻŋ āĻĒāϰ⧀āĻ•ā§āώāĻž āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ `src/main.rs`\\-āĻ āωāĻĻāĻžāĻšāϰāĻŖāϗ⧁āϞ⧋ āĻ•āĻĒāĻŋ/āĻĒ⧇āĻ¸ā§āϟ āĻ•āϰāϤ⧇ " -"āĻĒāĻžāϰ⧇āύ:" + +#: src/running-the-course/course-structure.md +msgid "Morning (3 hours and 20 minutes, including breaks)" +msgstr "" + +#: src/running-the-course/course-structure.md src/references.md +#: src/std-types.md src/memory-management.md src/error-handling.md +#: src/concurrency/welcome.md src/concurrency/sync-exercises.md +#: src/concurrency/welcome-async.md src/concurrency/async-pitfalls.md +#: src/concurrency/async-exercises.md +#: src/idiomatic/leveraging-the-type-system.md +msgid "20 minutes" +msgstr "" + +#: src/running-the-course/course-structure.md src/concurrency/welcome.md +msgid "Send and Sync" +msgstr "" + +#: src/running-the-course/course-structure.md src/concurrency/welcome.md +#: src/concurrency/welcome-async.md +msgid "1 hour and 10 minutes" +msgstr "" + +#: src/running-the-course/course-structure.md +msgid "Afternoon (3 hours and 30 minutes, including breaks)" +msgstr "" + +#: src/running-the-course/course-structure.md +msgid "" +"The [Idiomatic Rust](../idiomatic/welcome.md) deep dive is a 2-day class on " +"Rust idioms and patterns." +msgstr "" + +#: src/running-the-course/course-structure.md +msgid "" +"You should be familiar with the material in [Rust Fundamentals](../welcome-" +"day-1.md) before starting this course." +msgstr "" + +#: src/running-the-course/course-structure.md +msgid "Morning (14 hours and 25 minutes, including breaks)" +msgstr "" + +#: src/running-the-course/course-structure.md src/idiomatic/welcome.md +msgid "3 hours and 30 minutes" +msgstr "" + +#: src/running-the-course/course-structure.md src/idiomatic/welcome.md +msgid "7 hours and 30 minutes" +msgstr "" + +#: src/running-the-course/course-structure.md src/idiomatic/welcome.md +msgid "3 hours and 5 minutes" +msgstr "" + +#: src/running-the-course/course-structure.md +msgid "Unsafe (Work in Progress)" +msgstr "" + +#: src/running-the-course/course-structure.md +msgid "" +"The [Unsafe](../unsafe-deep-dive/welcome.md) deep dive is a two-day class on " +"the _unsafe_ Rust language. It covers the fundamentals of Rust's safety " +"guarantees, the motivation for `unsafe`, review process for `unsafe` code, " +"FFI basics, and building data structures that the borrow checker would " +"normally reject." +msgstr "" + +#: src/running-the-course/course-structure.md +msgid "not found - {{%course outline Unsafe}}" +msgstr "" #: src/running-the-course/course-structure.md msgid "Format" -msgstr "āĻŦāĻŋāĻ¨ā§āϝāĻžāϏ" +msgstr "" #: src/running-the-course/course-structure.md msgid "" "The course is meant to be very interactive and we recommend letting the " "questions drive the exploration of Rust!" msgstr "" -"āϕ⧋āĻ°ā§āϏāϟāĻŋ āϖ⧁āĻŦ āχāĻ¨ā§āϟāĻžāϰ⧇āĻ•ā§āϟāĻŋāĻ­ āĻšāϤ⧇ āĻŦā§‹āĻāĻžāύ⧋ āĻšāϝāĻŧ⧇āϛ⧇ āĻāĻŦāĻ‚ āφāĻŽāϰāĻž āĻāϟāĻŋ āĻ•āϰāĻžāϰ āϏ⧁āĻĒāĻžāϰāĻŋāĻļ āĻ•āϰāĻ›āĻŋ āĻĒā§āϰāĻļā§āύāϗ⧁āϞ⧋ " -"Rust āĻāϰ āĻ…āĻ¨ā§āĻŦ⧇āώāĻŖ āϚāĻžāϞāύāĻž āĻ•āϰ⧁āĻ•!" #: src/running-the-course/keyboard-shortcuts.md msgid "There are several useful keyboard shortcuts in mdBook:" -msgstr "mdBook-āĻ āĻŦ⧇āĻļ āĻ•āĻŋāϛ⧁ āĻĻāϰāĻ•āĻžāϰ⧀ āϕ⧀āĻŦā§‹āĻ°ā§āĻĄ āĻļāĻ°ā§āϟāĻ•āĻžāϟ āϰāϝāĻŧ⧇āϛ⧇āσ" +msgstr "" #: src/running-the-course/keyboard-shortcuts.md -msgid "Arrow-Left" -msgstr "Arrow-Left" +msgid "Arrow-Left: Navigate to the previous page." +msgstr "" #: src/running-the-course/keyboard-shortcuts.md -msgid ": Navigate to the previous page." -msgstr ": Navigate to the previous page." +msgid "Arrow-Right: Navigate to the next page." +msgstr "" #: src/running-the-course/keyboard-shortcuts.md -msgid "Arrow-Right" -msgstr "Arrow-Right" +msgid "" +"Ctrl + Enter: Execute the code sample that has focus." +msgstr "" #: src/running-the-course/keyboard-shortcuts.md -msgid ": Navigate to the next page." -msgstr ": Navigate to the next page." - -#: src/running-the-course/keyboard-shortcuts.md src/cargo/code-samples.md -msgid "Ctrl + Enter" -msgstr "Ctrl + Enter" +msgid "s: Activate the search bar." +msgstr "" #: src/running-the-course/keyboard-shortcuts.md -msgid ": Execute the code sample that has focus." -msgstr ": Execute the code sample that has focus." +msgid "" +"Mention that these shortcuts are standard for `mdbook` and can be useful " +"when navigating any `mdbook`\\-generated site." +msgstr "" #: src/running-the-course/keyboard-shortcuts.md -msgid "s" -msgstr "s" +msgid "You can demonstrate each shortcut live to the students." +msgstr "" #: src/running-the-course/keyboard-shortcuts.md -msgid ": Activate the search bar." -msgstr ": Activate the search bar." +msgid "" +"The s key for search is particularly useful for quickly finding " +"topics that have been discussed earlier." +msgstr "" + +#: src/running-the-course/keyboard-shortcuts.md +msgid "" +"Ctrl + Enter will be super important for you since " +"you'll do a lot of live coding." +msgstr "" #: src/running-the-course/translations.md msgid "" "The course has been translated into other languages by a set of wonderful " "volunteers:" -msgstr "āϕ⧋āĻ°ā§āϏāϟāĻŋ āĻŦāĻŋāĻ¸ā§āĻŽāϝāĻŧāĻ•āϰ āĻāĻ•āϟāĻŋ āϏ⧇āϟ āĻ¸ā§āĻŦ⧇āĻšā§āĻ›āĻžāϏ⧇āĻŦāĻ• āĻĻā§āĻŦāĻžāϰāĻž āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āĻ­āĻžāώāĻžāϝāĻŧ āĻ…āύ⧁āĻŦāĻžāĻĻ āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇āσ" +msgstr "" #: src/running-the-course/translations.md msgid "" @@ -1859,10 +2912,6 @@ msgid "" "com/hugojacob), [@joaovicmendes](https://github.com/joaovicmendes), and " "[@henrif75](https://github.com/henrif75)." msgstr "" -"[āĻŦā§āϰāĻžāϜāĻŋāϞ⧀āϝāĻŧ āĻĒāĻ°ā§āϤ⧁āĻ—ā§€āϜ](https://google.github.io/comprehensive-rust/pt-BR/) āĻ•āϰāĻž " -"āĻšā§Ÿā§‡āϛ⧇ [@rastringer](https://github.com/rastringer), [@hugojacob](https://" -"github.com/hugojacob), [@joaovicmendes](https://github.com/joaovicmendes) " -"āĻāĻŦāĻ‚ [@henrif75](https://github.com/henrif75) āĻĻā§āĻŦāĻžāϰāĻžāĨ¤" #: src/running-the-course/translations.md msgid "" @@ -1870,15 +2919,8 @@ msgid "" "by [@suetfei](https://github.com/suetfei), [@wnghl](https://github.com/" "wnghl), [@anlunx](https://github.com/anlunx), [@kongy](https://github.com/" "kongy), [@noahdragon](https://github.com/noahdragon), [@superwhd](https://" -"github.com/superwhd), [@SketchK](https://github.com/SketchK), and [@nodmp]" -"(https://github.com/nodmp)." +"github.com/superwhd), @SketchK, and [@nodmp](https://github.com/nodmp)." msgstr "" -"[āϏāϰāϞ⧀āĻ•ā§ƒāϤ āĻšā§€āύāĻž āĻ­āĻžāώāĻž](https://google.github.io/comprehensive-rust/zh-CN/) āĻ•āϰāĻž " -"āĻšā§Ÿā§‡āϛ⧇ [@suetfei](https://github.com/suetfei), [@wnghl](https://github.com/" -"wnghl), [@anlunx](https://github.com/anlunx), [@kongy](https://github.com/" -"kongy), [@noahdragon](https://github.com/noahdragon), [@superwhd](https://" -"github.com/superwhd), [@SketchK](https://github.com/SketchK), āĻāĻŦāĻ‚ [@nodmp]" -"(https://github.com/nodmp) āĻĻā§āĻŦāĻžāϰāĻžāĨ¤" #: src/running-the-course/translations.md msgid "" @@ -1888,11 +2930,23 @@ msgid "" "github.com/kuanhungchen), and [@johnathan79717](https://github.com/" "johnathan79717)." msgstr "" -"[āϐāϤāĻŋāĻšā§āϝāĻ—āϤ āĻšā§€āύāĻž āĻ­āĻžāώāĻž](https://google.github.io/comprehensive-rust/zh-TW/) āĻ•āϰāĻž " -"āĻšā§Ÿā§‡āϛ⧇ [@hueich](https://github.com/hueich), [@victorhsieh](https://github." -"com/victorhsieh), [@mingyc](https://github.com/mingyc), [@kuanhungchen]" -"(https://github.com/kuanhungchen), āĻāĻŦāĻ‚ [@johnathan79717](https://github.com/" -"johnathan79717) āĻĻā§āĻŦāĻžāϰāĻžāĨ¤" + +#: src/running-the-course/translations.md +msgid "" +"[Farsi](https://google.github.io/comprehensive-rust/fa/) by [@DannyRavi]" +"(https://github.com/DannyRavi), [@javad-jafari](https://github.com/javad-" +"jafari), [@Alix1383](https://github.com/alix1383), [@moaminsharifi](https://" +"github.com/moaminsharifi) , [@hamidrezakp](https://github.com/hamidrezakp) " +"and [@mehrad77](https://github.com/mehrad77)." +msgstr "" + +#: src/running-the-course/translations.md +msgid "" +"[Japanese](https://google.github.io/comprehensive-rust/ja/) by [@CoinEZ-JPN]" +"(https://github.com/CoinEZ), [@momotaro1105](https://github.com/" +"momotaro1105), [@HidenoriKobayashi](https://github.com/HidenoriKobayashi) " +"and [@kantasv](https://github.com/kantasv)." +msgstr "" #: src/running-the-course/translations.md msgid "" @@ -1901,68 +2955,59 @@ msgid "" "[@jooyunghan](https://github.com/jooyunghan), and [@namhyung](https://github." "com/namhyung)." msgstr "" -"[āϕ⧋āϰāĻŋāϝāĻŧāĻžāύ](https://google.github.io/comprehensive-rust/ko/) āĻ•āϰāĻž āĻšā§Ÿā§‡āϛ⧇ " -"[@keispace](https://github.com/keispace), [@jiyongp](https://github.com/" -"jiyongp) āĻāĻŦāĻ‚ [@jooyunghan](https://github.com/jooyunghan) āĻĻā§āĻŦāĻžāϰāĻžāĨ¤" #: src/running-the-course/translations.md msgid "" "[Spanish](https://google.github.io/comprehensive-rust/es/) by [@deavid]" "(https://github.com/deavid)." msgstr "" -"[āĻ¸ā§āĻĒā§āϝāĻžāύāĻŋāĻļ āĻ­āĻžāώāĻž](https://google.github.io/comprehensive-rust/es/) āĻ•āϰāĻž āĻšā§Ÿā§‡āϛ⧇ " -"[@deavid](https://github.com/deavid) āĻĻā§āĻŦāĻžāϰāĻžāĨ¤" + +#: src/running-the-course/translations.md +msgid "" +"[Ukrainian](https://google.github.io/comprehensive-rust/uk/) by [@git-user-" +"cpp](https://github.com/git-user-cpp), [@yaremam](https://github.com/" +"yaremam) and [@reta](https://github.com/reta)." +msgstr "" #: src/running-the-course/translations.md msgid "" "Use the language picker in the top-right corner to switch between languages." -msgstr "āĻ­āĻžāώāĻžāϰ āĻŽāĻ§ā§āϝ⧇ āĻ¸ā§āϝ⧁āχāϚ āĻ•āϰāϤ⧇ āωāĻĒāϰ⧇āϰ-āĻĄāĻžāύ āϕ⧋āϪ⧇ āĻ­āĻžāώāĻž āϚāϝāĻŧāύāĻ•āĻžāϰ⧀ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧁āύāĨ¤" +msgstr "" #: src/running-the-course/translations.md msgid "Incomplete Translations" -msgstr "āĻ…āϏāĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻ…āύ⧁āĻŦāĻžāĻĻ" +msgstr "" #: src/running-the-course/translations.md msgid "" "There is a large number of in-progress translations. We link to the most " "recently updated translations:" msgstr "" -"āĻĒā§āϰāϚ⧁āϰ āϏāĻ‚āĻ–ā§āϝāĻ• āĻ…āύ⧁āĻŦāĻžāĻĻ āϚāϞāϛ⧇āĨ¤ āφāĻŽāϰāĻž āϏāĻžāĻŽā§āĻĒā§āϰāϤāĻŋāĻ• āφāĻĒāĻĄā§‡āϟ āĻšāĻ“āϝāĻŧāĻž āĻ…āύ⧁āĻŦāĻžāĻĻāϗ⧁āϞāĻŋāϰ āϏāĻžāĻĨ⧇ āϞāĻŋāĻ™ā§āĻ• āĻ•āϰāĻŋāσ" + +#: src/running-the-course/translations.md +msgid "" +"[Arabic](https://google.github.io/comprehensive-rust/ar/) by [@younies]" +"(https://github.com/younies)" +msgstr "" #: src/running-the-course/translations.md msgid "" "[Bengali](https://google.github.io/comprehensive-rust/bn/) by [@raselmandol]" "(https://github.com/raselmandol)." msgstr "" -"[āĻŦāĻžāĻ‚āϞāĻž](https://google.github.io/comprehensive-rust/bn/) āĻ•āϰāĻž āĻšā§Ÿā§‡āϛ⧇ " -"[@abhik-99](https://github.com/abhik-99) āĻāĻŦāĻ‚ [@raselmandol](https://github." -"com/raselmandol) āĻĻā§āĻŦāĻžāϰāĻžāĨ¤" #: src/running-the-course/translations.md msgid "" "[French](https://google.github.io/comprehensive-rust/fr/) by [@KookaS]" -"(https://github.com/KookaS) and [@vcaen](https://github.com/vcaen)." +"(https://github.com/KookaS), [@vcaen](https://github.com/vcaen) and " +"[@AdrienBaudemont](https://github.com/AdrienBaudemont)." msgstr "" -"[French](https://google.github.io/comprehensive-rust/fr/) by [@KookaS]" -"(https://github.com/KookaS) and [@vcaen](https://github.com/vcaen)" #: src/running-the-course/translations.md msgid "" "[German](https://google.github.io/comprehensive-rust/de/) by [@Throvn]" "(https://github.com/Throvn) and [@ronaldfw](https://github.com/ronaldfw)." msgstr "" -"[German](https://google.github.io/comprehensive-rust/de/) by [@Throvn]" -"(https://github.com/Throvn) and [@ronaldfw](https://github.com/ronaldfw)." - -#: src/running-the-course/translations.md -msgid "" -"[Japanese](https://google.github.io/comprehensive-rust/ja/) by [@CoinEZ-JPN]" -"(https://github.com/CoinEZ) and [@momotaro1105](https://github.com/" -"momotaro1105)." -msgstr "" -"[Japanese](https://google.github.io/comprehensive-rust/ja/) by [@CoinEZ-JPN]" -"(https://github.com/CoinEZ) and [@momotaro1105](https://github.com/" -"momotaro1105)." #: src/running-the-course/translations.md msgid "" @@ -1970,9 +3015,14 @@ msgid "" "[@henrythebuilder](https://github.com/henrythebuilder) and [@detro](https://" "github.com/detro)." msgstr "" -"[āχāϤāĻžāϞāĻŋāϝāĻŧāĻžāύ āĻ­āĻžāώāĻž](https://google.github.io/comprehensive-rust/it/) āĻ•āϰāĻž āĻšā§Ÿā§‡āϛ⧇ " -"[@henrythebuilder](https://github.com/henrythebuilder) āĻāĻŦāĻ‚ [@detro](https://" -"github.com/detro) āĻĻā§āĻŦāĻžāϰāĻžāĨ¤" + +#: src/running-the-course/translations.md +msgid "" +"The full list of translations with their current status is also available " +"either [as of their last update](https://google.github.io/comprehensive-rust/" +"translation-report.html) or [synced to the latest version of the course]" +"(https://google.github.io/comprehensive-rust/synced-translation-report.html)." +msgstr "" #: src/running-the-course/translations.md msgid "" @@ -1981,8 +3031,25 @@ msgid "" "get going. Translations are coordinated on the [issue tracker](https://" "github.com/google/comprehensive-rust/issues/282)." msgstr "" -"āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āĻāχ āĻĒā§āϰāĻšā§‡āĻˇā§āϟāĻžāϝāĻŧ āϏāĻžāĻšāĻžāĻ¯ā§āϝ āĻ•āϰāϤ⧇ āϚāĻžāύ, āϤāĻžāĻšāϞ⧇ āϕ⧀āĻ­āĻžāĻŦ⧇ āĻļ⧁āϰ⧁ āĻ•āϰāĻŦ⧇āύ āϤāĻžāϰ āϜāĻ¨ā§āϝ " -"\\[āφāĻŽāĻžāĻĻ⧇āϰ āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻžāĻŦāϞ⧀\\] āĻĻ⧇āϖ⧁āύāĨ¤ āĻ…āύ⧁āĻŦāĻžāĻĻāϗ⧁āϞāĻŋ \\[āχāĻ¸ā§āϝ⧁ āĻŸā§āĻ°ā§āϝāĻžāĻ•āĻžāϰ\\] āĻ āϏāĻŽāĻ¨ā§āĻŦāĻŋāϤ āĻšāϝāĻŧ⧇āϛ⧇āĨ¤" + +#: src/running-the-course/translations.md +msgid "" +"This is a good opportunity to thank the volunteers who have contributed to " +"the translations." +msgstr "" + +#: src/running-the-course/translations.md +msgid "" +"If there are students in the class who speak any of the listed languages, " +"you can encourage them to check out the translated versions and even " +"contribute if they find any issues." +msgstr "" + +#: src/running-the-course/translations.md +msgid "" +"Highlight that the project is open source and contributions are welcome, not " +"just for translations but for the course content itself." +msgstr "" #: src/cargo.md msgid "" @@ -1992,29 +3059,21 @@ msgid "" "Cargo is and how it fits into the wider ecosystem and how it fits into this " "training." msgstr "" -"āφāĻĒāύāĻŋ āϝāĻ–āύ āϰāĻžāĻ¸ā§āϟ āϏāĻŽā§āĻŦāĻ¨ā§āϧ⧇ āĻĒāĻĄāĻŧāĻž āĻļ⧁āϰ⧁ āĻ•āϰāĻŦ⧇āύ, āφāĻĒāύāĻŋ āĻļā§€āĻ˜ā§āϰāχ [āĻ•āĻžāĻ°ā§āĻ—ā§‹](https://doc.rust-lang." -"org/cargo/) āĻāϰ āϏāĻžāĻĨ⧇ āĻĻ⧇āĻ–āĻž āĻ•āϰāĻŦ⧇āύ, āĻāĻ•āϟāĻŋ āφāĻĻāĻ°ā§āĻļ āϟ⧁āϞ āϝāĻž Rust āĻ…ā§āϝāĻžāĻĒā§āϞāĻŋāϕ⧇āĻļāύ āϤ⧈āϰāĻŋ āĻāĻŦāĻ‚ " -"āϚāĻžāϞāĻžāύ⧋āϰ āϜāĻ¨ā§āϝ Rust āχāϕ⧋āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽā§‡ āĻŦā§āϝāĻŦāĻšā§ƒāϤ āĻšāϝāĻŧ⧇āϛ⧇āĨ¤ āĻāĻ–āĻžāύ⧇ āφāĻŽāϰāĻž āϚāĻžāχ āĻ•āĻžāĻ°ā§āĻ—ā§‹ āϕ⧀ āĻāĻŦāĻ‚ āĻāϟāĻŋ " -"āϕ⧀āĻ­āĻžāĻŦ⧇ āĻŦ⧃āĻšāĻ¤ā§āϤāϰ āχāϕ⧋āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽā§‡ āĻĢāĻŋāϟ āĻ•āϰ⧇ āϤāĻžāϰ āĻāĻ•āϟāĻŋ āϏāĻ‚āĻ•ā§āώāĻŋāĻĒā§āϤ āĻŦāĻŋāĻŦāϰāĻŖ āĻĻāĻŋāϤ⧇ āĻāĻŦāĻ‚ āĻ•āĻŋāĻ­āĻžāĻŦ⧇ āĻāϟāĻŋ " -"āĻāχ āĻĒā§āϰāĻļāĻŋāĻ•ā§āώāϪ⧇āϰ āϏāĻžāĻĨ⧇ āĻ–āĻžāĻĒ āĻ–āĻžāϝāĻŧāĨ¤" #: src/cargo.md msgid "Installation" -msgstr "Installation" +msgstr "" #: src/cargo.md msgid "**Please follow the instructions on .**" -msgstr "**. āĻ āĻĻ⧇āĻ“ā§ŸāĻž āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻžāĻŦāϞ⧀ āĻ…āύ⧁āϏāϰāĻŖ āĻ•āϰ⧁āύāĨ¤**" +msgstr "" #: src/cargo.md msgid "" "This will give you the Cargo build tool (`cargo`) and the Rust compiler " "(`rustc`). You will also get `rustup`, a command line utility that you can " -"use to install to different compiler versions." +"use to install different compiler versions." msgstr "" -"āĻāĻ­āĻžāĻŦ⧇ āφāĻĒāύāĻŋ āĻ•āĻžāĻ°ā§āĻ—ā§‹ (`cargo`) āĻāĻŦāĻ‚ āϰāĻžāĻ¸ā§āĻŸā§‡āϰ āĻ•āĻŽā§āĻĒāĻžāχāϞāĻžāϰ (`rustc`) āĻĒā§‡ā§Ÿā§‡ āϝāĻžāĻŦ⧇āύāĨ¤ āĻ•āĻžāĻ°ā§āĻ—ā§‹ " -"āύāĻŋāĻ°ā§āĻŽāĻžāĻŖāĻ•āĻžāĻ°ā§āϝ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āĻšāĻŦ⧇āĨ¤ āωāĻĒāϰāĻ¨ā§āϤ⧁ `rustup` āĻ“ āĻĒā§‡ā§Ÿā§‡ āϝāĻžāĻŦ⧇āύāĨ¤ āĻāϟāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āĻšā§Ÿā§‡ " -"āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āύ āϰāĻžāĻ¸ā§āĻŸā§‡āϰ āĻ•āĻŽā§āĻĒāĻžāχāϞāĻžāϰ āĻāϰ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻāĻ•āχ āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽ āĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻŦāĻžāϰ āϜāĻ¨ā§āϝ⧇āĨ¤" #: src/cargo.md msgid "" @@ -2026,43 +3085,32 @@ msgid "" "analyzer.github.io/manual.html#vimneovim), and many others. There is also a " "different IDE available called [RustRover](https://www.jetbrains.com/rust/)." msgstr "" -"āϰāĻžāĻ¸ā§āϟ āχāύāĻ¸ā§āϟāϞ āĻ•āϰāĻŦāĻžāϰ āĻĒāϰ⧇ āφāĻĒāύāĻžāϰ āĻāĻĄāĻŋāϟāϰ āĻŦāĻž āφāχ.āĻĄāĻŋ.āχ āϏāĻœā§āϜāĻŋāϤ āĻ•āϰāĻž āĻĻāϰāĻ•āĻžāϰāĨ¤ āĻŦ⧇āĻļāĻŋāϰāĻ­āĻžāĻ— āĻāĻĄāĻŋāϟāϰ " -"āĻāχāϜāĻ¨ā§āϝ⧇ [rust-analyzer](https://rust-analyzer.github.io/) āĻāϰ āϏāĻžāĻĨ⧇ āϝ⧋āĻ—āĻžāϝ⧋āĻ— āĻ•āϰ⧇ " -"āĻ•āϰāϤ⧇ āϏāĻ•ā§āώāĻŽāĨ¤ [rust-analyzer](https://rust-analyzer.github.io/) [VS Code]" -"(https://code.visualstudio.com/), [Emacs](https://rust-analyzer.github.io/" -"manual.html#emacs), [Vim/Neovim](https://rust-analyzer.github.io/manual." -"html#vimneovim) āĻāĻŦāĻ‚ āχāĻ¤ā§āϝāĻžāĻĻāĻŋāϰ āϜāĻ¨ā§āϝ⧇ āĻ¸ā§āĻŦāϝāĻŧāĻ‚-āϏāĻŽā§āĻĒā§‚āĻ°ā§āĻŖāϤāĻž āĻāĻŦāĻ‚ āϏāϰāĻžāϏāϰāĻŋ āϏāĻ‚āĻœā§āĻžāĻžāϝāĻŧ āϖ⧁āϜāĻžāϰ āĻŽāϤāύ " -"āĻ•āĻžāĻ°ā§āϝāĻ•āĻžāϰāĻŋāϤāĻž āĻĒā§āϰāĻĻāĻžāύ āĻ•āϰ⧇āĨ¤ āφāϰ⧇āϟāĻž āφāχ.āĻĄāĻŋ.āχ-āĻ“ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āϝ⧇āϤ⧇ āĻĒāĻžāϰ⧇ āĻāĻ–āĻžāύ⧇ āϝāĻžāϰ āύāĻžāĻŽ " -"[RustRover](https://www.jetbrains.com/rust/)āĨ¤" + +#: src/cargo.md +msgid "On Debian/Ubuntu, you can install `rustup` via `apt`:" +msgstr "" #: src/cargo.md msgid "" -"On Debian/Ubuntu, you can also install Cargo, the Rust source and the [Rust " -"formatter](https://github.com/rust-lang/rustfmt) via `apt`. However, this " -"gets you an outdated rust version and may lead to unexpected behavior. The " -"command would be:" +"On macOS, you can use [Homebrew](https://brew.sh/) to install Rust, but this " +"may provide an outdated version. Therefore, it is recommended to install " +"Rust from the official site." msgstr "" -"āĻĄā§‡āĻŦāĻŋ⧟āĻžāύ āĻŦāĻž āωāĻŦ⧁āĻ¨ā§āϟ⧁ āϤ⧇āĻ“ `apt` āĻĻā§āĻŦāĻžāϰāĻž āφāĻĒāύāĻŋ āĻ•āĻžāĻ°ā§āĻ—ā§‹, āϰāĻžāĻ¸ā§āĻŸā§‡āϰ āĻ‰ā§ŽāϏ āĻāĻŦāĻ‚ [Rust formatter]" -"(https://github.com/rust-lang/rustfmt) āχāύāĻ¸ā§āϟāϞ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤ āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻāχ āĻĒāĻĻā§āϧāϤāĻŋāϤ⧇ " -"āĻ•āϰāϞ⧇ āĻĒ⧁āϰ⧋āύ⧋ āϰāĻžāĻ¸ā§āĻŸā§‡āϰ āϏāĻ‚āĻ•āϰāĻŖ āĻĒāĻžāĻŦāĻžāϰ āϏāĻŽā§āĻ­āĻŦāύāĻž āφāϛ⧇āĨ¤ āĻāϰ āĻĻāϰ⧁āύ āĻ…āĻĒā§āϰāĻ¤ā§āϝāĻžāĻļāĻŋāϤ āφāϚāϰāĻŖ āĻĒā§āϰāĻĻāĻ°ā§āĻļāύ āĻšāϤ⧇ " -"āĻĒāĻžāϰ⧇āĨ¤ āĻāϰ āϜāĻ¨ā§āϝ⧇ āĻ•āĻŽā§āϝāĻžāĻ¨ā§āĻĄ āĻšāϞ⧋:" #: src/cargo/rust-ecosystem.md msgid "The Rust Ecosystem" -msgstr "The Rust āĻāϰ āχāϕ⧋āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽ" +msgstr "" #: src/cargo/rust-ecosystem.md msgid "" "The Rust ecosystem consists of a number of tools, of which the main ones are:" -msgstr "The Rust ecosystem āĻ āĻŦ⧇āĻļ āĻ•āϝāĻŧ⧇āĻ•āϟāĻŋ āϏāϰāĻžā§āϜāĻžāĻŽ āϰāϝāĻŧ⧇āϛ⧇, āϝāĻžāϰ āĻŽāĻ§ā§āϝ⧇ āĻĒā§āϰāϧāĻžāύāϗ⧁āϞāĻŋ āĻšāϞ:" +msgstr "" #: src/cargo/rust-ecosystem.md msgid "" -"`rustc`: the Rust compiler which turns `.rs` files into binaries and other " +"`rustc`: the Rust compiler that turns `.rs` files into binaries and other " "intermediate formats." msgstr "" -"`rustc`: Rust āĻ•āĻŽā§āĻĒāĻžāχāϞāĻžāϰ āϝāĻž `.rs` āĻĢāĻžāχāϞāϗ⧁āϞāĻŋāϕ⧇ āĻŦāĻžāχāύāĻžāϰāĻŋ āĻāĻŦāĻ‚ āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝāϗ⧁āϞāĻŋāϤ⧇ āĻĒāϰāĻŋāĻŖāϤ āĻ•āϰ⧇ " -"āĻŽāĻ§ā§āϝāĻŦāĻ°ā§āϤ⧀ āĻŦāĻŋāĻ¨ā§āϝāĻžāϏ⧇āĨ¤" #: src/cargo/rust-ecosystem.md msgid "" @@ -2071,11 +3119,6 @@ msgid "" "pass them to `rustc` when building your project. Cargo also comes with a " "built-in test runner which is used to execute unit tests." msgstr "" -"`cargo`: āϰāĻžāĻ¸ā§āĻŸā§‡āϰ āύāĻŋāĻ°ā§āĻ­āϰāϤāĻž āĻŦā§āϝāĻŦāĻ¸ā§āĻĨāĻžāĻĒāĻ• āĻāĻŦāĻ‚ āύāĻŋāĻ°ā§āĻŽāĻžāĻŖ āϏāĻžāϧāύ⧀āĨ¤ āĻ•āĻžāĻ°ā§āĻ—ā§‹ āϜāĻžāύ⧇ āĻ•āĻŋāĻ­āĻžāĻŦ⧇ " -"\\-āĻ āĻšā§‹āĻ¸ā§āϟ āĻ•āϰāĻž āϝ⧇ āϏāĻŦ āĻ•ā§āĻ°ā§āϝāĻžāϟāϗ⧁āϞ⧋ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽā§‡āϰ āϜāĻ¨ā§āϝ⧇ āĻĻāϰāĻ•āĻžāϰ āϏ⧇āϗ⧁āϞāĻŋ " -"āĻĄāĻžāωāύāϞ⧋āĻĄ āĻ•āϰāϤ⧇ āĻšāϝāĻŧ āĻāĻŦāĻ‚ āĻāϟāĻŋ āϤāĻžāĻĻ⧇āϰ āĻĒāĻžāϏ āĻ•āϰāĻŦ⧇ āφāĻĒāύāĻžāϰ āĻĒā§āϰāĻœā§‡āĻ•ā§āϟ āϤ⧈āϰāĻŋ āĻ•āϰāĻžāϰ āϏāĻŽāϝāĻŧ `rustc` " -"āϤ⧇āĨ¤ āĻ•āĻžāĻ°ā§āĻ—ā§‹ āĻāĻ•āϟāĻŋ āĻ…āĻ¨ā§āϤāĻ°ā§āύāĻŋāĻ°ā§āĻŽāĻŋāϤ āĻĒāϰ⧀āĻ•ā§āώāĻž āĻĒāϰāĻŋāϚāĻžāϞāĻ• āĻāϰ āϏāĻ™ā§āϗ⧇ āφāϏ⧇ āϰāĻžāύāĻžāϰ āϝāĻž āϏāĻ°ā§āĻŦāύāĻŋāĻŽā§āύ āĻĒāϰ⧀āĻ•ā§āώāĻž " -"āϚāĻžāϞāĻžāύ⧋āϰ āϜāĻ¨ā§āϝ āĻŦā§āϝāĻŦāĻšā§ƒāϤ āĻšāϝāĻŧāĨ¤" #: src/cargo/rust-ecosystem.md msgid "" @@ -2085,19 +3128,13 @@ msgid "" "standard library. You can have multiple versions of Rust installed at once " "and `rustup` will let you switch between them as needed." msgstr "" -"`rustup`: āϰāĻžāĻ¸ā§āϟ āϟ⧁āϞāĻšā§‡āχāύ āχāύāĻ¸ā§āϟāϞāĻžāϰ āĻāĻŦāĻ‚ āφāĻĒāĻĄā§‡āϟāĻžāϰāĨ¤ āĻāχ āϟ⧁āϞ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āĻšāϝāĻŧ āϰāĻžāĻ¸ā§āϟ-āĻāϰ āύāϤ⧁āύ " -"āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻĒā§āϰāĻ•āĻžāĻļāĻŋāϤ āĻšāϞ⧇ `rustc` āĻāĻŦāĻ‚ `cargo` āχāύāĻ¸ā§āϟāϞ āĻ“ āφāĻĒāĻĄā§‡āϟ āĻ•āϰāϤ⧇āĨ¤ āωāĻĒāϰāĻ¨ā§āϤ⧁, `rustup` " -"āĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄā§‡ āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋāϰ āϜāĻ¨ā§āϝ āĻĄāϕ⧁āĻŽā§‡āĻ¨ā§āĻŸā§‡āĻļāύāĻ“ āĻĄāĻžāωāύāϞ⧋āĻĄ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇ āφāĻĒāύāĻŋ āĻāĻ•āĻŦāĻžāϰ⧇ Rust āĻāϰ " -"āĻāĻ•āĻžāϧāĻŋāĻ• āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āĻāĻŦāĻ‚ `āϰāĻ¸ā§āϟāφāĻĒ` āχāύāĻ¸ā§āϟāϞ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ āĻĒā§āϰāϝāĻŧā§‹āϜāύ āĻ…āύ⧁āϏāĻžāϰ⧇ āφāĻĒāύāĻžāϕ⧇ āϤāĻžāĻĻ⧇āϰ āĻŽāĻ§ā§āϝ⧇ " -"āĻ¸ā§āϝ⧁āχāϚ āĻ•āϰāϤ⧇ āĻĻ⧇āĻŦ⧇āĨ¤" #: src/cargo/rust-ecosystem.md src/types-and-values/hello-world.md -#: src/tuples-and-arrays/tuples-and-arrays.md src/references/exclusive.md -#: src/pattern-matching/destructuring.md src/memory-management/move.md -#: src/error-handling/try.md src/android/setup.md src/concurrency/threads.md -#: src/async/async-await.md +#: src/references/exclusive.md src/memory-management/move.md +#: src/error-handling/try.md src/unsafe-rust/unsafe-functions/calling.md +#: src/android/setup.md src/concurrency/async/async-await.md msgid "Key points:" -msgstr "āϗ⧁āϰ⧁āĻ¤ā§āĻŦāĻĒā§‚āĻ°ā§āĻŖ āĻĻāĻŋāĻ•:" +msgstr "" #: src/cargo/rust-ecosystem.md msgid "" @@ -2105,71 +3142,54 @@ msgid "" "weeks. New releases maintain backwards compatibility with old releases --- " "plus they enable new functionality." msgstr "" -"āϰāĻžāĻ¸ā§āϟ āĻĻā§āϰ⧁āϤ āĻĒā§āϰāĻ•āĻžāĻļ⧇āϰ āϏāĻŽāϝāĻŧāϏ⧂āĻšā§€ āĻ…āύ⧁āϏāϰāĻŖ āĻ•āϰ⧇ āϝāĻžāϰ āĻĻāϰ⧁āύ āĻĒā§āϰāĻ¤ā§āϝ⧇āĻ• ā§Ŧ āĻŽāĻžāϏ āĻ…āĻ¨ā§āϤāϰ-āĻ…āĻ¨ā§āϤāϰ āύāϤ⧁āύ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ " -"āĻĒā§āϰāĻ•āĻžāĻļ āĻ•āϰāĻž āĻšā§Ÿā§‡āĨ¤ āύāϤ⧁āύ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖāϗ⧁āϞāĻŋ āĻĒ⧁āϰ⧋āύ⧋ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖāϗ⧁āϞāĻŋāϰ āϏāĻžāĻĨ⧇ āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝ āĻŦāϜāĻžāϝāĻŧ āϰāĻžāĻ–āĻžāϰ " -"āĻ…āϤāĻŋāϰāĻŋāĻ•ā§āϤ āύāϤ⧁āύ āĻŦ⧈āĻļāĻŋāĻˇā§āĻŸā§āϝ āφāύ⧇āĨ¤" #: src/cargo/rust-ecosystem.md msgid "" "There are three release channels: \"stable\", \"beta\", and \"nightly\"." msgstr "" -"āύāϤ⧁āύ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ-āĻŽā§āĻ•ā§āϤāĻŋāϰ āϜāĻ¨ā§āϝ⧇ ā§ŠāϟāĻŋ āĻ—āϤāĻŋāĻĒāĻĨ āϰāĻžāĻ–āĻž āĻšā§Ÿā§‡āϛ⧇ - \"stable\" (āĻ¸ā§āĻŸā§āϝāĻžāĻŦāϞ - āĻ¸ā§āĻĨāĻŋāϤāĻŋāĻļā§€āϞ), " -"\"beta\" (āĻŦāĻŋāϟāĻž -āĻĒā§āϰāĻžāĻ• āĻŽā§āĻ•ā§āϤāĻŋ āύāĻŋāĻ°ā§āĻŽāĻŋāϤ) āĻāĻŦāĻ‚ \"nightly\" (āύāĻžāχāϟāϞāĻŋ - āϰāĻžāĻ¤ā§āϰāĻŋāĻ•āĻžāϞ⧀āύ)āĨ¤" #: src/cargo/rust-ecosystem.md msgid "" "New features are being tested on \"nightly\", \"beta\" is what becomes " "\"stable\" every six weeks." msgstr "" -"āύāϤ⧁āύ āĻŦ⧈āĻļāĻŋāĻˇā§āϟāϗ⧁āϞāĻŋ āύāĻžāχāϟāϞāĻŋ āύāĻŋāĻ°ā§āĻŽāĻŋāϤ āϰāĻžāĻ¸ā§āϟ-āĻ āĻĒāϰ⧀āĻ•ā§āώāĻž āĻ•āϰāĻž āĻšā§Ÿā§‡ āĻāĻŦāĻ‚ āĻŦāĻŋāϟāĻž āύāĻŋāĻ°ā§āĻŽāĻŋāϤ āĻĒā§āϰāĻ¤ā§āϝ⧇āĻ• " -"ā§ŦāĻŽāĻžāϏ⧇ āĻ¸ā§āĻŸā§āϝāĻžāĻŦāϞ āϏāĻ‚āĻ•āϰāĻŖ āĻšā§Ÿā§‡ āϝāĻžā§ŸāĨ¤" #: src/cargo/rust-ecosystem.md msgid "" "Dependencies can also be resolved from alternative [registries](https://doc." "rust-lang.org/cargo/reference/registries.html), git, folders, and more." msgstr "" -"āĻĄāĻŋāĻĒ⧇āĻ¨ā§āĻĄā§‡āĻ¨ā§āϏāĻŋāϰ āϏāĻŽāĻžāϧāĻžāύ āĻ•āϰāĻŦāĻžāϰ āϜāĻ¨ā§āϝ⧇ āϝ⧇āϕ⧋āύ⧋ [āĻŦ⧈āĻ•āĻ˛ā§āĻĒāĻŋāĻ• āϰ⧇āϜāĻŋāĻ¸ā§āĻŸā§āϰāĻŋ](https://doc.rust-" -"lang.org/cargo/reference/registries.html), āĻ—āĻŋāĻŸā§, āĻĢā§‹āĻ˛ā§āĻĄāĻžāϰ āχāĻ¤ā§āϝāĻžāĻĻāĻŋāϰ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ“ āĻ•āϰāĻž " -"āϝ⧇āϤ⧇ āĻĒāĻžāϰ⧇āĨ¤" #: src/cargo/rust-ecosystem.md msgid "" "Rust also has [editions](https://doc.rust-lang.org/edition-guide/): the " -"current edition is Rust 2021. Previous editions were Rust 2015 and Rust 2018." +"current edition is Rust 2024. Previous editions were Rust 2015, Rust 2018 " +"and Rust 2021." msgstr "" -"āϰāĻžāĻ¸ā§āĻŸā§‡āϰ [āĻĒā§āϰāĻ•āĻžāĻļāύ](https://doc.rust-lang.org/edition-guide/) -āĻ“ āφāϛ⧇: āχāĻĻāĻžāύāĻŋāĻ‚ " -"āϰāĻžāĻ¸ā§āϟ ⧍ā§Ļ⧍⧧ āĻĒā§āϰāĻ•āĻžāĻļāύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āĻšā§ŸāĨ¤ āĻāϰ āφāϗ⧇āϰ āĻĒā§āϰāĻ•āĻžāĻļāύāϗ⧁āϞāĻŋ āĻšāϞ⧋ āϰāĻžāĻ¸ā§āϟ ⧍ā§Ļā§§ā§Ģ āĻāĻŦāĻ‚ āϰāĻžāĻ¸ā§āϟ ⧍ā§Ļā§§āĨ¤" #: src/cargo/rust-ecosystem.md msgid "" "The editions are allowed to make backwards incompatible changes to the " "language." -msgstr "āĻāĻ•āϟāĻŋ āĻĒā§āϰāĻ•āĻžāĻļāύ āφāϗ⧇āϰ āĻĒā§āϰāĻ•āĻžāĻļāύ āĻāϰ āϏāĻ™ā§āϗ⧇ āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝ āĻŦāϜāĻžā§Ÿ āύāĻžāĻ“ āϰāĻžāĻ–āϤ⧇ āĻĒāĻžāϰ⧇āĨ¤" +msgstr "" #: src/cargo/rust-ecosystem.md msgid "" "To prevent breaking code, editions are opt-in: you select the edition for " "your crate via the `Cargo.toml` file." msgstr "" -"āϝāĻžāϤ⧇ āϕ⧋āĻĄ āĻ•āϰāĻŦāĻžāϰ āĻĻāϰ⧁āύ āϭ⧇āϙ⧇ āύāĻž āϝāĻžā§Ÿ āϤāĻžāχ āύāĻŋāĻœā§‡āϰ āĻĒāĻ›āĻ¨ā§āĻĻ⧇āϰ āĻŽāϤāύ āĻĒā§āϰāĻ•āĻžāĻļāύ āĻŦ⧇āρāĻšā§‡ āύ⧇āĻŦāĻžāϰ āϏ⧁āĻŦāĻŋāϧāĻž " -"`Cargo.toml` āĻĢāĻžāχāϞ āĻĻā§āĻŦāĻžāϰāĻž āĻĻ⧇āĻ“ā§ŸāĻž āĻšā§Ÿā§‡āϛ⧇āĨ¤" #: src/cargo/rust-ecosystem.md msgid "" "To avoid splitting the ecosystem, Rust compilers can mix code written for " "different editions." msgstr "" -"āĻŦāĻžāĻ¸ā§āϤ⧁āϤāĻ¨ā§āĻ¤ā§āϰ āϝāĻžāϤ⧇ āĻŦāĻŋāĻ­āĻžāϜāĻŋāϤ āύāĻž āĻšā§Ÿ āϝāĻžā§Ÿ āϤāĻžāχ āϰāĻžāĻ¸ā§āϟ āĻ•āĻŽā§āĻĒāĻžāχāϞāĻžāϰ āφāϞāĻžāĻĻāĻž-āφāϞāĻžāĻĻāĻž āĻĒā§āϰāĻ•āĻžāĻļāύ⧇āϰ āϕ⧋āĻĄ " -"āĻāĻ•āϏāĻžāĻĨ⧇ āĻŽāĻŋāϞāĻŋā§Ÿā§‡ āĻ•āĻžāϜ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤" #: src/cargo/rust-ecosystem.md msgid "" "Mention that it is quite rare to ever use the compiler directly not through " "`cargo` (most users never do)." msgstr "" -"āϤāĻŦ⧇ āĻāϟāĻžāĻ“ āωāĻ˛ā§āϞ⧇āĻ–ā§āϝāϝ⧋āĻ—ā§āϝ āϝ⧇ āĻŦ⧇āĻļāĻŋāϰāĻ­āĻžāĻ— āϏāĻŽā§Ÿā§‡ `cargo` āύāĻž āĻ•āĻžāĻœā§‡ āϞāĻžāĻ—āĻŋā§Ÿā§‡ āĻ•āĻŽā§āĻĒāĻžāχāϞāĻžāϰ āϧāϰ⧇ āĻ•āĻžāϜ " -"āĻ•āϰāĻž āϖ⧁āĻŦāχ āĻĻ⧁āĻ°ā§āϞāĻ­ (āĻŦ⧇āĻļāĻŋāϰāĻ­āĻžāĻ— āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀ āĻ•āĻ–āύāχ āϤāĻž āĻ•āϰ⧇ āĻĨāĻžāϕ⧇ āύāĻž)āĨ¤" #: src/cargo/rust-ecosystem.md msgid "" @@ -2177,57 +3197,45 @@ msgid "" "comprehensive tool. It is capable of many advanced features including but " "not limited to:" msgstr "" -"āĻāĻŦāĻ‚ āĻāϟāĻžāĻ“ āĻŦāϞ⧇ āϰāĻžāĻ–āĻž āĻĻāϰāĻ•āĻžāϰ āϝ⧇ āĻ•āĻžāĻ°ā§āĻ—ā§‹ āύāĻŋāĻœā§‡āĻ“ āĻ…āύ⧇āĻ• āĻ•ā§āώāĻŽāϤāĻžāĻļā§€āϞ āĻ“ āĻŦāĻŋāĻ¸ā§āϤ⧀āĻ°ā§āĻŖ āĻāĻ•āϟāĻŋ āϏāĻžāϧāύāĨ¤ āĻāϰ " -"āĻĻā§āĻŦāĻžāϰāĻž āĻāĻ•āĻžāϧāĻŋāĻ• āφāϧ⧁āύāĻŋāĻ• āĻ•āĻžāϜ āĻ•āϰāĻž āϏāĻŽā§āĻ­āĻŦ āϝ⧇āĻŽāύ:" #: src/cargo/rust-ecosystem.md msgid "Project/package structure" -msgstr "āĻĒā§āϰāĻœā§‡āĻ•ā§āϟ/āĻĒā§āϝāĻžāϕ⧇āϜ āĻāϰ āĻ—āĻ āύ" +msgstr "" #: src/cargo/rust-ecosystem.md msgid "[workspaces](https://doc.rust-lang.org/cargo/reference/workspaces.html)" msgstr "" -"[āĻ•āĻ°ā§āĻŽāĻ•ā§āώ⧇āĻ¤ā§āϰ āĻŦāĻž āĻ“ā§ŸāĻžāĻ°ā§āĻ•āĻ¸ā§āĻĒ⧇āϏ⧇āϏ](https://doc.rust-lang.org/cargo/reference/" -"workspaces.html)" #: src/cargo/rust-ecosystem.md msgid "Dev Dependencies and Runtime Dependency management/caching" -msgstr "āĻĄā§‡āĻ­ āĻāĻŦāĻ‚ āϰāĻžāύāϟāĻŋāĻŽā§‡āϰ āύāĻŋāĻ°ā§āĻ­āϰāϤāĻž āĻĒāϰāĻŋāϚāĻžāϞāύāĻž āĻāĻŦāĻ‚ āĻ•ā§āϝāĻžāĻļāĻŋāĻ‚" +msgstr "" #: src/cargo/rust-ecosystem.md msgid "" "[build scripting](https://doc.rust-lang.org/cargo/reference/build-scripts." "html)" msgstr "" -"[āύāĻŋāĻ°ā§āĻŽāĻžāϪ⧇āϰ āϞāĻŋāĻĒāĻŋāϰāϚāύāĻž](https://doc.rust-lang.org/cargo/reference/build-scripts." -"html)" #: src/cargo/rust-ecosystem.md msgid "" "[global installation](https://doc.rust-lang.org/cargo/commands/cargo-install." "html)" msgstr "" -"[āϏāĻžāĻ°ā§āĻŦāϜāύ⧀āύ āĻ¸ā§āĻĨāĻžāĻĒāύāĻž](https://doc.rust-lang.org/cargo/commands/cargo-install." -"html)" #: src/cargo/rust-ecosystem.md msgid "" "It is also extensible with sub command plugins as well (such as [cargo " "clippy](https://github.com/rust-lang/rust-clippy))." msgstr "" -"[cargo clippy](https://github.com/rust-lang/rust-clippy)-āϰ āĻŽāϤāύ āύāĻžāύāĻžāύ āωāĻĒ-āφāĻĻ⧇āĻļ " -"āĻĒā§āϞāĻžāĻ—āĻŋāύ āĻ•āĻžāĻœā§‡ āϞāĻžāĻ—āĻŋā§Ÿā§‡āĻ“ āĻĒā§āϰāϏāĻžāϰāĻŋāϤ āĻ•āϰāĻž āϝāĻžā§ŸāĨ¤" #: src/cargo/rust-ecosystem.md msgid "" "Read more from the [official Cargo Book](https://doc.rust-lang.org/cargo/)" msgstr "" -"[āĻ…āĻĢāĻŋāϏāĻŋ⧟āĻžāϞ āĻ•āĻžāĻ°ā§āĻ—ā§‹ āĻŦāχ](https://doc.rust-lang.org/cargo/) āϤ⧇ āĻāχ āĻŦā§āϝāĻžāĻĒāĻžāϰ⧇ āφāϰāĻ“ āĻĒ⧜āϤ⧇ " -"āĻĒāĻžāϰāĻŦ⧇āύāĨ¤" #: src/cargo/code-samples.md msgid "Code Samples in This Training" -msgstr "āĻāχ āĻĒā§āϰāĻļāĻŋāĻ•ā§āώāϪ⧇ āϕ⧋āĻĄ āύāĻŽā§āύāĻž" +msgstr "" #: src/cargo/code-samples.md msgid "" @@ -2235,51 +3243,337 @@ msgid "" "which can be executed through your browser. This makes the setup much easier " "and ensures a consistent experience for everyone." msgstr "" -"āĻāχ āĻĒā§āϰāĻļāĻŋāĻ•ā§āώāϪ⧇āϰ āϜāĻ¨ā§āϝ, āφāĻŽāϰāĻž āĻŦ⧇āĻļāĻŋāϰāĻ­āĻžāĻ— āĻāĻŽāύ āωāĻĻāĻžāĻšāϰāϪ⧇āϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ āϰāĻžāĻ¸ā§āϟ āĻ­āĻžāώāĻž āĻ…āĻ¨ā§āĻŦ⧇āώāĻŖ āĻ•āϰāĻŦ āϝāĻž " -"āφāĻĒāύāĻžāϰ āĻŦā§āϰāĻžāωāϜāĻžāϰ⧇āϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ āĻ•āĻžāĻ°ā§āϝāĻ•āϰ āϚāϞāϤ⧇ āĻĒāĻžāϰāĻŦ⧇āĨ¤ āĻāϟāĻŋ āϏ⧇āϟāφāĻĒāϟāĻŋāϕ⧇ āφāϰāĻ“ āϏāĻšāϜ āĻ•āϰ⧇ āϤ⧋āϞ⧇ āĻāĻŦāĻ‚ " -"āĻĒā§āϰāĻ¤ā§āϝ⧇āϕ⧇āϰ āϜāĻ¨ā§āϝ āĻāĻ•āϟāĻŋ āϧāĻžāϰāĻžāĻŦāĻžāĻšāĻŋāĻ• āĻ…āĻ­āĻŋāĻœā§āĻžāϤāĻž āύāĻŋāĻļā§āϚāĻŋāϤ āĻ•āϰ⧇āĨ¤" #: src/cargo/code-samples.md msgid "" "Installing Cargo is still encouraged: it will make it easier for you to do " -"the exercises. On the last day, we will do a larger exercise which shows you " +"the exercises. On the last day, we will do a larger exercise that shows you " "how to work with dependencies and for that you need Cargo." msgstr "" -"āĻ•āĻžāĻ°ā§āĻ—ā§‹ āχāύāĻ¸ā§āϟāϞ āĻ•āϰ⧇ āύ⧇āĻ“ā§ŸāĻž āĻ­āĻžāϞ⧋: āĻāϟāĻŋ āφāĻĒāύāĻžāϰ āϜāĻ¨ā§āϝ āĻ…āύ⧁āĻļā§€āϞāύ⧀ āϏāĻšāϜ āĻ•āϰ⧇ āϤ⧁āϞāĻŦ⧇āĨ¤ āĻļ⧇āώ⧇āϰ āĻĻāĻŋāύ⧇ " -"āφāĻŽāϰāĻž āĻāĻ•āϟāĻŋ āĻ…āύ⧁āĻļā§€āϞāύ⧀ āĻ•āϰāĻŦ āϝāĻž āφāĻĒāύāĻžāϕ⧇ āĻĻ⧇āĻ–āĻžāĻŦ⧇ āĻ•āĻŋāĻ­āĻžāĻŦ⧇ āĻĄāĻŋāĻĒ⧇āĻ¨ā§āĻĄā§‡āĻ¨ā§āϏāĻŋāϰ āϏāĻžāĻĨ⧇ āĻ•āĻžāϜ āĻ•āϰāϤ⧇ āĻšāϝāĻŧ " -"āĻāĻŦāĻ‚ āĻāϰ āϜāĻ¨ā§āϝ āφāĻĒāύāĻžāϰ āĻ•āĻžāĻ°ā§āĻ—ā§‹ āĻĨāĻžāĻ•āĻž āĻĻāϰāĻ•āĻžāϰāĨ¤" #: src/cargo/code-samples.md msgid "The code blocks in this course are fully interactive:" -msgstr "āĻāχ āϕ⧋āĻ°ā§āϏ⧇āϰ āϕ⧋āĻĄ āĻŦā§āϞāĻ•āϗ⧁āϞāĻŋ āϏāĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āχāĻ¨ā§āϟāĻžāϰ⧇āĻ•ā§āϟāĻŋāĻ­:" +msgstr "" + +#: src/cargo/code-samples.md src/cargo/running-locally.md +#: src/pattern-matching/destructuring-structs.md +#: src/pattern-matching/destructuring-enums.md src/generics/trait-bounds.md +#: src/generics/impl-trait.md src/modules/filesystem.md +#: src/modules/visibility.md src/modules/paths.md src/testing/unit-tests.md +#: src/error-handling/panics.md src/error-handling/result.md +#: src/android/build-rules/binary.md src/android/build-rules/library.md +#: src/android/logging.md src/android/interoperability/with-c.md +#: src/android/interoperability/with-c/bindgen.md +#: src/android/interoperability/java.md src/concurrency/channels/unbounded.md +#: src/concurrency/channels/bounded.md +msgid "// Copyright 2022 Google LLC\n" +msgstr "" + +#: src/cargo/code-samples.md src/cargo/running-locally.md +#: src/types-and-values/hello-world.md src/types-and-values/variables.md +#: src/types-and-values/arithmetic.md src/types-and-values/inference.md +#: src/types-and-values/exercise.md src/types-and-values/solution.md +#: src/control-flow-basics/blocks-and-scopes.md src/control-flow-basics/if.md +#: src/control-flow-basics/match.md src/control-flow-basics/loops.md +#: src/control-flow-basics/loops/for.md src/control-flow-basics/loops/loop.md +#: src/control-flow-basics/break-continue.md +#: src/control-flow-basics/break-continue/labels.md +#: src/control-flow-basics/macros.md src/control-flow-basics/exercise.md +#: src/control-flow-basics/solution.md src/tuples-and-arrays/arrays.md +#: src/tuples-and-arrays/iteration.md src/tuples-and-arrays/destructuring.md +#: src/tuples-and-arrays/exercise.md src/tuples-and-arrays/solution.md +#: src/references/shared.md src/references/strings.md +#: src/references/dangling.md src/references/exercise.md +#: src/references/solution.md src/user-defined-types/named-structs.md +#: src/user-defined-types/tuple-structs.md src/user-defined-types/enums.md +#: src/user-defined-types/aliases.md src/user-defined-types/static.md +#: src/user-defined-types/exercise.md src/user-defined-types/solution.md +#: src/pattern-matching/infallible.md src/pattern-matching/match.md +#: src/pattern-matching/destructuring-structs.md +#: src/pattern-matching/destructuring-enums.md +#: src/pattern-matching/let-control-flow/if-let.md +#: src/pattern-matching/let-control-flow/while-let.md +#: src/pattern-matching/let-control-flow/let-else.md +#: src/pattern-matching/exercise.md src/pattern-matching/solution.md +#: src/methods-and-traits/methods.md src/methods-and-traits/traits.md +#: src/methods-and-traits/traits/implementing.md +#: src/methods-and-traits/traits/supertraits.md +#: src/methods-and-traits/traits/associated-types.md +#: src/methods-and-traits/deriving.md src/methods-and-traits/exercise.md +#: src/methods-and-traits/solution.md src/generics/generic-functions.md +#: src/generics/trait-bounds.md src/generics/generic-data.md +#: src/generics/generic-traits.md src/generics/impl-trait.md +#: src/generics/dyn-trait.md src/generics/exercise.md src/generics/solution.md +#: src/closures/syntax.md src/closures/capturing.md src/closures/traits.md +#: src/closures/exercise.md src/closures/solution.md src/std-types/docs.md +#: src/std-types/option.md src/std-types/result.md src/std-types/string.md +#: src/std-types/vec.md src/std-types/hashmap.md src/std-types/exercise.md +#: src/std-types/solution.md src/std-traits/comparisons.md +#: src/std-traits/operators.md src/std-traits/from-and-into.md +#: src/std-traits/casting.md src/std-traits/read-and-write.md +#: src/std-traits/default.md src/std-traits/exercise.md +#: src/std-traits/solution.md src/memory-management/review.md +#: src/memory-management/move.md src/memory-management/clone.md +#: src/memory-management/drop.md src/memory-management/exercise.md +#: src/memory-management/solution.md src/smart-pointers/box.md +#: src/smart-pointers/rc.md src/smart-pointers/trait-objects.md +#: src/smart-pointers/exercise.md src/smart-pointers/solution.md +#: src/borrowing/examples.md src/borrowing/interior-mutability/cell.md +#: src/borrowing/interior-mutability/refcell.md src/borrowing/exercise.md +#: src/borrowing/solution.md src/lifetimes/simple-borrows.md +#: src/lifetimes/returning-borrows.md src/lifetimes/multiple-borrows.md +#: src/lifetimes/borrow-both.md src/lifetimes/borrow-one.md +#: src/lifetimes/lifetime-elision.md src/lifetimes/struct-lifetimes.md +#: src/lifetimes/exercise.md src/lifetimes/solution.md +#: src/iterators/motivation.md src/iterators/iterator.md +#: src/iterators/helpers.md src/iterators/collect.md +#: src/iterators/intoiterator.md src/iterators/exercise.md +#: src/iterators/solution.md src/modules/modules.md src/modules/filesystem.md +#: src/modules/visibility.md src/modules/encapsulation.md src/modules/paths.md +#: src/modules/exercise.md src/modules/solution.md src/testing/unit-tests.md +#: src/testing/other.md src/testing/lints.md src/testing/exercise.md +#: src/testing/solution.md src/error-handling/panics.md +#: src/error-handling/result.md src/error-handling/try.md +#: src/error-handling/try-conversions.md src/error-handling/error.md +#: src/error-handling/thiserror.md src/error-handling/anyhow.md +#: src/error-handling/exercise.md src/error-handling/solution.md +#: src/unsafe-rust/dereferencing.md src/unsafe-rust/mutable-static.md +#: src/unsafe-rust/unions.md src/unsafe-rust/unsafe-functions/rust.md +#: src/unsafe-rust/unsafe-functions/extern-c.md +#: src/unsafe-rust/unsafe-functions/calling.md src/unsafe-rust/unsafe-traits.md +#: src/unsafe-rust/exercise.md src/unsafe-rust/solution.md +#: src/android/build-rules/binary.md src/android/build-rules/library.md +#: src/android/aidl/example-service/service-bindings.md +#: src/android/aidl/example-service/service.md +#: src/android/aidl/example-service/server.md +#: src/android/aidl/example-service/client.md +#: src/android/aidl/example-service/changing-definition.md +#: src/android/aidl/example-service/changing-implementation.md +#: src/android/aidl/types/objects.md src/android/aidl/types/parcelables.md +#: src/android/aidl/types/file-descriptor.md src/android/testing.md +#: src/android/testing/googletest.md src/android/testing/mocking.md +#: src/android/logging.md src/android/interoperability/with-c.md +#: src/android/interoperability/with-c/bindgen.md +#: src/android/interoperability/with-c/rust-library.md +#: src/android/interoperability/cpp/bridge.md +#: src/android/interoperability/cpp/rust-bridge.md +#: src/android/interoperability/cpp/generated-cpp.md +#: src/android/interoperability/cpp/cpp-bridge.md +#: src/android/interoperability/cpp/shared-types.md +#: src/android/interoperability/cpp/shared-enums.md +#: src/android/interoperability/cpp/rust-result.md +#: src/android/interoperability/cpp/cpp-exception.md +#: src/android/interoperability/java.md src/exercises/chromium/build-rules.md +#: src/chromium/testing.md src/chromium/testing/rust-gtest-interop.md +#: src/chromium/testing/chromium-import-macro.md +#: src/chromium/interoperability-with-cpp/example-bindings.md +#: src/chromium/interoperability-with-cpp/error-handling-qr.md +#: src/chromium/interoperability-with-cpp/error-handling-png.md +#: src/bare-metal/alloc.md src/bare-metal/microcontrollers/mmio.md +#: src/bare-metal/microcontrollers/pacs.md +#: src/bare-metal/microcontrollers/hals.md +#: src/bare-metal/microcontrollers/type-state.md +#: src/exercises/bare-metal/solutions-morning.md +#: src/bare-metal/aps/inline-assembly.md src/bare-metal/aps/mmio.md +#: src/bare-metal/aps/uart.md src/bare-metal/aps/uart/traits.md +#: src/bare-metal/aps/uart/using.md src/bare-metal/aps/better-uart/bitflags.md +#: src/bare-metal/aps/better-uart/driver.md +#: src/bare-metal/aps/safemmio/driver.md src/bare-metal/aps/safemmio/using.md +#: src/bare-metal/aps/logging.md src/bare-metal/aps/logging/using.md +#: src/bare-metal/aps/aarch64-rt.md +#: src/bare-metal/useful-crates/aarch64-paging.md +#: src/exercises/bare-metal/solutions-afternoon.md +#: src/concurrency/threads/plain.md src/concurrency/threads/scoped.md +#: src/concurrency/channels/senders-receivers.md +#: src/concurrency/channels/unbounded.md src/concurrency/channels/bounded.md +#: src/concurrency/shared-state/arc.md src/concurrency/shared-state/mutex.md +#: src/concurrency/shared-state/example.md +#: src/concurrency/sync-exercises/dining-philosophers.md +#: src/concurrency/sync-exercises/link-checker.md +#: src/concurrency/sync-exercises/solutions.md +#: src/concurrency/async/async-await.md src/concurrency/async/futures.md +#: src/concurrency/async/state-machine.md +#: src/concurrency/async/runtimes/tokio.md src/concurrency/async/tasks.md +#: src/concurrency/async-control-flow/channels.md +#: src/concurrency/async-control-flow/join.md +#: src/concurrency/async-control-flow/select.md +#: src/concurrency/async-pitfalls/blocking-executor.md +#: src/concurrency/async-pitfalls/pin.md +#: src/concurrency/async-pitfalls/async-traits.md +#: src/concurrency/async-pitfalls/cancellation.md +#: src/concurrency/async-exercises/dining-philosophers.md +#: src/concurrency/async-exercises/chat-app.md +#: src/concurrency/async-exercises/solutions.md +#: src/idiomatic/foundations-api-design/meaningful-doc-comments.md +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/who-are-you-writing-for.md +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/anatomy-of-a-doc-comment.md +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/name-drop-signpost.md +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-isnt-docs.md +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-why-not-how-where.md +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/exercise.md +#: src/idiomatic/foundations-api-design/predictable-api.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/new.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/get.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/push.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/is.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/mut.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-constructor.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-copy-setter.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-closure.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-word.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/try.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/from.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into_inner.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/by.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/unchecked.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/raw_parts.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/exercise.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/debug.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialeq-eq.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialord-ord.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/hash.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/clone.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/copy.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/serde.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/from-into.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/try-from-into.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/display.md +#: src/idiomatic/leveraging-the-type-system/newtype-pattern.md +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/semantic-confusion.md +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/parse-don-t-validate.md +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/is-it-encapsulated.md +#: src/idiomatic/leveraging-the-type-system/raii.md +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +#: src/idiomatic/leveraging-the-type-system/raii/mutex.md +#: src/idiomatic/leveraging-the-type-system/raii/drop_guards.md +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb_forget.md +#: src/idiomatic/leveraging-the-type-system/raii/forget_and_drop.md +#: src/idiomatic/leveraging-the-type-system/raii/scope_guard.md +#: src/idiomatic/leveraging-the-type-system/raii/drop_option.md +#: src/idiomatic/leveraging-the-type-system/extension-traits.md +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-foreign-types.md +#: src/idiomatic/leveraging-the-type-system/extension-traits/method-resolution-conflicts.md +#: src/idiomatic/leveraging-the-type-system/extension-traits/trait-method-conflicts.md +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +#: src/idiomatic/leveraging-the-type-system/extension-traits/should-i-define-an-extension-trait.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-example.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-advanced.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/root.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/struct.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/property.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/complete.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-01-types.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-02-types-implemented.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-04-borrowedfd.md +#: src/idiomatic/leveraging-the-type-system/token-types.md +#: src/idiomatic/leveraging-the-type-system/token-types/permission-tokens.md +#: src/idiomatic/leveraging-the-type-system/token-types/mutex-guard.md +#: src/idiomatic/leveraging-the-type-system/token-types/branded-01-motivation.md +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +#: src/idiomatic/leveraging-the-type-system/token-types/branded-03-impl.md +#: src/idiomatic/leveraging-the-type-system/token-types/branded-04-in-action.md +#: src/idiomatic/polymorphism.md src/idiomatic/polymorphism/refresher.md +#: src/idiomatic/polymorphism/refresher/traits.md +#: src/idiomatic/polymorphism/refresher/trait-bounds.md +#: src/idiomatic/polymorphism/refresher/deriving-traits.md +#: src/idiomatic/polymorphism/refresher/default-impls.md +#: src/idiomatic/polymorphism/refresher/supertraits.md +#: src/idiomatic/polymorphism/refresher/blanket-impls.md +#: src/idiomatic/polymorphism/refresher/conditional-methods.md +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +#: src/idiomatic/polymorphism/refresher/sized.md +#: src/idiomatic/polymorphism/refresher/monomorphization.md +#: src/idiomatic/polymorphism/from-oop-to-rust/why-no-inheritance.md +#: src/idiomatic/polymorphism/from-oop-to-rust/switch-perspective.md +#: src/idiomatic/polymorphism/from-oop-to-rust/supertraits.md +#: src/idiomatic/polymorphism/from-oop-to-rust/composition.md +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-trait.md +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-compatible.md +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-vs-generics.md +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/limits.md +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/heterogeneous.md +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/any-trait.md +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/pitfalls.md +#: src/idiomatic/polymorphism/from-oop-to-rust/sealed-traits.md +#: src/idiomatic/polymorphism/from-oop-to-rust/sealing-with-enums.md +#: src/idiomatic/polymorphism/from-oop-to-rust/sticking-with-traits.md +#: src/idiomatic/polymorphism/from-oop-to-rust/problem-solving.md +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-block.md +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-fn.md +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-impl.md +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-trait.md +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/sometimes-necessary.md +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/sometimes-useful.md +#: src/unsafe-deep-dive/introduction/may_overflow.md +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +#: src/unsafe-deep-dive/safety-preconditions/getter.md +#: src/unsafe-deep-dive/safety-preconditions/determining.md +#: src/unsafe-deep-dive/safety-preconditions/references.md +#: src/unsafe-deep-dive/safety-preconditions/ascii.md +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory.md +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/safe.md +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/encapsulated-unsafe.md +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/documented-safety-preconditions.md +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/crying-wolf.md +#: src/unsafe-deep-dive/initialization/maybeuninit.md +#: src/unsafe-deep-dive/initialization/maybeuninit/arrays.md +#: src/unsafe-deep-dive/initialization/maybeuninit/zeroed-method.md +#: src/unsafe-deep-dive/initialization/maybeuninit/write-vs-assignment.md +#: src/unsafe-deep-dive/initialization/how-to-initialize-memory.md +#: src/unsafe-deep-dive/initialization/partial-initialization.md +#: src/unsafe-deep-dive/pinning/what-a-move-is.md +#: src/unsafe-deep-dive/pinning/definition-of-pin.md +#: src/unsafe-deep-dive/pinning/phantompinned.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust-raw-pointers.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust-offset.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust-pin.md +#: src/unsafe-deep-dive/pinning/pin-and-drop.md +#: src/unsafe-deep-dive/pinning/drop-and-not-unpin-worked-example.md +#: src/unsafe-deep-dive/ffi/language-differences/representations.md +#: src/unsafe-deep-dive/ffi/language-differences/semantics.md +#: src/unsafe-deep-dive/ffi/abs.md src/unsafe-deep-dive/ffi/rand.md +#: src/unsafe-deep-dive/ffi/c-library-example.md +#: src/unsafe-deep-dive/ffi/cpp-library-example.md +msgid "// SPDX-License-Identifier: Apache-2.0\n" +msgstr "" #: src/cargo/code-samples.md src/cargo/running-locally.md msgid "\"Edit me!\"" -msgstr "\"āφāĻŽāĻžāϕ⧇ āĻŦāĻĻāϞ⧇ āĻĻ⧇āĻ–ā§‹ āϤ⧋ āĻĻ⧇āĻ–āĻŋ!\"" +msgstr "" #: src/cargo/code-samples.md -msgid "You can use " -msgstr "āϝāĻ–āύ āĻŸā§‡āĻ•ā§āϏāϟ āĻŦāĻ•ā§āϏ āĻ āĻĢā§‹āĻ•āĻžāϏ āĻĨāĻžāϕ⧇ āϤāĻ–āύ āϕ⧋āĻĄāϟāĻŋ āĻāĻ•ā§āϏāĻŋāĻ•āĻŋāωāϟ āĻ•āϰāϤ⧇ āφāĻĒāύāĻŋ " - -#: src/cargo/code-samples.md -msgid " to execute the code when focus is in the text box." -msgstr " āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤" +msgid "" +"You can use Ctrl + Enter to execute the code when " +"focus is in the text box." +msgstr "" #: src/cargo/code-samples.md msgid "" "Most code samples are editable like shown above. A few code samples are not " "editable for various reasons:" msgstr "" -"āĻŦ⧇āĻļāĻŋāϰāĻ­āĻžāĻ— āϕ⧋āĻĄ āύāĻŽā§āύāĻž āωāĻĒāϰ⧇ āĻĻ⧇āĻ–āĻžāύ⧋ āĻŽāϤ āϏāĻŽā§āĻĒāĻžāĻĻāύāĻžāϝ⧋āĻ—ā§āϝāĨ¤ āĻ•āϝāĻŧ⧇āĻ•āϟāĻŋ āϕ⧋āĻĄ āύāĻŽā§āύāĻž āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āύ āĻ•āĻžāϰāϪ⧇ " -"āϏāĻŽā§āĻĒāĻžāĻĻāύāĻžāϝ⧋āĻ—ā§āϝ āύāϝāĻŧ:" #: src/cargo/code-samples.md msgid "" "The embedded playgrounds cannot execute unit tests. Copy-paste the code and " "open it in the real Playground to demonstrate unit tests." msgstr "" -"āĻ…āύ⧁āĻŦāĻŋāĻĻā§āϧ āĻĒā§āϞ⧇āĻ—ā§āϰāĻžāωāĻ¨ā§āĻĄāϟāĻŋ āĻāĻ•āĻ• āĻĒāϰ⧀āĻ•ā§āώāĻž āϚāĻžāϞāĻžāϤ⧇ āĻĒāĻžāϰāĻŦ⧇ āύāĻžāĨ¤ āĻāĻ•āĻ• āĻĒāϰ⧀āĻ•ā§āώāĻžāϗ⧁āϞāĻŋ āĻĒā§āϰāĻĻāĻ°ā§āĻļāύ⧇āϰ āϜāĻ¨ā§āϝ " -"āϕ⧋āĻĄāϟāĻŋ āĻ•āĻĒāĻŋ-āĻĒ⧇āĻ¸ā§āϟ āĻ•āϰ⧁āύ āφāϏāϞ āĻĒā§āϞ⧇āĻ—ā§āϰāĻžāωāĻ¨ā§āĻĄā§‡āĨ¤" #: src/cargo/code-samples.md msgid "" @@ -2287,13 +3581,10 @@ msgid "" "the page! This is the reason that the students should solve the exercises " "using a local Rust installation or via the Playground." msgstr "" -"āĻ…āύ⧁āĻŦāĻŋāĻĻā§āϧ āĻĒā§āϞ⧇āĻ—ā§āϰāĻžāωāĻ¨ā§āĻĄāϗ⧁āϞāĻŋāϰ āĻ…āĻŦāĻ¸ā§āĻĨāĻž āĻ•ā§āώāĻŖāĻ¸ā§āĻĨāĻžā§Ÿā§€ - āĻ…āĻ¨ā§āϝ āĻ“ā§Ÿā§‡āĻŦāĻĒ⧇āϜ āĻ āϗ⧇āϞ⧇ āĻāϗ⧁āϞāĻŋ āφāĻŦāĻžāϰ āĻĒ⧁āϰ⧋āύ⧋ " -"āĻ…āĻŦāĻ¸ā§āĻĨāĻžā§Ÿ āĻĢāĻŋāϰ⧇ āϝāĻžāĻŦ⧇! āĻāχ āĻ•āĻžāϰāϪ⧇āχ āĻ›āĻžāĻ¤ā§āϰāĻĻ⧇āϰ āύāĻŋāĻœā§‡āϰ āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽā§‡ āϰāĻžāĻ¸ā§āϟ āχāύāĻ¸ā§āϟāϞ⧇āĻļāύ āĻ•āϰ⧇ āφāϏāϞ " -"āĻĒā§āϞ⧇āĻ—ā§āϰāĻžāωāĻ¨ā§āĻĄā§‡āϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ āĻ…āύ⧁āĻļā§€āϞāύāϗ⧁āϞāĻŋ āϏāĻŽāĻžāϧāĻžāύ āĻ•āϰāĻž āωāϚāĻŋāϤāĨ¤" #: src/cargo/running-locally.md msgid "Running Code Locally with Cargo" -msgstr "Cargo āĻāϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ āĻ¸ā§āĻĨāĻžāύ⧀āϝāĻŧāĻ­āĻžāĻŦ⧇ āϕ⧋āĻĄ āϚāĻžāϞāĻžāύ⧋" +msgstr "" #: src/cargo/running-locally.md msgid "" @@ -2303,57 +3594,42 @@ msgid "" "should give you a working `rustc` and `cargo`. At the time of writing, the " "latest stable Rust release has these version numbers:" msgstr "" -"āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āφāĻĒāύāĻžāϰ āύāĻŋāĻœā§‡āϰ āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽā§‡ āϕ⧋āĻĄāϟāĻŋ āĻĒāϰ⧀āĻ•ā§āώāĻž āĻ•āϰāϤ⧇ āϚāĻžāύ āϤāĻŦ⧇ āφāĻĒāύāĻžāϕ⧇ āĻĒā§āϰāĻĨāĻŽā§‡ āϰāĻžāĻ¸ā§āϟ " -"āχāύāĻ¸ā§āϟāϞ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇āĨ¤ [āϰāĻžāĻ¸ā§āϟ āĻŦāχāϝāĻŧ⧇āϰ āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻžāĻŦāϞ⧀](https://doc.rust-lang.org/book/" -"ch01-01-installation.html) āĻ…āύ⧁āϏāϰāĻŖ āĻ•āϰ⧇ āĻāϟāĻŋ āĻ•āϰ⧁āύāĨ¤ āĻāϰāχ āĻ­āĻžāĻŦ⧇ āφāĻĒāύāĻŋ āĻ•āĻžāĻœā§‡ āϞāĻžāĻ—āĻžāύ⧋āϰ āĻŽāϤāύ " -"`rustc` āĻāĻŦāĻ‚ `cargo` āĻĒā§‡ā§Ÿā§‡ āϝāĻžāĻŦ⧇āύāĨ¤ āĻāχ āĻŦāχāϟāĻŋ āϞāĻŋāĻ–āĻŦāĻžāϰ āϏāĻŽā§Ÿā§‡, āϏāĻ°ā§āĻŦāĻļ⧇āώ āĻ¸ā§āĻĨāĻŋāϤāĻŋāĻļā§€āϞ āϰāĻžāĻ¸ā§āĻŸā§‡āϰ " -"āĻŽā§āĻ•ā§āϤāĻŋāϰ āĻāχ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖ āϏāĻ‚āĻ–ā§āϝāĻž āϰāϝāĻŧ⧇āϛ⧇:" #: src/cargo/running-locally.md msgid "" "You can use any later version too since Rust maintains backwards " "compatibility." msgstr "" -"āφāĻĒāύāĻŋ āĻĒāϰāĻŦāĻ°ā§āϤ⧀ āϏāĻ‚āĻ¸ā§āĻ•āϰāĻŖāĻ“ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ āϝ⧇āĻšā§‡āϤ⧁ āϰāĻžāĻ¸ā§āϟ āϐāϤāĻŋāĻšāĻžāϏāĻŋāĻ• āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝ āĻŦāϜāĻžāϝāĻŧ āϰāĻžāϖ⧇āĨ¤" #: src/cargo/running-locally.md msgid "" "With this in place, follow these steps to build a Rust binary from one of " "the examples in this training:" msgstr "" -"āĻāϟāĻŋāϰ āϏāĻžāĻĨ⧇, āĻāχ āĻĒā§āϰāĻļāĻŋāĻ•ā§āώāϪ⧇āϰ āωāĻĻāĻžāĻšāϰāĻŖāϗ⧁āϞāĻŋāϰ āĻŽāĻ§ā§āϝ⧇ āĻāĻ•āϟāĻŋ āĻĨ⧇āϕ⧇ āĻāĻ•āϟāĻŋ āϰāĻžāĻ¸ā§āĻŸā§‡āϰ āĻŦāĻžāχāύāĻžāϰāĻŋ āϤ⧈āϰāĻŋ " -"āĻ•āϰāϤ⧇ āĻāχ āĻĒāĻĻāĻ•ā§āώ⧇āĻĒāϗ⧁āϞāĻŋ āĻ…āύ⧁āϏāϰāĻŖ āĻ•āϰ⧁āύ:" #: src/cargo/running-locally.md msgid "Click the \"Copy to clipboard\" button on the example you want to copy." msgstr "" -"āφāĻĒāύāĻŋ \"Copy to clipboard\" āĻŦāĻžāϟāύ āĻĻāĻžāĻŦāĻŋā§Ÿā§‡ āϝ⧇āχ āωāĻĻāĻžāĻšāϰāĻŖāϟāĻŋ āϚāĻžāύ āϏ⧇āϟāĻŋ āĻ•āĻĒāĻŋ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤" #: src/cargo/running-locally.md msgid "" "Use `cargo new exercise` to create a new `exercise/` directory for your code:" msgstr "" -"āφāĻĒāύāĻžāϰ āϕ⧋āĻĄā§‡āϰ āϜāĻ¨ā§āϝ āĻāĻ•āϟāĻŋ āύāϤ⧁āύ `exercise/` āĻĄāĻŋāϰ⧇āĻ•ā§āϟāϰāĻŋ āϤ⧈āϰāĻŋ āĻ•āϰāϤ⧇ ``cargo new " -"exercise` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧁āύ:" #: src/cargo/running-locally.md msgid "" "Navigate into `exercise/` and use `cargo run` to build and run your binary:" msgstr "" -"`exercise/` -āĻĄāĻŋāϰ⧇āĻ•ā§āϟāϰāĻŋāϤ⧇ āĻ—āĻŋā§Ÿā§‡ āφāĻĒāύāĻžāϰ āĻŦāĻžāχāύāĻžāϰāĻŋ āϤ⧈āϰāĻŋ āĻ•āϰāĻž āĻ“ āϏ⧇āϟāĻž āϚāĻžāϞāĻžāϤ⧇ `cargo " -"run` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧁āύ:" #: src/cargo/running-locally.md msgid "" -"Replace the boiler-plate code in `src/main.rs` with your own code. For " +"Replace the boilerplate code in `src/main.rs` with your own code. For " "example, using the example on the previous page, make `src/main.rs` look like" msgstr "" -"`src/main.rs`-āĻāϰ āĻĨ⧇āϕ⧇ āĻŦāϝāĻŧāϞāĻžāϰāĻĒā§āϞ⧇āϟ āϕ⧋āĻĄ āϏāϰāĻŋā§Ÿā§‡ āύāĻŋāĻœā§‡āϰ āϕ⧋āĻĄ āĻĻāĻŋā§Ÿā§‡ āĻĒā§āϰāϤāĻŋāĻ¸ā§āĻĨāĻžāĻĒāύ āĻ•āϰ⧁āύāĨ¤ āϝ⧇āĻŽāύ " -"āφāϗ⧇āϰ āĻĒ⧃āĻˇā§āĻ āĻžāϰ āωāĻĻāĻžāĻšāϰāĻŖ āĻ•āĻžāĻœā§‡ āϞāĻžāĻ—āĻŋā§Ÿā§‡ `src/main.rs`-āϟāĻŋāϕ⧇ āĻāĻŽāύāĻŋ āĻŦāĻžāύāĻŋā§Ÿā§‡ āĻĢ⧇āϞ⧁āύ" #: src/cargo/running-locally.md msgid "Use `cargo run` to build and run your updated binary:" -msgstr "`cargo run` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āύāĻŋāĻœā§‡āϰ āĻŦāĻŋāύāĻžāϰ⧀āϟāĻŋāϕ⧇ āĻŦāĻžāύāĻžāύ āĻāĻŦāĻ‚ āφāĻĒāĻĄā§‡āϟ āĻ•āϰ⧁āύ:" +msgstr "" #: src/cargo/running-locally.md msgid "" @@ -2362,10 +3638,6 @@ msgid "" "debug/` for a normal debug build. Use `cargo build --release` to produce an " "optimized release build in `target/release/`." msgstr "" -"āφāĻĒāύāĻžāϰ āĻĒā§āϰāĻœā§‡āĻ•ā§āϟāĻŋāϰ āĻĻā§āϰ⧁āϤ āĻĒāϰ⧀āĻ•ā§āώāĻž āĻ•āϰ⧇ āĻ¤ā§āϰ⧁āϟāĻŋāϰ āĻŦ⧇āϰ āĻ•āϰāĻŦāĻžāϰ āϜāĻ¨ā§āϝ `cargo check` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧁āύ, " -"āĻāϟāĻŋāϕ⧇ āύāĻž āϚāĻžāϞāĻŋāϝāĻŧ⧇ āĻ•āĻŽā§āĻĒāĻžāχāϞ āĻ•āϰāϤ⧇ `cargo build` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧁āύāĨ¤ āĻāĻ•āϟāĻŋ āϏāĻžāϧāĻžāϰāĻŖ āĻĄāĻŋāĻŦāĻžāĻ— " -"āĻŦāĻŋāĻ˛ā§āĻĄā§‡āϰ āϜāĻ¨ā§āϝ āφāĻĒāύāĻŋ āφāωāϟāĻĒ⧁āϟāĻŋ `target/debug/` āĻĄāĻŋāϰ⧇āĻ•ā§āϟāϰāĻŋāϤ⧇ āĻĒāĻžāĻŦ⧇āύāĨ¤ `target/release/`-āĻ " -"āĻāĻ•āϟāĻŋ āĻ…āĻĒā§āϟāĻŋāĻŽāĻžāχāϜāĻĄ āϰāĻŋāϞāĻŋāϜ āĻŦāĻŋāĻ˛ā§āĻĄ āϤ⧈āϰāĻŋ āĻ•āϰāϤ⧇ `cargo build --release` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧁āύāĨ¤" #: src/cargo/running-locally.md msgid "" @@ -2373,9 +3645,6 @@ msgid "" "run `cargo` commands, it will automatically download and compile missing " "dependencies for you." msgstr "" -"`Cargo.toml` āĻŦāĻĻāϞ⧇ āφāĻĒāύāĻŋ āύāĻŋāĻœā§‡āϰ āĻĒā§āϰāĻœā§‡āĻ•ā§āĻŸā§‡ āφāϰāĻ“ āύāϤ⧁āύ āĻĄāĻŋāĻĒ⧇āĻ¨ā§āĻĄā§‡āĻ¨ā§āϏāĻŋ āϝ⧋āĻ— āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤\n" -"āφāĻĒāύāĻŋ āϝāĻ–āύ `cargo` āĻ•āĻŽāĻžāĻ¨ā§āĻĄ āϚāĻžāϞāĻžāύ, āϤāĻ–āύ āĻāϟāĻŋ āύāĻŋāĻœā§‡-āύāĻŋāĻœā§‡āχ āφāĻĒāύāĻžāϰ āϜāĻ¨ā§āϝ āĻ…āύ⧁āĻĒāĻ¸ā§āĻĨāĻŋāϤ " -"āĻĄāĻŋāĻĒ⧇āĻ¨ā§āĻĄā§‡āĻ¨ā§āϏāĻŋāϗ⧁āϞāĻŋ āĻĄāĻžāωāύāϞ⧋āĻĄ āĻāĻŦāĻ‚ āĻ•āĻŽā§āĻĒāĻžāχāϞ āĻ•āϰāĻŦ⧇āĨ¤" #: src/cargo/running-locally.md msgid "" @@ -2383,114 +3652,75 @@ msgid "" "editor. It will make their life easier since they will have a normal " "development environment." msgstr "" -"āĻ•ā§āϞāĻžāϏ āĻ…āĻ‚āĻļāĻ—ā§āϰāĻšāĻŖāĻ•āĻžāϰ⧀āĻĻ⧇āϰ Cargo āχāύāĻ¸ā§āϟāϞ āĻ•āϰāϤ⧇ āĻāĻŦāĻ‚ āĻāĻ•āϟāĻŋ āϞ⧋āĻ•āĻžāϞ āĻāĻĄāĻŋāϟāϰ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ " -"āĻ‰ā§ŽāϏāĻžāĻšāĻŋāϤ āĻ•āϰāĻžāϰ āĻšā§‡āĻˇā§āϟāĻž āĻ•āϰ⧁āύāĨ¤ āĻāϟāĻŋ āϤāĻžāĻĻ⧇āϰ āĻœā§€āĻŦāύāϕ⧇ āϏāĻšāϜ āĻ•āϰ⧇ āϤ⧁āϞāĻŦ⧇ āϝ⧇āĻšā§‡āϤ⧁ āϤāĻžāĻĻ⧇āϰ āĻāĻ•āϟāĻŋ " -"āĻ¸ā§āĻŦāĻžāĻ­āĻžāĻŦāĻŋāĻ• āĻĄā§‡āϭ⧇āϞāĻĒāĻŽā§‡āĻ¨ā§āϟ āĻāύāĻ­āĻžāχāϰāύāĻŽā§‡āĻ¨ā§āϟ āĻĨāĻžāĻ•āĻŦ⧇āĨ¤" #: src/welcome-day-1.md msgid "Welcome to Day 1" -msgstr "āĻĒā§āϰāĻĨāĻŽ āĻĻāĻŋāύ⧇ āφāĻĒāύāĻžāϕ⧇ āĻ¸ā§āĻŦāĻžāĻ—āϤāĻŽ" +msgstr "" #: src/welcome-day-1.md msgid "" -"This is the first day of Rust Fundamentals. We will cover a lot of ground " -"today:" -msgstr "āϰāĻžāĻ¸ā§āĻŸā§‡āϰ āĻŽā§‚āϞāĻŦāĻŋāώ⧟ āϚāĻ°ā§āϚāĻžāϰ āĻāϟāĻŋ āĻĒā§āϰāĻĨāĻŽ āĻĻāĻŋāύāĨ¤ āφāĻŽāϰāĻž āφāϜāϕ⧇ āĻ…āύ⧇āĻ•āĻ•āĻŋāϛ⧁ āĻŦ⧁āĻāĻŦāĻžāϰ āĻšā§‡āĻˇā§āϟāĻž āĻ•āϰāĻŦā§‹āĨ¤" +"This is the first day of Rust Fundamentals. We will cover a broad range of " +"topics today:" +msgstr "" #: src/welcome-day-1.md msgid "" "Basic Rust syntax: variables, scalar and compound types, enums, structs, " "references, functions, and methods." msgstr "" -"āϰāĻžāϤ āĻāϰ āĻĒā§āϰāĻžāĻĨāĻŽāĻŋāĻ• āĻļāĻŦā§āĻĻāĻŦāĻŋāĻ¨ā§āϝāĻžāϏ: āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ, āĻ¸ā§āϕ⧇āϞāĻžāϰ āĻāĻŦāĻ‚ āϝ⧌āĻ—āĻŋāĻ• āĻĒā§āϰāĻ•āĻžāϰ, āχāύāĻžāĻŽ, āĻ¸ā§āĻŸā§āϰāĻžāĻ•ā§āϟ, " -"āϰ⧇āĻĢāĻžāϰ⧇āĻ¨ā§āϏ, āĻĢāĻžāĻ‚āĻļāύ, āĻāĻŦāĻ‚ āĻĒāĻĻā§āϧāϤāĻŋāĨ¤" #: src/welcome-day-1.md msgid "Types and type inference." -msgstr "āϟāĻžāχāĻĒ āĻāĻŦāĻ‚ āϟāĻžāχāĻĒ⧇āϰ āĻ…āύ⧁āĻŽāĻžāύ āĻ•āϰāĻž" +msgstr "" #: src/welcome-day-1.md msgid "Control flow constructs: loops, conditionals, and so on." -msgstr "āύāĻŋāϝāĻŧāĻ¨ā§āĻ¤ā§āϰāĻŖ āĻĒā§āϰāĻŦāĻžāĻš āĻ—āĻ āύ: āϞ⧁āĻĒ, āĻļāĻ°ā§āϤāϏāĻžāĻĒ⧇āĻ•ā§āώāĻ—āĻ āύ āĻāĻŦāĻ‚ āφāϰāĻ“ āĻ…āύ⧇āĻ• āĻ•āĻŋāϛ⧁āĨ¤" +msgstr "" #: src/welcome-day-1.md msgid "User-defined types: structs and enums." -msgstr "āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀-āϏāĻ‚āĻœā§āĻžāĻžāϝāĻŧāĻŋāϤ āϟāĻžāχāĻĒ: āĻˇā§āĻŸā§āϰāĻžāĻ•ā§āϟ āĻ“ āχāύāĻžāĻŽ" - -#: src/welcome-day-1.md -msgid "Pattern matching: destructuring enums, structs, and arrays." -msgstr "āĻĒā§āϝāĻžāϟāĻžāĻ°ā§āύ āĻŽā§āϝāĻžāϚāĻŋāĻ‚: āχāύāĻžāĻŽ, āĻˇā§āĻŸā§āϰāĻžāĻ•ā§āϟ āĻāĻŦāĻ‚ āĻ…ā§āϝāĻžāϰ⧇ āĻĄāĻŋāĻ¸ā§āĻŸā§āϰāĻžāĻ•ā§āϟāϚāĻžāϰ āĻ•āϰāĻžāĨ¤" +msgstr "" #: src/welcome-day-1.md src/welcome-day-2.md src/welcome-day-3.md -#: src/welcome-day-4.md +#: src/welcome-day-4.md src/concurrency/welcome.md +#: src/concurrency/welcome-async.md src/idiomatic/welcome.md msgid "Schedule" -msgstr "āϏāĻŽāϝāĻŧāϏ⧂āĻšā§€" - -#: src/welcome-day-1.md src/welcome-day-1-afternoon.md src/welcome-day-2.md -#: src/welcome-day-2-afternoon.md src/welcome-day-3.md -#: src/welcome-day-3-afternoon.md src/welcome-day-4.md -#: src/welcome-day-4-afternoon.md -msgid "In this session:" -msgstr "āĻāχ āĻ…āϧāĻŋāĻŦ⧇āĻļāύ⧇:" +msgstr "" #: src/welcome-day-1.md -msgid "[Welcome](./welcome-day-1.md) (5 minutes)" -msgstr "[āĻ¸ā§āĻŦāĻžāĻ—āϤāĻŽ](./welcome-day-1.md) (ā§Ģ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/welcome-day-1.md -msgid "[Hello, World](./hello-world.md) (15 minutes)" -msgstr "[āĻšā§āϝāĻžāϞ⧋,āĻ“ā§ŸāĻžāĻ°ā§āĻ˛ā§āĻĄ](./hello-world.md) (ā§§ā§Ģ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/welcome-day-1.md -msgid "[Types and Values](./types-and-values.md) (45 minutes)" -msgstr "[āϟāĻžāχāĻĒ āĻāĻŦāĻ‚ āϤāĻžāĻĻ⧇āϰ āĻŽāĻžāύ](./types-and-values.md) (ā§Ēā§Ģ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/welcome-day-1.md -msgid "[Control Flow Basics](./control-flow-basics.md) (40 minutes)" -msgstr "[āϏāĻŽā§āĻĒāĻžāĻĻāύ āĻĒā§āϰāĻŦāĻžāĻš āύāĻŋāϝāĻŧāĻ¨ā§āĻ¤ā§āϰāĻŖ āĻāϰ āĻŽā§āϞāĻœā§āĻžāĻžāύ](./control-flow-basics.md) (ā§Ēā§Ļ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/welcome-day-1.md src/welcome-day-3-afternoon.md -#: src/welcome-day-4-afternoon.md msgid "" "Including 10 minute breaks, this session should take about 2 hours and 10 " -"minutes" -msgstr "ā§§ā§Ļ āĻŽāĻŋāύāĻŋāϟ āĻŦāĻŋāϰāϤāĻŋāϏāĻš āĻāχ āĻ…āϧāĻŋāĻŦ⧇āĻļāύāϟāĻŋ ⧍ āϘāĻ¨ā§āϟāĻž ā§§ā§Ļ āĻŽāĻŋāύāĻŋāĻŸā§‡āϰ" +"minutes. It contains:" +msgstr "" #: src/welcome-day-1.md msgid "Please remind the students that:" -msgstr "āĻļāĻŋāĻ•ā§āώāĻžāĻ°ā§āĻĨā§€āĻĻ⧇āϰ āĻāϟāĻŋ āĻŽāύ⧇ āĻ•āϰāĻŋāϝāĻŧ⧇ āĻĻāĻŋāύ āϝ⧇āσ" +msgstr "" #: src/welcome-day-1.md msgid "" "They should ask questions when they get them, don't save them to the end." msgstr "" -"āϤāĻžāĻĻ⧇āϰ āĻĒā§āϰāĻļā§āύ āϜāĻŋāĻœā§āĻžāĻžāϏāĻž āĻ•āϰāĻž āωāϚāĻŋāϤ āϝāĻ–āύ āϤāĻžāϰāĻž āϏ⧇āϗ⧁āϞāĻŋ āĻĒāĻžāĻŦ⧇, āĻļ⧇āώ āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āĻŦāĻžāρāϚāĻŋā§Ÿā§‡ āϰ⧇āϖ⧇ āϞāĻžāĻ­ " -"āύ⧇āχāĨ¤" #: src/welcome-day-1.md msgid "" "The class is meant to be interactive and discussions are very much " "encouraged!" msgstr "" -"āĻāχ āĻ•ā§āϞāĻžāϏāϟāĻŋ āĻŽāĻŋāĻĨāĻˇā§āĻ•ā§āϰāĻŋ⧟ āĻšāĻ“ā§ŸāĻž āĻĻāϰāĻ•āĻžāϰ āĻāĻŦāĻ‚ āϤāĻžāϰ āϜāĻ¨ā§āϝ⧇ āĻŦāĻŋāώāϝāĻŧ āϏāĻŽā§āĻĒāĻ°ā§āĻ•āĻŋāϤ āϤāĻ°ā§āĻ•-āĻŦāĻŋāϤāĻ°ā§āĻ• āĻ•āϰāϤ⧇ āωāĻ¤ā§āϏāĻžāĻš " -"āĻĻ⧇āĻ“āϝāĻŧāĻž āωāϚāĻŋāϤāĨ¤" #: src/welcome-day-1.md msgid "" "As an instructor, you should try to keep the discussions relevant, i.e., " -"keep the discussions related to how Rust does things vs some other language. " -"It can be hard to find the right balance, but err on the side of allowing " -"discussions since they engage people much more than one-way communication." +"keep the discussions related to how Rust does things vs. some other " +"language. It can be hard to find the right balance, but err on the side of " +"allowing discussions since they engage people much more than one-way " +"communication." msgstr "" -"āĻāĻ•āϜāύ āĻĒā§āϰāĻļāĻŋāĻ•ā§āώāĻ• āĻšāĻŋāϏāĻžāĻŦ⧇, āφāĻĒāύāĻžāϰ āφāϞ⧋āϚāύāĻžāϗ⧁āϞāĻŋāϕ⧇ āĻĒā§āϰāĻžāϏāĻ™ā§āĻ—āĻŋāĻ• āϰāĻžāĻ–āĻžāϰ āĻšā§‡āĻˇā§āϟāĻž āĻ•āϰāĻž āωāϚāĻŋāϤ, āĻ…āĻ°ā§āĻĨāĻžā§Ž, " -"āĻ…āĻ¨ā§āϝ āϕ⧋āύ āĻ­āĻžāώāĻž āĻŦāύāĻžāĻŽ āϰāĻžāĻ¸ā§āϟ āϕ⧀āĻ­āĻžāĻŦ⧇ āϜāĻŋāύāĻŋāϏāϗ⧁āϞāĻŋ āĻ•āϰ⧇ āϤāĻžāϰ āϏāĻžāĻĨ⧇ āϏāĻŽā§āĻĒāĻ°ā§āĻ•āĻŋāϤ āφāϞ⧋āϚāύāĻžāϗ⧁āϞāĻŋ āϰāĻžāϖ⧁āύāĨ¤ " -"āϏāĻ āĻŋāĻ• āĻ­āĻžāϰāϏāĻžāĻŽā§āϝ āϖ⧁āρāĻœā§‡ āĻĒāĻžāĻ“āϝāĻŧāĻž āĻ•āĻ āĻŋāύ āĻšāϤ⧇ āĻĒāĻžāϰ⧇, āϤāĻŦ⧇ āφāϞ⧋āϚāύāĻžāϰ āĻ…āύ⧁āĻŽāϤāĻŋ āĻĻ⧇āĻ“āϝāĻŧāĻžāϰ āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇ āϭ⧁āϞ āĻšāϤ⧇ " -"āĻĒāĻžāϰ⧇ āĻ•āĻžāϰāĻŖ āϤāĻžāϰāĻž āĻāĻ•āĻŽā§āĻ–ā§€ āϝ⧋āĻ—āĻžāϝ⧋āϗ⧇āϰ āĻšā§‡āϝāĻŧ⧇ āĻ…āύ⧇āĻ• āĻŦ⧇āĻļāĻŋ āϞ⧋āĻ•āϕ⧇ āϜāĻĄāĻŧāĻŋāϤ āĻ•āϰ⧇āĨ¤" #: src/welcome-day-1.md msgid "" "The questions will likely mean that we talk about things ahead of the slides." -msgstr "āϝāĻĻāĻŋ āϕ⧋āύ⧋ āĻĒā§āϰāĻļā§āύ āφāϏ⧇ āϤāĻžāĻšāϞ⧇ āϏ⧇āϟāĻž āϏāĻŽā§āĻ­āĻŦāϤ āϏāĻžāĻŽāύ⧇āϰ āĻ¸ā§āϞāĻžāχāĻĄ āĻāϰ āĻŦāĻŋāώ⧟āϗ⧁āϞāĻŋ āύāĻŋā§Ÿā§‡āχ āφāϏāĻŦ⧇āĨ¤" +msgstr "" #: src/welcome-day-1.md msgid "" @@ -2498,8 +3728,6 @@ msgid "" "Remember that the slides are just a support and you are free to skip them as " "you like." msgstr "" -"āĻāϟāĻž āϭ⧁āϞ āĻŦā§āϝāĻžāĻĒāĻžāϰ āύ⧟! āĻĒ⧁āύāϰāĻžāĻŦ⧃āĻ¤ā§āϤāĻŋ āĻļ⧇āĻ–āĻžāϰ āĻāĻ•āϟāĻŋ āϗ⧁āϰ⧁āĻ¤ā§āĻŦāĻĒā§‚āĻ°ā§āĻŖ āĻ…āĻ‚āĻļāĨ¤ āĻŽāύ⧇ āϰāĻžāĻ–āĻŦ⧇āύ āϝ⧇ āĻ¸ā§āϞāĻžāχāĻĄāϗ⧁āϞāĻŋ " -"āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āĻāĻ•āϟāĻŋ āϏāĻŽāĻ°ā§āĻĨāύ āĻāĻŦāĻ‚ āφāĻĒāύāĻŋ āφāĻĒāύāĻžāϰ āĻĒāĻ›āĻ¨ā§āĻĻ āĻŽāϤ⧋ āϏ⧇āϗ⧁āϞāĻŋ āĻāĻĄāĻŧāĻŋāϝāĻŧ⧇ āϝ⧇āϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤" #: src/welcome-day-1.md msgid "" @@ -2507,8 +3735,6 @@ msgid "" "should have immediate parallels in other languages. The more advanced parts " "of Rust come on the subsequent days." msgstr "" -"āĻĒā§āϰāĻĨāĻŽ āĻĻāĻŋāύ⧇āϰ āϧāĻžāϰāĻŖāĻžāϟāĻŋ āĻšāϞ āϰāĻžāĻ¸ā§āĻŸā§‡āϰ \"āĻŽā§ŒāϞāĻŋāĻ•\" āϜāĻŋāύāĻŋāϏāϗ⧁āϞāĻŋ āĻĻ⧇āĻ–āĻžāύ⧋ āϝāĻž āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āĻ­āĻžāώāĻžāϝāĻŧ " -"āĻ…āĻŦāĻŋāϞāĻŽā§āĻŦ⧇ āϏāĻŽāĻžāĻ¨ā§āϤāϰāĻžāϞ āĻšāĻ“āϝāĻŧāĻž āωāϚāĻŋāϤāĨ¤ āϰāĻžāĻ¸ā§āĻŸā§‡āϰ āφāϰ⧋ āωāĻ¨ā§āύāϤ āĻ…āĻ‚āĻļ āĻĒāϰāĻŦāĻ°ā§āϤ⧀ āĻĻāĻŋāύ⧇ āφāϞ⧋āϚāύāĻž āĻ•āϰāĻž āĻšāĻŦ⧇āĨ¤" #: src/welcome-day-1.md msgid "" @@ -2518,230 +3744,223 @@ msgid "" "The times listed here are a suggestion in order to keep the course on " "schedule. Feel free to be flexible and adjust as necessary!" msgstr "" -"āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āĻāϟāĻŋ āĻāĻ•āϟāĻŋ āĻļā§āϰ⧇āĻŖā§€āĻ•āĻ•ā§āώ⧇ āĻļ⧇āĻ–āĻžāύ āϤāĻžāĻšāϞ⧇ āĻāϟāĻŋ āϏāĻŽāϝāĻŧāϏ⧂āĻšā§€āϤ⧇ āϝāĻžāĻ“āϝāĻŧāĻžāϰ āϜāĻ¨ā§āϝ āĻāĻ•āϟāĻŋ āĻ­āĻžāϞ " -"āϜāĻžāϝāĻŧāĻ—āĻžāĨ¤ āĻŽāύ⧇ āϰāĻžāĻ–āĻŦ⧇āύ āϝ⧇ āĻĒā§āϰāϤāĻŋāϟāĻŋ āϏ⧇āĻ—āĻŽā§‡āĻ¨ā§āĻŸā§‡āϰ āĻļ⧇āώ⧇ āĻāĻ•āϟāĻŋ āĻ…āύ⧁āĻļā§€āϞāύ āϰāϝāĻŧ⧇āϛ⧇, āϤāĻžāϰāĻĒāϰ⧇ āĻāĻ•āϟāĻŋ " -"āĻŦāĻŋāϰāϤāĻŋāĻ“ āϰāϝāĻŧ⧇āϛ⧇āĨ¤ āĻŦāĻŋāϰāϤāĻŋāϰ āĻĒāϰ⧇ āĻ…āύ⧁āĻļā§€āϞāύ⧀āϰ āϏāĻŽāĻžāϧāĻžāύāϚāĻ°ā§āϚāĻž āĻ•āϰāĻž āĻ­āĻžāϞ⧋āĨ¤ āϕ⧋āĻ°ā§āϏāϟāĻŋ āϏāĻŽāϝāĻŧāϏ⧂āĻšā§€āϤ⧇ āϰāĻžāĻ–āĻžāϰ " -"āϜāĻ¨ā§āϝ āĻāĻ–āĻžāύ⧇ āϤāĻžāϞāĻŋāĻ•āĻžāϭ⧁āĻ•ā§āϤ āϏāĻŽāϝāĻŧāϗ⧁āϞāĻŋ āĻĒāϰāĻžāĻŽāĻ°ā§āĻļ āĻšāĻŋāϏāĻžāĻŦ⧇ āĻĻ⧇āĻ“ā§ŸāĻž āĻšā§Ÿā§‡āϛ⧇āĨ¤ āĻŦāĻŋāύāĻž āĻĻā§āĻŦāĻŋāϧāĻžāϝāĻŧ āĻāĻŦāĻ‚ " -"āĻĒā§āϰāϝāĻŧā§‹āϜāύ⧀āϝāĻŧ āĻšāĻŋāϏāĻžāĻŦ⧇ āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝ āĻ•āϰ⧁āύ āĻ­āĻžāϞ⧋ āĻ•āϰ⧇ āĻĒā§‹ā§œāĻžāύ⧋āϰ āϜāĻ¨ā§āϝ⧇!" + +#: src/hello-world.md src/concurrency/send-sync.md +msgid "This segment should take about 15 minutes. It contains:" +msgstr "" #: src/hello-world.md src/types-and-values.md src/control-flow-basics.md #: src/tuples-and-arrays.md src/references.md src/user-defined-types.md #: src/pattern-matching.md src/methods-and-traits.md src/generics.md -#: src/std-types.md src/std-traits.md src/memory-management.md -#: src/smart-pointers.md src/borrowing.md src/slices-and-lifetimes.md -#: src/iterators.md src/modules.md src/testing.md src/error-handling.md -#: src/unsafe-rust.md -msgid "In this segment:" -msgstr "āĻāχ āĻ…āĻ‚āĻļ⧇:" +#: src/closures.md src/std-types.md src/std-traits.md src/memory-management.md +#: src/smart-pointers.md src/borrowing.md src/lifetimes.md src/iterators.md +#: src/modules.md src/testing.md src/error-handling.md src/unsafe-rust.md +#: src/concurrency/threads.md src/concurrency/channels.md +#: src/concurrency/send-sync.md src/concurrency/shared-state.md +#: src/concurrency/sync-exercises.md src/concurrency/async.md +#: src/concurrency/async-control-flow.md src/concurrency/async-pitfalls.md +#: src/concurrency/async-exercises.md src/idiomatic/foundations-api-design.md +#: src/idiomatic/leveraging-the-type-system.md +#: src/unsafe-deep-dive/introduction.md src/unsafe-deep-dive/pinning.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer.md +msgid "Slide" +msgstr "" -#: src/hello-world.md -msgid "[What is Rust?](./hello-world/what-is-rust.md) (10 minutes)" -msgstr "[āϰāĻžāĻ¸ā§āϟ āĻ•āĻŋ?](./hello-world/what-is-rust.md) (ā§§ā§Ļ āĻŽāĻŋāύāĻŋāϟ)" +#: src/hello-world.md src/references.md src/user-defined-types.md +#: src/pattern-matching.md src/methods-and-traits.md src/generics.md +#: src/closures.md src/std-types.md src/memory-management.md +#: src/smart-pointers.md src/borrowing.md src/modules.md src/unsafe-rust.md +#: src/concurrency/channels.md src/concurrency/send-sync.md +#: src/concurrency/shared-state.md src/concurrency/async.md +#: src/concurrency/async-control-flow.md src/concurrency/async-pitfalls.md +#: src/unsafe-deep-dive/introduction.md +msgid "10 minutes" +msgstr "" -#: src/hello-world.md -msgid "[Benefits of Rust](./hello-world/benefits.md) (3 minutes)" -msgstr "[āϰāĻžāĻ¸ā§āĻŸā§‡āϰ āϏ⧁āĻŦāĻŋāϧ⧇](./hello-world/benefits.md) (ā§Š āĻŽāĻŋāύāĻŋāϟ)" - -#: src/hello-world.md -msgid "[Playground](./hello-world/playground.md) (2 minutes)" -msgstr "[āĻĒā§āϞ⧇āĻ—ā§āϰāĻžāωāĻ¨ā§āĻĄ](./hello-world/playground.md) (⧍ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/hello-world.md -msgid "This segment should take about 15 minutes" -msgstr "āĻāχ āĻ…āĻ‚āĻļāϟāĻŋ āĻļ⧇āώ āĻ•āϰāϤ⧇ āĻĒā§āϰāĻžā§Ÿ ā§§ā§Ģ āĻŽāĻŋāύāĻŋāϟ āϞāĻžāĻ—āĻŦ⧇" +#: src/hello-world.md src/control-flow-basics.md src/user-defined-types.md +#: src/memory-management.md src/concurrency/channels.md +#: src/concurrency/send-sync.md src/idiomatic/foundations-api-design.md +msgid "2 minutes" +msgstr "" #: src/hello-world/what-is-rust.md msgid "" -"Rust is a new programming language which had its [1.0 release in 2015]" +"Rust is a new programming language that had its [1.0 release in 2015]" "(https://blog.rust-lang.org/2015/05/15/Rust-1.0.html):" msgstr "" -"Rust āĻāĻ•āϟāĻŋ āύāϤ⧁āύ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāĻŋāĻ‚ āĻ­āĻžāώāĻž āϝ⧇āϟāĻžāϰ āĻ›āĻŋāϞ⧋ [1.0 āĻĒā§āϰāĻ•āĻžāĻļ 2015 āϤ⧇](https://blog." -"rust-lang.org/2015/05/15/Rust-1.0.html):" #: src/hello-world/what-is-rust.md msgid "Rust is a statically compiled language in a similar role as C++" -msgstr " āϏāĻŋ++ āĻāϰ āĻŽāϤāύ, āϰāĻžāĻ¸ā§āϟāĻ“ 'āĻāĻ•āϟāĻŋ āĻ¸ā§āĻĨāĻŋāϤāĻŋāĻļā§€āϞāĻ­āĻžāĻŦ⧇ āϏāĻ‚āĻ•āϞāĻŋāϤ āĻ­āĻžāώāĻž" +msgstr "" #: src/hello-world/what-is-rust.md msgid "`rustc` uses LLVM as its backend." -msgstr "`rustc` āĻāϞ.āĻāϞ.āĻ­āĻŋ.āĻāĻŽ āύ⧇āĻĒāĻĨā§āϝ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇" +msgstr "" #: src/hello-world/what-is-rust.md msgid "" "Rust supports many [platforms and architectures](https://doc.rust-lang.org/" "nightly/rustc/platform-support.html):" msgstr "" -"āϰāĻžāĻ¸ā§āϟ āĻ…āύ⧇āĻ•āϗ⧁āϞāĻŋ [āĻĒā§āĻ˛ā§āϝāĻžāϟāĻĢāĻ°ā§āĻŽ āĻāĻŦāĻ‚ āφāĻ°ā§āĻ•āĻŋāĻŸā§‡āĻ•āϚāĻžāϰ](https://doc.rust-lang.org/nightly/" -"rustc/platform-support.html) āϏāĻŽāĻ°ā§āĻĨāύ āĻ•āϰ⧇ āϝ⧇āĻŽāύ:" #: src/hello-world/what-is-rust.md msgid "x86, ARM, WebAssembly, ..." -msgstr "x86, ARM, WebAssembly, ..." +msgstr "" #: src/hello-world/what-is-rust.md msgid "Linux, Mac, Windows, ..." -msgstr "Linux, Mac, Windows, ..." +msgstr "" #: src/hello-world/what-is-rust.md msgid "Rust is used for a wide range of devices:" -msgstr "āϰāĻžāĻ¸ā§āϟ āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āύ āĻĄāĻŋāĻ­āĻžāχāϏ⧇āϰ āϜāĻ¨ā§āϝ āĻŦā§āϝāĻŦāĻšā§ƒāϤ āĻšāϝāĻŧ:" +msgstr "" #: src/hello-world/what-is-rust.md msgid "firmware and boot loaders," -msgstr "āĻĢāĻžāĻ°ā§āĻŽāĻ“ā§Ÿā§āϝāĻžāϰ āĻāĻŦāĻ‚ āĻŦ⧁āϟ āĻ˛ā§‹ā§ŸāĻžāĻĄāĻ°ā§āϏ," +msgstr "" #: src/hello-world/what-is-rust.md msgid "smart displays," -msgstr "āĻ¸ā§āĻŽāĻžāĻ°ā§āϟ āĻĄāĻŋāϏāĻĒā§āϞ⧇," +msgstr "" #: src/hello-world/what-is-rust.md msgid "mobile phones," -msgstr "āĻŽā§‹āĻŦāĻžāχāϞ āĻĢā§‹āύ," +msgstr "" #: src/hello-world/what-is-rust.md msgid "desktops," -msgstr "āĻĄā§‡āĻ¸ā§āĻ•āϟāĻĒ," +msgstr "" #: src/hello-world/what-is-rust.md msgid "servers." -msgstr "āϏāĻžāĻ°ā§āĻ­āĻžāϰāĨ¤" +msgstr "" #: src/hello-world/what-is-rust.md msgid "Rust fits in the same area as C++:" -msgstr "Rust āĻ āĻŋāĻ• C++ āĻāϰ āĻŽāϤ⧋ āϏāĻŦāϜāĻžāϝāĻŧāĻ—āĻžāϝāĻŧ āĻ–āĻžāĻĒ āĻ–āĻžāϝāĻŧ:" +msgstr "" #: src/hello-world/what-is-rust.md msgid "High flexibility." -msgstr "āωāĻšā§āϚāĻ¸ā§āϤāϰ⧇āϰ āύāĻŽāύ⧀āϝāĻŧāϤāĻžāĨ¤" +msgstr "" #: src/hello-world/what-is-rust.md msgid "High level of control." -msgstr "āύāĻŋāϝāĻŧāĻ¨ā§āĻ¤ā§āϰāϪ⧇āϰ āωāĻšā§āϚ āĻ¸ā§āϤāϰāĨ¤" +msgstr "" #: src/hello-world/what-is-rust.md msgid "" "Can be scaled down to very constrained devices such as microcontrollers." -msgstr "āĻŽāĻžāχāĻ•ā§āϰ⧋āĻ•āĻ¨ā§āĻŸā§āϰ⧋āϞāĻžāϰ⧇āϰ āĻŽāϤ⧋ āϖ⧁āĻŦ āϏ⧀āĻŽāĻžāĻŦāĻĻā§āϧ āĻĄāĻŋāĻ­āĻžāχāϏ⧇ āϛ⧋āϟ āĻ•āϰ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āϝ⧇āϤ⧇ āĻĒāĻžāϰ⧇āĨ¤" +msgstr "" #: src/hello-world/what-is-rust.md msgid "Has no runtime or garbage collection." -msgstr "āϕ⧋āύ āϰāĻžāύāϟāĻžāχāĻŽ āĻŦāĻž āφāĻŦāĻ°ā§āϜāύāĻž āϏāĻ‚āĻ—ā§āϰāĻšāĻĒā§āϰāĻŖāĻžāϞ⧀ āύ⧇āχāĨ¤" +msgstr "" #: src/hello-world/what-is-rust.md msgid "Focuses on reliability and safety without sacrificing performance." msgstr "" -"āĻ•āĻ°ā§āĻŽāĻ•ā§āώāĻŽāϤāĻžā§Ÿā§‡ āϕ⧋āύ⧋āϰāĻ•āĻŽ āĻŦāϞāĻŋāĻĻāĻžāύ āύāĻž āĻĻāĻŋā§Ÿā§‡ āύāĻŋāĻ°ā§āĻ­āϰāϝ⧋āĻ—ā§āϝāϤāĻž āĻāĻŦāĻ‚ āύāĻŋāϰāĻžāĻĒāĻ¤ā§āϤāĻž āωāĻĒāϰ āĻĢā§‹āĻ•āĻžāϏ āĻ•āϰ⧇āĨ¤" #: src/hello-world/benefits.md msgid "Some unique selling points of Rust:" -msgstr "RustāĻāϰ āĻ•āĻŋāϛ⧁ āĻ…āύāĻ¨ā§āϝ āĻŦāĻŋāĻ•ā§āϰāϝāĻŧ āĻĒāϝāĻŧ⧇āĻ¨ā§āϟ:" +msgstr "" #: src/hello-world/benefits.md msgid "" "_Compile time memory safety_ - whole classes of memory bugs are prevented at " "compile time" msgstr "" -"_āϏāĻ‚āĻ•āϞāύ āϏāĻŽāϝāĻŧ āĻŽā§‡āĻŽāϰāĻŋ āύāĻŋāϰāĻžāĻĒāĻ¤ā§āϤāĻž_ - āĻ•āĻŽā§āĻĒāĻžāχāϞ⧇āϰ āϏāĻŽāϝāĻŧ āĻŽā§‡āĻŽāϰāĻŋ āĻŦāĻžāĻ—āϗ⧁āϞāĻŋāϰ āϏāĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻ­āĻžāĻŦ⧇ āĻĒā§āϰāϤāĻŋāϰ⧋āϧ " -"āĻ•āϰāĻž āĻšāϝāĻŧ" #: src/hello-world/benefits.md msgid "No uninitialized variables." -msgstr "āϕ⧋āύ⧋ āϏ⧂āϚāύāĻžāĻ•ā§ƒāϤ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ āĻĨāĻžāϕ⧇ āύāĻžāĨ¤" +msgstr "" #: src/hello-world/benefits.md msgid "No double-frees." -msgstr "āϕ⧋āύ⧋ āϰāĻ•āĻŽ āĻĄāĻžāĻŦāϞ-āĻĢā§āϰ⧇āϏ āĻšā§Ÿā§‡ āύāĻžāĨ¤" +msgstr "" #: src/hello-world/benefits.md msgid "No use-after-free." -msgstr "āĻŽā§āĻ•ā§āϤāĻŋāϰ āĻĒāϰ⧇ āϕ⧋āύ⧋ āϰāĻ•āĻŽ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻŦāĻžāϰ āϜāĻžā§ŸāĻ—āĻž āύ⧇āχāĨ¤" +msgstr "" #: src/hello-world/benefits.md msgid "No `NULL` pointers." -msgstr "āϕ⧋āύ⧋ `NULL` āĻĒā§Ÿā§‡āĻ¨ā§āϟāĻžāϰ āύ⧇āχāĨ¤" +msgstr "" #: src/hello-world/benefits.md msgid "No forgotten locked mutexes." -msgstr "āϭ⧁āϞ āĻ•āϰ⧇ āϭ⧁āϞ⧇āϝāĻžāĻ“ āϕ⧋āύ⧋ āϞāĻ• āĻ•āϰāĻž āĻŽāĻŋāωāĻŸā§‡āĻ•ā§āϏ āĻĨāĻžāϕ⧇ āϏāĻŽā§āĻ­āĻžāĻŦāύāĻž āύ⧇āχāĨ¤" +msgstr "" #: src/hello-world/benefits.md msgid "No data races between threads." -msgstr "āĻĨā§āϰ⧇āĻĄā§‡āϰ āĻŽāĻžāĻā§‡ āϕ⧋āύ⧋ āϰāĻ•āĻŽā§‡āϰ āĻĄāĻžāϟāĻž āύāĻŋā§Ÿā§‡āχ āϰ⧇āϏ āĻĒāϰāĻŋāĻ¸ā§āĻĨāĻŋāϤāĻŋ āύ⧇āχāĨ¤" +msgstr "" #: src/hello-world/benefits.md msgid "No iterator invalidation." -msgstr "āχāϟāĻžāϰ⧇āϟāϰ⧇āϰ āĻ…āĻŦ⧈āϧāĻ•āϰāĻŖ āĻ•āϰāĻž āϝāĻžā§ŸāύāĻžāĨ¤" +msgstr "" #: src/hello-world/benefits.md msgid "" "_No undefined runtime behavior_ - what a Rust statement does is never left " "unspecified" msgstr "" -"_āϕ⧋āύ āĻ…āύāĻŋāĻ°ā§āϧāĻžāϰāĻŋāϤ āϰāĻžāύāϟāĻžāχāĻŽ āφāϚāϰāĻŖ āύ⧟_- āĻāĻ•āϟāĻŋ āϰāĻžāĻ¸ā§āϟ āĻŦāĻŋāĻŦ⧃āϤāĻŋ āϝāĻž āĻ•āϰ⧇ āϤāĻž āĻ•āĻ–āύāχ āĻ…āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ " -"āĻĨāĻžāϕ⧇ āύāĻž" #: src/hello-world/benefits.md msgid "Array access is bounds checked." -msgstr "āĻ…ā§āϝāĻžāϰ⧇ āĻ…ā§āϝāĻžāĻ•ā§āϏ⧇āϏ āϏ⧀āĻŽāĻžāύāĻž āĻšā§‡āĻ• āĻ•āϰāĻž āĻšāϝāĻŧ." +msgstr "" #: src/hello-world/benefits.md msgid "Integer overflow is defined (panic or wrap-around)." -msgstr "āĻĒā§‚āĻ°ā§āĻŖāϏāĻ‚āĻ–ā§āϝāĻž āĻ“āĻ­āĻžāϰāĻĢā§āϞ⧋ āϏāĻ‚āĻœā§āĻžāĻžāϝāĻŧāĻŋāϤ āĻ•āϰāĻž āĻšāϝāĻŧāĨ¤" +msgstr "" #: src/hello-world/benefits.md msgid "" "_Modern language features_ - as expressive and ergonomic as higher-level " "languages" msgstr "" -"_āφāϧ⧁āύāĻŋāĻ• āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāĻŋāĻ‚ āĻ­āĻžāώāĻžāϰ āĻŦ⧈āĻļāĻŋāĻˇā§āĻŸā§āϝ_- āωāĻšā§āϚ-āĻ¸ā§āϤāϰ⧇āϰ āĻ­āĻžāώāĻžāϰ āĻŽāϤ⧋āχ āĻ…āĻ­āĻŋāĻŦā§āϝāĻ•ā§āϤāĻŋāĻĒā§‚āĻ°ā§āĻŖ āĻāĻŦāĻ‚ " -"āĻāϰāĻ—āύ⧋āĻŽāĻŋāĻ•" #: src/hello-world/benefits.md msgid "Enums and pattern matching." -msgstr "āχāύāĻžāĻŽ āĻāĻŦāĻ‚ āĻĒā§āϝāĻžāϟāĻžāĻ°ā§āύ āĻŽā§āϝāĻžāϚāĻŋāĻ‚āĨ¤" +msgstr "" #: src/hello-world/benefits.md msgid "Generics." -msgstr "āĻœā§‡āύ⧇āϰāĻŋāĻ•ā§āϏāĨ¤" +msgstr "" #: src/hello-world/benefits.md msgid "No overhead FFI." -msgstr "No overhead FFI." +msgstr "" #: src/hello-world/benefits.md msgid "Zero-cost abstractions." -msgstr "Zero-cost abstractions." +msgstr "" #: src/hello-world/benefits.md msgid "Great compiler errors." -msgstr "āĻŽāĻšāĻžāύ āĻ•āĻŽā§āĻĒāĻžāχāϞāĻžāϰ āĻ¤ā§āϰ⧁āϟāĻŋāĨ¤" +msgstr "" #: src/hello-world/benefits.md msgid "Built-in dependency manager." -msgstr "āĻ…āĻ¨ā§āϤāĻ°ā§āύāĻŋāĻ°ā§āĻŽāĻŋāϤ āĻĄāĻŋāĻĒ⧇āĻ¨ā§āĻĄā§‡āĻ¨ā§āϏāĻŋ āĻĒāϰāĻŋāϚāĻžāϞāĻ•āĨ¤" +msgstr "" #: src/hello-world/benefits.md msgid "Built-in support for testing." -msgstr "āĻĒāϰ⧀āĻ•ā§āώāĻž-āύāĻŋāϰ⧀āĻ•ā§āώāĻžāϰ āϜāĻ¨ā§āϝ⧇ āĻ…āĻ¨ā§āϤāĻ°ā§āύāĻŋāĻ°ā§āĻŽāĻŋāϤāĻ­āĻžāĻŦ⧇ āϏāĻŽāĻ°ā§āĻĨāύāĨ¤" +msgstr "" #: src/hello-world/benefits.md msgid "Excellent Language Server Protocol support." -msgstr "āϖ⧁āĻŦāχ āĻ­āĻžāϞ⧋ āϏāĻŽāĻ°ā§āĻĨāύ āĻ°ā§Ÿā§‡āϛ⧇ āĻ­āĻžāώāĻžāϰ āϏāĻžāĻ°ā§āĻ­āĻžāϰ āĻŽā§āϏāĻžāĻŦāĻŋāĻĻāĻžāϰāĨ¤" +msgstr "" #: src/hello-world/benefits.md msgid "" "Do not spend much time here. All of these points will be covered in more " "depth later." msgstr "" -"āĻāĻ–āĻžāύ⧇ āĻŦ⧇āĻļāĻŋ āϏāĻŽāϝāĻŧ āĻŦā§āϝāϝāĻŧ āĻ•āϰāĻŦ⧇āύ āύāĻžāĨ¤ āĻāχ āϏāĻŽāĻ¸ā§āϤ āĻŦāĻŋāώ⧟āϗ⧁āϞāĻŋ āĻĒāϰ⧇ āφāϰāĻ“ āĻ—āĻ­ā§€āϰāϤāĻžāϝāĻŧ āϚāĻ°ā§āϚāĻž āĻ•āϰāĻž āĻšāĻŦ⧇āĨ¤" #: src/hello-world/benefits.md msgid "" "Make sure to ask the class which languages they have experience with. " "Depending on the answer you can highlight different features of Rust:" msgstr "" -"āĻ•ā§āϞāĻžāϏ⧇ āϤāĻžāĻĻ⧇āϰ āϕ⧋āύ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāĻŋāĻ‚ āĻ­āĻžāώāĻžāϰ āĻ…āĻ­āĻŋāĻœā§āĻžāϤāĻž āφāϛ⧇ āϤāĻž āϜāĻŋāĻœā§āĻžāĻžāϏāĻž āĻ•āϰāϤ⧇ āϭ⧁āϞāĻŦ⧇āύ āύāĻžāĨ¤ āωāĻ¤ā§āϤāϰ⧇āϰ " -"āωāĻĒāϰ āύāĻŋāĻ°ā§āĻ­āϰ āĻ•āϰ⧇ āφāĻĒāύāĻŋ āϰāĻžāĻ¸ā§āϟ āĻāϰ āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āύ āĻŦ⧈āĻļāĻŋāĻˇā§āĻŸā§āϝ āωāĻ˛ā§āϞ⧇āĻ– āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ:" #: src/hello-world/benefits.md msgid "" @@ -2750,22 +3969,14 @@ msgid "" "have the memory unsafety issues. In addition, you get a modern language with " "constructs like pattern matching and built-in dependency management." msgstr "" -"āϏāĻŋ āĻŦāĻž āϏāĻŋ++ āĻāϰ āĻ…āĻ­āĻŋāĻœā§āĻžāϤāĻž: āϰāĻžāĻ¸ā§āϟ āϧāĻžāϰ āĻĒāϰ⧀āĻ•ā§āώāϕ⧇āϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ _āϰāĻžāύāϟāĻžāχāĻŽ āĻ¤ā§āϰ⧁āϟāĻŋāϰ_ āĻāĻ•āϟāĻŋ āϏāĻŽā§āĻĒā§‚āĻ°ā§āĻŖ " -"āĻ­āĻžāĻŦ⧇ āĻĻā§‚āϰ āĻ•āϰ⧇āĨ¤ āĻāĻŦāĻ‚ āφāĻĒāύāĻŋ āϏāĻŋ āĻāĻŦāĻ‚ āϏāĻŋ++ āĻāϰ āĻŽāϤ āĻ•āĻ°ā§āĻŽāĻ•ā§āώāĻŽāϤāĻž āĻĒāĻžāύ, āĻ•āĻŋāĻ¨ā§āϤ⧁ āφāĻĒāύāĻžāϰ āĻŽā§‡āĻŽāϰāĻŋāϰ " -"āύāĻŋāϰāĻžāĻĒāĻ¤ā§āϤāĻž āϏāĻ‚āĻ•ā§āϰāĻžāĻ¨ā§āϤ āϏāĻŽāĻ¸ā§āϝāĻž āĻĨāĻžāϕ⧇ āύāĻžāĨ¤ āĻāĻ›āĻžāĻĄāĻŧāĻžāĻ“, āφāĻĒāύāĻŋ āĻĒā§āϝāĻžāϟāĻžāĻ°ā§āύ āĻŽā§āϝāĻžāϚāĻŋāĻ‚ āĻāĻŦāĻ‚ " -"āĻ…āĻ¨ā§āϤāĻ°ā§āύāĻŋāĻšāĻŋāϤāĻ­āĻžāĻŦ⧇ āĻĄāĻŋāĻĒ⧇āĻ¨ā§āĻĄā§‡āĻ¨ā§āϏāĻŋ āĻŦā§āϝāĻŦāĻ¸ā§āĻĨāĻžāĻĒāύāĻžāϰ āĻŽāϤ⧋ āĻŦ⧈āĻļāĻŋāĻˇā§āϟ āϏāĻš āĻāĻ•āϟāĻŋ āφāϧ⧁āύāĻŋāĻ• āĻ­āĻžāώāĻž āĻĒāĻžāύāĨ¤" #: src/hello-world/benefits.md msgid "" "Experience with Java, Go, Python, JavaScript...: You get the same memory " "safety as in those languages, plus a similar high-level language feeling. In " "addition you get fast and predictable performance like C and C++ (no garbage " -"collector) as well as access to low-level hardware (should you need it)" +"collector) as well as access to low-level hardware (should you need it)." msgstr "" -"āϜāĻžāĻ­āĻž, āĻ—ā§‹, āĻĒāĻžāχāĻĨāύ, āϜāĻžāĻ­āĻžāĻ¸ā§āĻ•ā§āϰāĻŋāĻĒā§āĻŸā§‡āϰ āϏāĻžāĻĨ⧇ āĻ…āĻ­āĻŋāĻœā§āĻžāϤāĻž...: āφāĻĒāύāĻŋ āϏ⧇āχ āĻ­āĻžāώāĻžāϗ⧁āϞāĻŋāϰ āĻŽāϤ⧋ āĻāĻ•āχ " -"āĻŽā§‡āĻŽāϰāĻŋ āϏ⧁āϰāĻ•ā§āώāĻž āĻāĻŦāĻ‚ āĻāĻ•āχ āϰāĻ•āĻŽ āωāĻšā§āϚ-āĻ¸ā§āϤāϰ⧇āϰ āĻ­āĻžāώāĻž āĻ…āύ⧁āĻ­ā§‚āϤāĻŋ āĻĒā§‡ā§Ÿā§‡ āĻĨāĻžāϕ⧇āύāĨ¤ āĻāĻ›āĻžāĻĄāĻŧāĻžāĻ“ āφāĻĒāύāĻŋ āϏāĻŋ āĻāĻŦāĻ‚ " -"āϏāĻŋ++ āĻāϰ āĻŽāϤ āĻĻā§āϰ⧁āϤ āĻāĻŦāĻ‚ āĻ…āύ⧁āĻŽāĻžāύāϝ⧋āĻ—ā§āϝ āĻ•āĻ°ā§āĻŽāĻ•ā§āώāĻŽāϤāĻž āĻĒāĻžāĻŦ⧇āύ (āϕ⧋āύ⧋ āĻ—āĻžāĻ°ā§āĻŦ⧇āϜ āĻ•āĻžāϞ⧇āĻ•ā§āϟāϰ āĻ›āĻžā§œāĻžāχ) " -"āĻĒāĻžāĻļāĻžāĻĒāĻžāĻļāĻŋ āĻĻāϰāĻ•āĻžāϰāĻŽāϤāύ āύāĻŋāĻŽā§āύ-āĻ¸ā§āϤāϰ⧇āϰ āĻšāĻžāĻ°ā§āĻĄāĻ“āϝāĻŧā§āϝāĻžāϰ⧇ āĻ…ā§āϝāĻžāĻ•ā§āϏ⧇āϏāĨ¤" #: src/hello-world/playground.md msgid "" @@ -2774,18 +3985,12 @@ msgid "" "this course. Try running the \"hello-world\" program it starts with. It " "comes with a few handy features:" msgstr "" -"[āϰāĻžāĻ¸ā§āϟ āĻĒā§āϞ⧇āĻ—ā§āϰāĻžāωāĻ¨ā§āĻĄ](https://play.rust-lang.org/) āϏāĻ‚āĻ•ā§āώāĻŋāĻĒā§āϤ āϰāĻžāĻ¸ā§āϟ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽ āϚāĻžāϞāĻžāύ⧋āϰ " -"āĻāĻ•āϟāĻŋ āϏāĻšāϜ āωāĻĒāĻžāϝāĻŧ āĻĒā§āϰāĻĻāĻžāύ āĻ•āϰ⧇, āĻāĻŦāĻ‚ āĻāχ āϕ⧋āĻ°ā§āϏ⧇āϰ āωāĻĻāĻžāĻšāϰāĻŖ āĻāĻŦāĻ‚ āĻ…āύ⧁āĻļā§€āϞāύ⧇āϰ āĻ­āĻŋāĻ¤ā§āϤāĻŋāĨ¤ āĻāϟāĻŋ āĻĻāĻŋāϝāĻŧ⧇ " -"āĻļ⧁āϰ⧁ āĻšāĻ“āϝāĻŧāĻž \"āĻšā§āϝāĻžāϞ⧋-āĻ“āϝāĻŧāĻžāĻ°ā§āĻ˛ā§āĻĄ\" āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāϟāĻŋ āϚāĻžāϞāĻžāύ⧋āϰ āĻšā§‡āĻˇā§āϟāĻž āĻ•āϰ⧁āύāĨ¤ āĻāϟāĻŋ āĻ•āϝāĻŧ⧇āĻ•āϟāĻŋ āϏ⧁āĻŦāĻŋāϧāĻžāϜāύāĻ• " -"āĻŦ⧈āĻļāĻŋāĻˇā§āĻŸā§āϝ āϏāĻš āφāϏ⧇:" #: src/hello-world/playground.md msgid "" "Under \"Tools\", use the `rustfmt` option to format your code in the " "\"standard\" way." msgstr "" -"\"Tools\" āĻāϰ āύāĻŋāĻšā§‡, \"āĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄ\" āωāĻĒāĻžāϝāĻŧ⧇ āφāĻĒāύāĻžāϰ āϕ⧋āĻĄ āĻĢāĻ°ā§āĻŽā§āϝāĻžāϟ āĻ•āϰāϤ⧇ `rustfmt` " -"āĻŦāĻŋāĻ•āĻ˛ā§āĻĒāϟāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧁āύāĨ¤" #: src/hello-world/playground.md msgid "" @@ -2793,17 +3998,12 @@ msgid "" "checks, less optimization) and Release (fewer runtime checks, lots of " "optimization). These are accessible under \"Debug\" at the top." msgstr "" -"āϕ⧋āĻĄ āϤ⧈āϰāĻŋ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āϰāĻžāĻ¸ā§āĻŸā§‡āϰ āĻĻ⧁āϟāĻŋ āĻĒā§āϰāϧāĻžāύ \"āĻĒāϰāĻŋāϞ⧇āĻ–\" āφāϛ⧇: āĻĄāĻŋāĻŦāĻžāĻ— (āĻ…āϤāĻŋāϰāĻŋāĻ•ā§āϤ āϰāĻžāύāϟāĻžāχāĻŽ " -"āĻšā§‡āĻ•, āĻ•āĻŽ āĻ…āĻĒā§āϟāĻŋāĻŽāĻžāχāĻœā§‡āĻļāĻžāύ) āĻāĻŦāĻ‚ āϰāĻŋāϞāĻŋāϜ (āĻ•āĻŽ āϰāĻžāύāϟāĻžāχāĻŽ āĻšā§‡āĻ• āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻĒā§āϰāϚ⧁āϰ āĻĒāϰāĻŋāĻŽāĻžāϪ⧇ " -"āĻ…āĻĒā§āϟāĻŋāĻŽāĻžāχāĻœā§‡āĻļāĻžāύ)āĨ¤ \"Debug\" āĻāϰ āύāĻŋāĻšā§‡ āĻāϗ⧁āϞāĻŋ āĻĒāĻžāĻ“ā§ŸāĻž āϝāĻžāĻŦ⧇āĨ¤" #: src/hello-world/playground.md msgid "" "If you're interested, use \"ASM\" under \"...\" to see the generated " "assembly code." msgstr "" -"āϤ⧈āϰ⧀ āĻ•āϰāĻž āϏāĻŽāĻžāĻŦ⧇āĻļ āϕ⧋āĻĄ āĻĻ⧇āĻ–āϤ⧇ āϝāĻĻāĻŋ āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āφāĻ—ā§āϰāĻšā§€ āĻšāύ, āϤāĻžāĻšāϞ⧇ \"...\" āĻāϰ āĻ…āϧ⧀āύ⧇ " -"\"ASM\" āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧁āύāĨ¤" #: src/hello-world/playground.md msgid "" @@ -2813,80 +4013,95 @@ msgid "" "students who want to know more about Rust's optimizations or generated " "assembly." msgstr "" -"āĻļāĻŋāĻ•ā§āώāĻžāĻ°ā§āĻĨā§€āϰāĻž āϝāĻ–āύ āĻŦāĻŋāϰāϤāĻŋāϤ⧇ āϝāĻžāϝāĻŧ, āϤāĻ–āύ āϤāĻžāĻĻ⧇āϰ āĻĒā§āϞ⧇āĻ—ā§āϰāĻžāωāĻ¨ā§āĻĄ āϖ⧁āϞāϤ⧇ āĻāĻŦāĻ‚ āĻāĻ•āϟ⧁ āĻĒāϰ⧀āĻ•ā§āώāĻž-āύāĻŋāϰ⧀āĻ•ā§āώāĻž " -"āĻ•āϰāϤ⧇ āĻ‰ā§ŽāϏāĻžāĻšāĻŋāϤ āĻ•āϰ⧁āύāĨ¤ āϤāĻžāĻĻ⧇āϰ āĻŸā§āϝāĻžāĻŦ āĻ–ā§‹āϞāĻž āϰāĻžāĻ–āϤ⧇ āωāĻ¤ā§āϏāĻžāĻšāĻŋāϤ āĻ•āϰ⧁āύ āĻāĻŦāĻ‚ āĻŦāĻžāĻ•āĻŋ āϕ⧋āĻ°ā§āϏ⧇āϰ āϏāĻŽāϝāĻŧ āĻ•āĻŋāϛ⧁ " -"āĻšā§‡āĻˇā§āϟāĻž āĻ•āϰ⧇ āĻĻ⧇āĻ–āϤ⧇ āĻŦāϞ⧁āύāĨ¤ āĻāϟāĻŋ āĻŦāĻŋāĻļ⧇āώāϤ āωāĻ¨ā§āύāϤ āĻ›āĻžāĻ¤ā§āϰāĻĻ⧇āϰ āϜāĻ¨ā§āϝ āϏāĻšāĻžāϝāĻŧāĻ• āϝāĻžāϰāĻž āϰāĻžāĻ¸ā§āĻŸā§‡āϰ " -"āĻ…āĻĒā§āϟāĻŋāĻŽāĻžāχāĻœā§‡āĻļāύ āĻŦāĻž āĻœā§‡āύāĻžāϰ⧇āϟ āĻ•āϰāĻž āĻ…ā§āϝāĻžāϏ⧇āĻŽā§āĻŦāϞāĻŋ āϏāĻŽā§āĻĒāĻ°ā§āϕ⧇ āφāϰāĻ“ āϜāĻžāύāϤ⧇ āϚāĻžāύāĨ¤" -#: src/types-and-values.md -msgid "[Hello, World](./types-and-values/hello-world.md) (5 minutes)" -msgstr "[āĻšā§āϝāĻžāϞ⧋, āĻ“ā§ŸāĻžāĻ°ā§āĻ˛ā§āĻĄ](./types-and-values/hello-world.md) (ā§Ģ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/types-and-values.md -msgid "[Variables](./types-and-values/variables.md) (5 minutes)" -msgstr "[āϭ⧇āϰāĻŋāĻāĻŦāϞ⧇āϏ](./types-and-values/variables.md) (ā§Ģ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/types-and-values.md -msgid "[Values](./types-and-values/values.md) (5 minutes)" -msgstr "[āĻŽāĻžāύ](./types-and-values/values.md) (ā§Ģ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/types-and-values.md -msgid "[Arithmetic](./types-and-values/arithmetic.md) (3 minutes)" -msgstr "[āĻ—āĻŖāĻŋāϤ](./types-and-values/arithmetic.md) (ā§Š āĻŽāĻŋāύāĻŋāϟ)" - -#: src/types-and-values.md -msgid "[Strings](./types-and-values/strings.md) (5 minutes)" -msgstr "[āĻ¸ā§āĻŸā§āϰāĻŋāĻ‚](./types-and-values/strings.md) (ā§Ģ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/types-and-values.md -msgid "[Type Inference](./types-and-values/inference.md) (3 minutes)" -msgstr "[āϟāĻžāχāĻĒ⧇āϰ āĻ…āύ⧁āĻŽāĻŋāϤāĻŋ](./types-and-values/inference.md) (ā§Š āĻŽāĻŋāύāĻŋāϟ)" - -#: src/types-and-values.md -msgid "[Exercise: Fibonacci](./types-and-values/exercise.md) (15 minutes)" -msgstr "[āĻ…āύ⧁āĻļā§€āϞāύ⧀: : āĻĢāĻŋāĻŦā§‹āύāĻžāϚāĻŋ](./types-and-values/exercise.md) (ā§§ā§Ģ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/types-and-values.md src/methods-and-traits.md src/iterators.md -msgid "This segment should take about 45 minutes" -msgstr "āĻāχ āĻ…āĻ‚āĻļāϟāĻŋ āĻĒā§āϰāĻžāϝāĻŧ ā§Ēā§Ģ āĻŽāĻŋāύāĻŋāϟ āϏāĻŽāϝāĻŧ āύ⧇āĻŦ⧇" +#: src/types-and-values.md src/concurrency/async.md +msgid "This segment should take about 40 minutes. It contains:" +msgstr "" #: src/types-and-values/hello-world.md msgid "" "Let us jump into the simplest possible Rust program, a classic Hello World " "program:" msgstr "" -"āφāϏ⧁āύ āϏāĻšāϜāϤāĻŽ āϏāĻŽā§āĻ­āĻžāĻŦā§āϝ āϰāĻžāĻ¸ā§āϟ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽā§‡ āĻāĻžāρāĻĒ āĻĻ⧇āĻ“āϝāĻŧāĻž āϝāĻžāĻ•, āĻāĻ•āϟāĻŋ āĻ•ā§āϞāĻžāϏāĻŋāĻ• āĻšā§āϝāĻžāϞ⧋ āĻ“āϝāĻŧāĻžāĻ°ā§āĻ˛ā§āĻĄ " -"āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽ:" + +#: src/types-and-values/hello-world.md src/control-flow-basics/if.md +#: src/control-flow-basics/match.md src/control-flow-basics/loops/for.md +#: src/control-flow-basics/loops/loop.md +#: src/control-flow-basics/break-continue/labels.md +#: src/tuples-and-arrays/arrays.md src/references/strings.md +#: src/references/dangling.md src/user-defined-types/static.md +#: src/pattern-matching/match.md src/methods-and-traits/traits/implementing.md +#: src/methods-and-traits/traits/supertraits.md +#: src/methods-and-traits/traits/associated-types.md +#: src/generics/generic-traits.md src/generics/dyn-trait.md +#: src/smart-pointers/trait-objects.md src/borrowing/examples.md +#: src/lifetimes/lifetime-elision.md src/lifetimes/struct-lifetimes.md +#: src/lifetimes/exercise.md src/lifetimes/solution.md +#: src/iterators/motivation.md src/iterators/helpers.md +#: src/iterators/collect.md src/modules/encapsulation.md +#: src/error-handling/thiserror.md src/error-handling/anyhow.md +#: src/android/aidl/example-service/service-bindings.md +#: src/android/aidl/example-service/service.md +#: src/android/aidl/example-service/server.md +#: src/android/aidl/example-service/client.md +#: src/android/aidl/example-service/changing-definition.md +#: src/android/aidl/example-service/changing-implementation.md +#: src/android/aidl/types/objects.md src/android/aidl/types/parcelables.md +#: src/android/aidl/types/file-descriptor.md src/android/testing.md +#: src/android/testing/googletest.md src/android/testing/mocking.md +#: src/concurrency/threads/plain.md src/concurrency/threads/scoped.md +#: src/concurrency/channels/senders-receivers.md +#: src/concurrency/shared-state/arc.md src/concurrency/shared-state/mutex.md +#: src/concurrency/shared-state/example.md +#: src/concurrency/sync-exercises/dining-philosophers.md +#: src/concurrency/sync-exercises/link-checker.md +#: src/concurrency/sync-exercises/solutions.md +#: src/concurrency/async/async-await.md src/concurrency/async/futures.md +#: src/concurrency/async/runtimes/tokio.md src/concurrency/async/tasks.md +#: src/concurrency/async-control-flow/channels.md +#: src/concurrency/async-control-flow/join.md +#: src/concurrency/async-control-flow/select.md +#: src/concurrency/async-pitfalls/blocking-executor.md +#: src/concurrency/async-pitfalls/pin.md +#: src/concurrency/async-pitfalls/async-traits.md +#: src/concurrency/async-pitfalls/cancellation.md +#: src/concurrency/async-exercises/dining-philosophers.md +#: src/concurrency/async-exercises/chat-app.md +#: src/concurrency/async-exercises/solutions.md +msgid "// Copyright 2024 Google LLC\n" +msgstr "" #: src/types-and-values/hello-world.md msgid "\"Hello 🌍!\"" -msgstr "\"Hello 🌍!\"" +msgstr "" #: src/types-and-values/hello-world.md msgid "What you see:" -msgstr "āϝāĻž āϤ⧁āĻŽāĻŋ āĻĻ⧇āĻ–āϤ⧇ āĻĒāĻžāĻ“āσ" +msgstr "" #: src/types-and-values/hello-world.md msgid "Functions are introduced with `fn`." -msgstr "`fn` āĻĻāĻŋāϝāĻŧ⧇ āĻĢāĻžāĻ‚āĻļāύ āϚāĻžāϞ⧁ āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇āĨ¤" +msgstr "" + +#: src/types-and-values/hello-world.md +msgid "The `main` function is the entry point of the program." +msgstr "" #: src/types-and-values/hello-world.md msgid "Blocks are delimited by curly braces like in C and C++." msgstr "" -"āĻŦā§āϞāĻ•āϗ⧁āϞāĻŋ āϏāĻŋ āĻāĻŦāĻ‚ āϏāĻŋ++ āĻāϰ āĻŽāϤ āϕ⧋āρāĻ•āĻĄāĻŧāĻž āϧāύ⧁āĻ°ā§āĻŦāĻ¨ā§āϧāύ⧀ (āĻ•āĻžāϰāϞāĻŋ āĻŦā§āϰ⧇āϏ⧇āϏ) āĻĻā§āĻŦāĻžāϰāĻž āϏ⧀āĻŽāĻžāĻŦāĻĻā§āϧ āĻ•āϰāĻž āĻšāϝāĻŧāĨ¤" #: src/types-and-values/hello-world.md -msgid "The `main` function is the entry point of the program." -msgstr "āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽ āϏāĻŦāϏāĻŽā§Ÿā§‡ `main` āĻĢāĻžāĻ‚āĻļāύ āĻĨ⧇āϕ⧇ āĻļ⧁āϰ⧁ āĻšā§ŸāĨ¤" +msgid "Statements end with `;`." +msgstr "" #: src/types-and-values/hello-world.md -msgid "Rust has hygienic macros, `println!` is an example of this." -msgstr "āϰāĻžāĻ¸ā§āĻŸā§‡āϰ āĻŽā§āϝāĻžāĻ•ā§āϰ⧋ āĻ¸ā§āĻŦāĻžāĻ¸ā§āĻĨāĻ•āϰ āĻŦāϞāĻž āϝ⧇āϤ⧇ āĻĒāĻžāϰ⧇, `println!` āĻāϰāχ āĻāĻ• āωāĻĻāĻžāĻšāϰāĻŖāĨ¤" +msgid "`println` is a macro, indicated by the `!` in the invocation." +msgstr "" #: src/types-and-values/hello-world.md msgid "Rust strings are UTF-8 encoded and can contain any Unicode character." msgstr "" -"āϰāĻžāĻ¸ā§āĻŸā§‡āϰ āĻ¸ā§āĻŸā§āϰāĻŋāĻ‚āϗ⧁āϞāĻŋ āχāω.āϟāĻŋ.āĻāĻĢ-ā§Ž āĻāύāϕ⧋āĻĄā§‡āĻĄ āĻāĻŦāĻ‚ āϝ⧇ āϕ⧋āύāĻ“ āχāωāύāĻŋāϕ⧋āĻĄ āĻ…āĻ•ā§āώāϰ āĻāϤ⧇ āĻĨāĻžāĻ•āϤ⧇ āĻĒāĻžāϰ⧇āĨ¤" #: src/types-and-values/hello-world.md msgid "" @@ -2894,39 +4109,29 @@ msgid "" "see a ton of it over the next four days so we start small with something " "familiar." msgstr "" -"āĻāχ āĻ¸ā§āϞāĻžāχāĻĄāϟāĻŋ āĻļāĻŋāĻ•ā§āώāĻžāĻ°ā§āĻĨā§€āĻĻ⧇āϰ āϰāĻžāĻ¸ā§āϟ āϕ⧋āĻĄā§‡āϰ āϏāĻžāĻĨ⧇ āϏ⧁āĻĒāϰāĻŋāϚāĻŋāϤ āĻ•āϰāĻžāϰ āĻšā§‡āĻˇā§āϟāĻž āĻ•āϰ⧇āĨ¤ āϤāĻžāϰāĻž āĻĒāϰ⧇āϰ āϚāĻžāϰ " -"āĻĻāĻŋāύ⧇ āĻāϟāĻŋ āĻ…āύ⧇āĻ•āĻŦāĻžāϰ āĻĻ⧇āĻ–āϤ⧇ āĻĒāĻžāĻŦ⧇ āϤāĻžāχ āφāĻŽāϰāĻž āĻĒāϰāĻŋāϚāĻŋāϤ āĻ•āĻŋāϛ⧁ āϛ⧋āϟ āĻĻāĻŋāϝāĻŧ⧇ āĻļ⧁āϰ⧁ āĻ•āϰāĻŋāĨ¤" #: src/types-and-values/hello-world.md msgid "" "Rust is very much like other languages in the C/C++/Java tradition. It is " "imperative and it doesn't try to reinvent things unless absolutely necessary." msgstr "" -"āϰāĻžāĻ¸ā§āϟ āϏāĻŋ/āϏāĻŋ++/āϜāĻžāĻ­āĻž āϐāϤāĻŋāĻšā§āϝ⧇āϰ āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āĻ­āĻžāώāĻžāϰ āĻŽāϤ⧋āχāĨ¤ āĻāϟāĻž āĻ…āύ⧁āĻœā§āĻžāĻžāϏ⧂āϚāĻ• āĻāĻŦāĻ‚ āĻāϟāĻŋ āĻāϕ⧇āĻŦāĻžāϰ⧇ " -"āĻĒā§āϰāϝāĻŧā§‹āϜāύ⧀āϝāĻŧ āύāĻž āĻšāϞ⧇ āϜāĻŋāύāĻŋāϏāϗ⧁āϞāĻŋāϕ⧇ āĻĒ⧁āύāϰāĻžāϝāĻŧ āωāĻĻā§āĻ­āĻžāĻŦāύ⧇āϰ āĻšā§‡āĻˇā§āϟāĻž āĻ•āϰ⧇ āύāĻžāĨ¤" #: src/types-and-values/hello-world.md -msgid "Rust is modern with full support for things like Unicode." -msgstr "āχāωāύāĻŋāϕ⧋āĻĄā§‡āϰ āĻŽāϤ⧋ āϜāĻŋāύāĻŋāϏāϗ⧁āϞāĻŋāϰ āϜāĻ¨ā§āϝ āϏāĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āϏāĻŽāĻ°ā§āĻĨāύ āϏāĻš āϰāĻžāĻ¸ā§āϟ āĻāĻ•āϟāĻŋ āφāϧ⧁āύāĻŋāĻ• āĻ­āĻžāώāĻžāĨ¤" +msgid "Rust is modern with full support for Unicode." +msgstr "" #: src/types-and-values/hello-world.md msgid "" "Rust uses macros for situations where you want to have a variable number of " "arguments (no function [overloading](../control-flow-basics/functions.md))." msgstr "" -"āϰāĻžāĻ¸ā§āĻŸā§‡ āĻĢāĻžāĻ‚āĻļāύ [āĻ“āĻ­āĻžāϰāϞ⧋āĻĄāĻŋāĻ‚](../control-flow-basics/functions.md) āύ⧇āχ āϤāĻžāχ āĻāĻŽāύ " -"āĻĒāϰāĻŋāĻ¸ā§āĻĨāĻŋāϤāĻŋāϤ⧇ āĻŽā§āϝāĻžāĻ•ā§āϰ⧋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ āϝ⧇āĻ–āĻžāύ⧇ āφāĻĒāύāĻŋ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύāĻļā§€āϞ āϏāĻ‚āĻ–ā§āϝāĻ• āφāĻ°ā§āϗ⧁āĻŽā§‡āĻ¨ā§āϟ āϰāĻžāĻ–āϤ⧇ āϚāĻžāύāĨ¤" #: src/types-and-values/hello-world.md msgid "" -"Macros being 'hygienic' means they don't accidentally capture identifiers " -"from the scope they are used in. Rust macros are actually only [partially " -"hygienic](https://veykril.github.io/tlborm/decl-macros/minutiae/hygiene." -"html)." +"`println!` is a macro because it needs to handle an arbitrary number of " +"arguments based on the format string, which can't be done with a regular " +"function. Otherwise it can be treated like a regular function." msgstr "" -"āĻŽā§āϝāĻžāĻ•ā§āϰ⧋āϗ⧁āϞāĻŋ 'āĻ¸ā§āĻŦāĻžāĻ¸ā§āĻĨā§āϝāĻ•āϰ' āĻšāĻ“āϝāĻŧāĻžāϰ āĻ…āĻ°ā§āĻĨ āĻšāϞ āϝ⧇ āϤāĻžāϰāĻž āĻĻ⧁āĻ°ā§āϘāϟāύāĻžāĻ•ā§āϰāĻŽā§‡ āϤāĻžāĻĻ⧇āϰ āĻŦā§āϝāĻŦāĻšā§ƒāϤ āĻ¸ā§āϕ⧋āĻĒ⧇āϰ āĻŽāĻ§ā§āϝ⧇ " -"āĻĨ⧇āϕ⧇ āĻ­ā§āϝāĻžāϰāĻŋā§Ÿā§‡āĻŦāϞ āϤ⧁āϞ⧇ āύāĻžāĨ¤ āϰāĻžāĻ¸ā§āĻŸā§‡āϰ āĻŽā§āϝāĻžāĻ•ā§āϰ⧋ āφāϏāϞ⧇ āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ [āφāĻ‚āĻļāĻŋāĻ•āĻ­āĻžāĻŦ⧇ āĻ¸ā§āĻŦāĻžāĻ¸ā§āĻĨā§āϝāĻ•āϰ]" -"(https://veykril.github.io/tlborm/decl-macros/minutiae/hygiene.html)āĨ¤" #: src/types-and-values/hello-world.md msgid "" @@ -2935,39 +4140,105 @@ msgid "" "while it is not a functional language, it includes a range of [functional " "concepts](https://doc.rust-lang.org/book/ch13-00-functional-features.html)." msgstr "" -"āϰāĻžāĻ¸ā§āϟ āĻŦāĻšā§-āĻĻ⧃āĻˇā§āϟāĻžāĻ¨ā§āϤ āĻāĻ•āϟāĻŋ āĻ­āĻžāώāĻžāĨ¤ āωāĻĻāĻžāĻšāϰāĻŖāĻ¸ā§āĻŦāϰ⧂āĻĒ, āĻāϟāĻŋāϤ⧇ āĻļāĻ•ā§āϤāĻŋāĻļāĻžāϞ⧀ [āĻ…āĻŦāĻœā§‡āĻ•ā§āϟ-āĻ“āϰāĻŋāϝāĻŧ⧇āĻ¨ā§āĻŸā§‡āĻĄ " -"āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāĻŋāĻ‚ āĻŦ⧈āĻļāĻŋāĻˇā§āĻŸā§āϝ āϰāϝāĻŧ⧇āϛ⧇](https://doc.rust-lang.org/book/ch17-00-oop.html)," -"āĻāĻŦāĻ‚, āϝāĻĻāĻŋāĻ“ āĻāϟāĻŋ āĻāĻ•āϟāĻŋ āĻĢāĻžāĻ‚āĻļāύāĻžāϞ āĻ­āĻžāώāĻž āύāϝāĻŧ, āĻāϟāĻŋāϤ⧇ āĻ…āύ⧇āĻ• [āĻĢāĻžāĻ‚āĻļāύāĻžāϞ āĻ­āĻžāώāĻžāϰ āϧāĻžāϰāĻŖāĻž](https://" -"doc.rust-lang.org/book/ch13-00-functional-features.html) āĻ“ āĻ°ā§Ÿā§‡āϛ⧇āĨ¤" #: src/types-and-values/variables.md msgid "" "Rust provides type safety via static typing. Variable bindings are made with " "`let`:" msgstr "" -"āϰāĻžāĻ¸ā§āϟ āĻ¸ā§āĻŸā§āϝāĻžāϟāĻŋāĻ• āϟāĻžāχāĻĒāĻŋāĻ‚āϝāĻŧ⧇āϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ āϟāĻžāχāĻĒ āύāĻŋāϰāĻžāĻĒāĻ¤ā§āϤāĻž āĻĒā§āϰāĻĻāĻžāύ āĻ•āϰ⧇āĨ¤ āĻ­ā§āϝāĻžāϰāĻŋā§Ÿā§‡āĻŦāϞ⧇āϰ āĻŦāĻžāχāĻ¨ā§āĻĄāĻŋāĻ‚ " -"`let` āĻĻāĻŋāϝāĻŧ⧇ āϤ⧈āϰāĻŋ āĻ•āϰāĻž āĻšāϝāĻŧ:" -#: src/types-and-values/variables.md src/control-flow-basics/loops/for.md +#: src/types-and-values/variables.md src/types-and-values/arithmetic.md +#: src/types-and-values/inference.md src/types-and-values/exercise.md +#: src/types-and-values/solution.md #: src/control-flow-basics/blocks-and-scopes.md +#: src/control-flow-basics/loops.md src/control-flow-basics/break-continue.md +#: src/control-flow-basics/macros.md src/control-flow-basics/exercise.md +#: src/control-flow-basics/solution.md src/tuples-and-arrays/iteration.md +#: src/tuples-and-arrays/destructuring.md src/tuples-and-arrays/exercise.md +#: src/tuples-and-arrays/solution.md src/references/shared.md +#: src/references/exercise.md src/references/solution.md +#: src/user-defined-types/named-structs.md +#: src/user-defined-types/tuple-structs.md src/user-defined-types/enums.md +#: src/user-defined-types/aliases.md src/user-defined-types/exercise.md +#: src/user-defined-types/solution.md src/pattern-matching/exercise.md +#: src/pattern-matching/solution.md src/methods-and-traits/methods.md +#: src/methods-and-traits/traits.md src/methods-and-traits/deriving.md +#: src/methods-and-traits/exercise.md src/methods-and-traits/solution.md +#: src/generics/generic-functions.md src/generics/generic-data.md +#: src/generics/exercise.md src/generics/solution.md src/std-types/docs.md +#: src/std-types/option.md src/std-types/result.md src/std-types/string.md +#: src/std-types/vec.md src/std-types/hashmap.md src/std-types/exercise.md +#: src/std-types/solution.md src/std-traits/comparisons.md +#: src/std-traits/operators.md src/std-traits/from-and-into.md +#: src/std-traits/casting.md src/std-traits/read-and-write.md +#: src/std-traits/default.md src/std-traits/exercise.md +#: src/std-traits/solution.md src/memory-management/review.md +#: src/memory-management/move.md src/memory-management/clone.md +#: src/memory-management/drop.md src/memory-management/exercise.md +#: src/memory-management/solution.md src/smart-pointers/box.md +#: src/smart-pointers/rc.md src/smart-pointers/exercise.md +#: src/smart-pointers/solution.md src/borrowing/exercise.md +#: src/borrowing/solution.md src/iterators/iterator.md +#: src/iterators/intoiterator.md src/iterators/exercise.md +#: src/iterators/solution.md src/modules/modules.md src/modules/exercise.md +#: src/modules/solution.md src/testing/other.md src/testing/lints.md +#: src/testing/exercise.md src/testing/solution.md src/error-handling/try.md +#: src/error-handling/try-conversions.md src/error-handling/error.md +#: src/error-handling/exercise.md src/error-handling/solution.md +#: src/unsafe-rust/dereferencing.md src/unsafe-rust/mutable-static.md +#: src/unsafe-rust/unions.md src/unsafe-rust/unsafe-traits.md +#: src/unsafe-rust/exercise.md src/unsafe-rust/solution.md +#: src/android/interoperability/cpp/bridge.md +#: src/android/interoperability/cpp/rust-bridge.md +#: src/android/interoperability/cpp/generated-cpp.md +#: src/android/interoperability/cpp/cpp-bridge.md +#: src/android/interoperability/cpp/shared-types.md +#: src/android/interoperability/cpp/shared-enums.md +#: src/android/interoperability/cpp/rust-result.md +#: src/android/interoperability/cpp/cpp-exception.md +#: src/exercises/chromium/build-rules.md src/chromium/testing.md +#: src/chromium/testing/rust-gtest-interop.md +#: src/chromium/testing/chromium-import-macro.md +#: src/chromium/interoperability-with-cpp/example-bindings.md +#: src/chromium/interoperability-with-cpp/error-handling-qr.md +#: src/chromium/interoperability-with-cpp/error-handling-png.md +#: src/bare-metal/alloc.md src/bare-metal/microcontrollers/mmio.md +#: src/bare-metal/microcontrollers/pacs.md +#: src/bare-metal/microcontrollers/hals.md +#: src/bare-metal/microcontrollers/type-state.md +#: src/exercises/bare-metal/solutions-morning.md +#: src/bare-metal/aps/inline-assembly.md src/bare-metal/aps/mmio.md +#: src/bare-metal/aps/uart.md src/bare-metal/aps/uart/traits.md +#: src/bare-metal/aps/better-uart/bitflags.md +#: src/bare-metal/aps/better-uart/driver.md src/bare-metal/aps/logging.md +#: src/bare-metal/aps/logging/using.md +#: src/bare-metal/useful-crates/aarch64-paging.md +#: src/exercises/bare-metal/solutions-afternoon.md +msgid "// Copyright 2023 Google LLC\n" +msgstr "" + +#: src/types-and-values/variables.md msgid "\"x: {x}\"" -msgstr "\"x: {x}\"" +msgstr "" #: src/types-and-values/variables.md -msgid "// x = 20;" -msgstr "// x = 20;" - -#: src/types-and-values/variables.md -msgid "// println!(\"x: {x}\");" -msgstr "// println!(\"x: {x}\");" +msgid "" +"// x = 20;\n" +" // println!(\"x: {x}\");\n" +msgstr "" #: src/types-and-values/variables.md msgid "" "Uncomment the `x = 20` to demonstrate that variables are immutable by " "default. Add the `mut` keyword to allow changes." msgstr "" -"āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞāϗ⧁āϞāĻŋ āĻ—āϤāĻžāύ⧁āĻ—āϤāĻŋāĻ•āϰ⧂āĻĒ⧇ āĻ…āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ⧀āϝāĻŧ āϤāĻž āĻĒā§āϰāĻĻāĻ°ā§āĻļāύ āĻ•āϰāϤ⧇ `x = 20` āϟāĻŋ āφāύāĻ•āĻŽā§‡āĻ¨ā§āϟ āĻ•āϰ⧁āύāĨ¤ " -"āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ⧇āϰ āĻ…āύ⧁āĻŽāϤāĻŋ āĻĻāĻŋāϤ⧇ `mut` āϕ⧀āĻ“āϝāĻŧāĻžāĻ°ā§āĻĄ āϝ⧋āĻ— āĻ•āϰ⧁āύāĨ¤" + +#: src/types-and-values/variables.md +msgid "" +"Warnings are enabled for this slide, such as for unused variables or " +"unnecessary `mut`. These are omitted in most slides to avoid distracting " +"warnings. Try removing the mutation but leaving the `mut` keyword in place." +msgstr "" #: src/types-and-values/variables.md msgid "" @@ -2975,109 +4246,104 @@ msgid "" "time, but type inference (covered later) allows the programmer to omit it in " "many cases." msgstr "" -"āĻāĻ–āĻžāύ⧇ `i32` āĻšāϞ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ⧇āϰ āϧāϰāύāĨ¤ āĻ•āĻŽā§āĻĒāĻžāχāϞ⧇āϰ āϏāĻŽāϝāĻŧ āĻāϟāĻŋ āĻ…āĻŦāĻļā§āϝāχ āϜāĻžāύāĻž āĻĨāĻžāĻ•āĻž āĻĻāϰāĻ•āĻžāϰ, āϤāĻŦ⧇ " -"āϟāĻžāχāĻĒ āχāύāĻĢāĻžāϰ⧇āĻ¨ā§āϏ (āĻĒāϰ⧇ āφāĻšā§āĻ›āĻžāĻĻāĻŋāϤ) āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāĻžāϰāϕ⧇ āĻ…āύ⧇āĻ• āĻ•ā§āώ⧇āĻ¤ā§āϰ⧇ āĻāϟāĻŋ āĻŦāĻžāĻĻ āĻĻ⧇āĻ“āϝāĻŧāĻžāϰ āĻ…āύ⧁āĻŽāϤāĻŋ āĻĻ⧇āϝāĻŧāĨ¤" #: src/types-and-values/values.md msgid "" "Here are some basic built-in types, and the syntax for literal values of " "each type." msgstr "" -"āĻāĻ–āĻžāύ⧇ āĻ•āĻŋāϛ⧁ āĻŽā§ŒāϞāĻŋāĻ• āĻ…āĻ¨ā§āϤāĻ°ā§āύāĻŋāĻ°ā§āĻŽāĻŋāϤ āϟāĻžāχāĻĒ āϰāϝāĻŧ⧇āϛ⧇, āĻāĻŦāĻ‚ āĻĒā§āϰāϤāĻŋāϟāĻŋ āĻĒā§āϰāĻ•āĻžāϰ⧇āϰ āφāĻ•ā§āώāϰāĻŋāĻ• āĻŽāĻžāύāϗ⧁āϞāĻŋāϰ āϜāĻ¨ā§āϝ " -"āĻŦāĻžāĻ•ā§āϝ āĻ—āĻ āύ āĻ“ āĻĻ⧇āĻ“ā§ŸāĻž āĻ°ā§Ÿā§‡āϛ⧇āĨ¤" -#: src/types-and-values/values.md src/tuples-and-arrays/tuples-and-arrays.md -#: src/unsafe-rust/exercise.md +#: src/types-and-values/values.md src/unsafe-rust/exercise.md msgid "Types" -msgstr "Types" +msgstr "" -#: src/types-and-values/values.md src/tuples-and-arrays/tuples-and-arrays.md +#: src/types-and-values/values.md msgid "Literals" -msgstr "Literals" +msgstr "" #: src/types-and-values/values.md msgid "Signed integers" -msgstr "Signed integers" +msgstr "" #: src/types-and-values/values.md msgid "`i8`, `i16`, `i32`, `i64`, `i128`, `isize`" -msgstr "`i8`, `i16`, `i32`, `i64`, `i128`, `isize`" +msgstr "" #: src/types-and-values/values.md msgid "`-10`, `0`, `1_000`, `123_i64`" -msgstr "`-10`, `0`, `1_000`, `123_i64`" +msgstr "" #: src/types-and-values/values.md msgid "Unsigned integers" -msgstr "Unsigned integers" +msgstr "" #: src/types-and-values/values.md msgid "`u8`, `u16`, `u32`, `u64`, `u128`, `usize`" -msgstr "`u8`, `u16`, `u32`, `u64`, `u128`, `usize`" +msgstr "" #: src/types-and-values/values.md msgid "`0`, `123`, `10_u16`" -msgstr "`0`, `123`, `10_u16`" +msgstr "" #: src/types-and-values/values.md msgid "Floating point numbers" -msgstr "Floating point numbers" +msgstr "" #: src/types-and-values/values.md msgid "`f32`, `f64`" -msgstr "`f32`, `f64`" +msgstr "" #: src/types-and-values/values.md msgid "`3.14`, `-10.0e20`, `2_f32`" -msgstr "`3.14`, `-10.0e20`, `2_f32`" +msgstr "" #: src/types-and-values/values.md msgid "Unicode scalar values" -msgstr "Unicode scalar values" +msgstr "" #: src/types-and-values/values.md src/android/aidl/types/primitives.md msgid "`char`" -msgstr "`char`" +msgstr "" #: src/types-and-values/values.md msgid "`'a'`, `'Îą'`, `'∞'`" -msgstr "`'a'`, `'Îą'`, `'∞'`" +msgstr "" #: src/types-and-values/values.md msgid "Booleans" -msgstr "Booleans" +msgstr "" #: src/types-and-values/values.md src/android/aidl/types/primitives.md msgid "`bool`" -msgstr "`bool`" +msgstr "" #: src/types-and-values/values.md msgid "`true`, `false`" -msgstr "`true`, `false`" +msgstr "" #: src/types-and-values/values.md msgid "The types have widths as follows:" -msgstr "āϟāĻžāχāĻĒāϗ⧁āϞ⧋āϰ āφāĻ•āĻžāϰ āĻ āϰāĻ•āĻŽ:" +msgstr "" #: src/types-and-values/values.md msgid "`iN`, `uN`, and `fN` are _N_ bits wide," -msgstr "`iN`, `uN`, and `fN` are _N_ bits wide," +msgstr "" #: src/types-and-values/values.md msgid "`isize` and `usize` are the width of a pointer," -msgstr "`isize` and `usize` are the width of a pointer," +msgstr "" #: src/types-and-values/values.md msgid "`char` is 32 bits wide," -msgstr "`char` āĻšāĻšā§āϛ⧇ ā§Šā§¨ āĻŦāĻŋāϟ āĻĒā§āϰāĻļāĻ¸ā§āϤ," +msgstr "" #: src/types-and-values/values.md msgid "`bool` is 8 bits wide." -msgstr "`bool` āĻšāĻšā§āϛ⧇ ā§Ž āĻŦāĻŋāϟ āϚ⧌⧜āĻžāĨ¤" +msgstr "" #: src/types-and-values/values.md -msgid "There are a few syntaxes which are not shown above:" -msgstr "āĻ•āĻŋāϛ⧁ āϏāĻŋāύāĻŸā§āϝāĻžāĻ•ā§āϏ āφāϛ⧇ āϝāĻž āωāĻĒāϰ⧇ āĻĻ⧇āĻ–āĻžāύ⧋ āĻšāϝāĻŧāύāĻŋāσ" +msgid "There are a few syntaxes that are not shown above:" +msgstr "" #: src/types-and-values/values.md msgid "" @@ -3085,13 +4351,10 @@ msgid "" "`1_000` can be written as `1000` (or `10_00`), and `123_i64` can be written " "as `123i64`." msgstr "" -"āϏāĻ‚āĻ–ā§āϝāĻžāϰ āϏāĻŽāĻ¸ā§āϤ āφāĻ¨ā§āĻĄāĻžāϰāĻ¸ā§āϕ⧋āϰ āĻŦāĻžāĻĻ āĻĻ⧇āĻ“āϝāĻŧāĻž āϝ⧇āϤ⧇ āĻĒāĻžāϰ⧇, āϏ⧇āϗ⧁āϞāĻŋ āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ āĻ¸ā§āĻĒāĻˇā§āϟāϤāĻžāϰ āϜāĻ¨ā§āϝ āĻĻ⧇āĻ“ā§ŸāĻžāĨ¤ " -"āϏ⧁āϤāϰāĻžāĻ‚ `1_000` āϕ⧇ `1000` (āĻŦāĻž `10_00`) āĻšāĻŋāϏāĻžāĻŦ⧇ āϞ⧇āĻ–āĻž āϝ⧇āϤ⧇ āĻĒāĻžāϰ⧇ āĻāĻŦāĻ‚ `123_i64` āϕ⧇ " -"`123i64` āĻšāĻŋāϏāĻžāĻŦ⧇ āϞ⧇āĻ–āĻž āϝ⧇āϤ⧇ āĻĒāĻžāϰ⧇āĨ¤" #: src/types-and-values/arithmetic.md msgid "\"result: {}\"" -msgstr "\"result: {}\"" +msgstr "" #: src/types-and-values/arithmetic.md msgid "" @@ -3099,23 +4362,17 @@ msgid "" "meaning should be clear: it takes three integers, and returns an integer. " "Functions will be covered in more detail later." msgstr "" -"āĻāχ āĻĒā§āϰāĻĨāĻŽ āφāĻŽāϰāĻž āĻŦāĻžāĻĻ⧇ āĻ…āĻ¨ā§āϝ āϕ⧋āύ⧋ āĻĢāĻžāĻ‚āĻļāύ āĻĻ⧇āĻ–āĻ›āĻŋ, āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻāχ āĻĢāĻžāĻ‚āĻļāύ⧇āϰ āĻ…āĻ°ā§āĻĨāϟāĻŋ āĻĒāϰāĻŋāĻˇā§āĻ•āĻžāϰ āĻšāĻ“āϝāĻŧāĻž " -"āωāϚāĻŋāϤ: āĻāϟāĻŋ āϤāĻŋāύāϟāĻŋ āĻĒā§‚āĻ°ā§āĻŖāϏāĻ‚āĻ–ā§āϝāĻž āĻŦāĻž āχāĻ¨ā§āϟāĻŋāϜāĻžāϰ āύ⧇āϝāĻŧ āĻāĻŦāĻ‚ āĻāĻ•āϟāĻŋ āχāĻ¨ā§āϟāĻŋāϜāĻžāϰ āĻĒā§āϰāĻĻāĻžāύ āĻ•āϰ⧇āĨ¤ āĻĢāĻžāĻ‚āĻļāύ " -"āĻĒāϰ⧇ āφāϰ⧋ āĻŦāĻŋāĻ¸ā§āϤāĻžāϰāĻŋāϤ āϚāĻ°ā§āϚāĻž āĻ•āϰāĻž āĻšāĻŦ⧇āĨ¤" #: src/types-and-values/arithmetic.md msgid "Arithmetic is very similar to other languages, with similar precedence." -msgstr "āĻāĻ•āχ āĻ…āĻ—ā§āϰāĻžāϧāĻŋāĻ•āĻžāϰ āϰ⧇āϖ⧇ āĻāĻ–āĻžāύ⧇ āĻĒāĻžāϟāĻŋāĻ—āĻŖāĻŋāϤ⧇āϰ āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āĻ­āĻžāώāĻžāϰ āϏāĻžāĻĨ⧇ āϖ⧁āĻŦ āĻŽāĻŋāϞāĨ¤" +msgstr "" #: src/types-and-values/arithmetic.md msgid "" "What about integer overflow? In C and C++ overflow of _signed_ integers is " -"actually undefined, and might do different things on different platforms or " -"compilers. In Rust, it's defined." +"actually undefined, and might do unknown things at runtime. In Rust, it's " +"defined." msgstr "" -"āχāĻ¨ā§āϟāĻŋāϜāĻžāϰ āĻ“āĻ­āĻžāϰāĻĢā§āϞ⧋ āĻšāϞ⧇? āϏāĻŋ āĻŦāĻž āϏāĻŋ++ -āĻ āϚāĻŋāĻšā§āύāĻŋāϤ āχāĻ¨ā§āϟāĻŋāϜāĻžāϰ āĻ“āĻ­āĻžāϰāĻĢā§āϞ⧋ āĻšāϞ⧇ āϤāĻžāϰ āĻŽā§āϝāĻžāύ " -"āĻ…āύāĻŋāĻ°ā§āϧāĻžāϰāĻŋāϤ āĻšā§Ÿā§‡ āĻāĻŦāĻ‚ āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āύ āĻĒā§āĻ˛ā§āϝāĻžāϟāĻĢāĻ°ā§āĻŽ āĻŦāĻž āĻ•āĻŽā§āĻĒāĻžāχāϞāĻžāϰ⧇ āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āύ āϜāĻŋāύāĻŋāϏ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĨ¤ āϰāĻžāĻ¸ā§āϟ āĻ " -"āϤāĻž āύāĻŋāĻ°ā§āϧāĻžāϰāĻŋāϤ āĻŽā§āϝāĻžāύ āύāĻŋā§Ÿā§‡ āĻĨāĻžāϕ⧇āĨ¤" #: src/types-and-values/arithmetic.md msgid "" @@ -3125,135 +4382,22 @@ msgid "" "with method syntax, e.g., `(a * b).saturating_add(b * c).saturating_add(c * " "a)`." msgstr "" -"āχāĻ¨ā§āϟāĻŋāϜāĻžāϰ āĻ“āĻ­āĻžāϰāĻĢā§āϞ⧋ āϏāϰāĻžāϏāϰāĻŋ āĻĻ⧇āĻ–āĻŦāĻžāϰ āϜāĻ¨ā§āϝ⧇ āϕ⧇ āĻ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰ⧇ āĻĻ⧇āϖ⧁āύāĨ¤ āĻĄāĻŋāĻŦāĻžāĻ— āĻ…āĻŦāĻ¸ā§āĻĨāĻžā§Ÿ " -"āύāĻŋāĻ°ā§āĻŽāĻŋāϤ āĻšāϞ⧇ āĻāϟāĻŋ āφāϤāĻ‚āĻ•āĻŋāϤ (āĻĒā§āϝāĻžāύāĻŋāĻ•) āĻšā§Ÿā§‡ āĻĒāϰ⧇ āĻāĻŦāĻ‚ āĻŽā§āĻ•ā§āϤāĻŋāĻ—āĻžāĻŽā§€ āύāĻŋāĻ°ā§āĻŽāĻžāĻŖ āĻšāϞ⧇ āϏ⧇āϟāĻŋ āĻŽā§ā§œāĻŋā§Ÿā§‡ " -"āĻĻ⧇āĻ“ā§ŸāĻž āĻšā§Ÿā§‡ āύāĻŋāĻœā§‡ āύāĻŋāĻœā§‡āχāĨ¤ āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āĻŦāĻŋāĻ•āĻ˛ā§āĻĒāĻ“ āφāϛ⧇ āϝ⧇āĻŽāύ āĻ“āĻ­āĻžāϰāĻĢā§āϞ⧋ (āĻŽā§āϝāĻžāύ āωāĻĒāĻšā§‡ āĻĒ⧜āĻž), " -"āĻ¸ā§āϝāĻžāϚ⧁āϰ⧇āϟāĻŋāĻ‚ (āĻŦāĻž āĻĒāϰāĻŋāĻĒ⧃āĻ•ā§āϤ āĻ•āϰāĻž) āĻāĻŦāĻ‚ āĻ•ā§āϝāĻžāϰāĻŋāĻ‚ (āĻŦāĻž āĻŦāĻšāύ āĻ•āϰāĻž)āĨ¤ āĻāϗ⧁āϞāĻŋ āĻ…āĻ­āĻŋāĻ—āĻŽāύ āĻ•āϰāĻŦāĻžāϰ āϜāĻ¨ā§āϝ⧇ " -"āĻāϰāĻ–āĻŽ āϕ⧋āύ⧋ āĻŽā§‡āĻĨāĻĄ āϏāĻŋāύāĻŸā§‡āĻ•ā§āϏ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻšāĻŦ⧇ `(a * b).saturating_add(b * c)." -"saturating_add(c * a)`āĨ¤" #: src/types-and-values/arithmetic.md msgid "" "In fact, the compiler will detect overflow of constant expressions, which is " "why the example requires a separate function." msgstr "" -"āĻĒā§āϰāĻ•ā§ƒāϤāĻĒāĻ•ā§āώ⧇, āĻ•āĻŽā§āĻĒāĻžāχāϞāĻžāϰ āĻ§ā§āϰ⧁āĻŦāĻ• āĻ…āĻ­āĻŋāĻŦā§āϝāĻ•ā§āϤāĻŋāϰ āĻ“āĻ­āĻžāϰāĻĢā§āϞ⧋ āϏāύāĻžāĻ•ā§āϤ āĻ•āϰāĻŦ⧇, āϝāĻžāϰ āĻ•āĻžāϰāϪ⧇ āωāĻĻāĻžāĻšāϰāĻŖāϟāĻŋāϰ " -"āϜāĻ¨ā§āϝ āĻāĻ•āϟāĻŋ āφāϞāĻžāĻĻāĻž āĻĢāĻžāĻ‚āĻļāύ āĻĒā§āϰāϝāĻŧā§‹āϜāύāĨ¤" - -#: src/types-and-values/strings.md -msgid "" -"Rust has two types to represent strings, both of which will be covered in " -"more depth later. Both _always_ store UTF-8 encoded strings." -msgstr "" -"āĻ¸ā§āĻŸā§āϰāĻŋāĻ‚āϗ⧁āϞāĻŋāϕ⧇ āωāĻĒāĻ¸ā§āĻĨāĻžāĻĒāύ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ āϰāĻžāĻ¸ā§āϟ āĻ āĻĻ⧁āϟāĻŋ āωāĻĒāĻžā§Ÿā§‡ āφāϛ⧇, āωāĻ­āϝāĻŧāχ āĻĒāϰāĻŦāĻ°ā§āϤ⧀āϤ⧇ āφāϰāĻ“ āĻ—āĻ­ā§€āϰāϤāĻžāϝāĻŧ " -"āĻ•āĻ­āĻžāϰ āĻ•āϰāĻž āĻšāĻŦ⧇āĨ¤ āωāĻ­āϝāĻŧāχ _āϏāĻŦāϏāĻŽā§Ÿā§‡_ āχāω.āϟāĻŋ.āĻāĻĢ-ā§Ž āĻāύāϕ⧋āĻĄ āĻ•āϰ⧇ āĻ¸ā§āĻŸā§āϰāĻŋāĻ‚ āϏāĻ‚āϰāĻ•ā§āώāĻŖ āĻ•āϰ⧇āĨ¤" - -#: src/types-and-values/strings.md -msgid "`String` - a modifiable, owned string." -msgstr "`String` - āĻāĻ•āϟāĻŋ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύāϝ⧋āĻ—ā§āϝ, āĻŽāĻžāϞāĻŋāĻ•āĻžāύāĻžāϧ⧀āύ āĻ¸ā§āĻŸā§āϰāĻŋāĻ‚āĨ¤" - -#: src/types-and-values/strings.md -msgid "`&str` - a read-only string. String literals have this type." -msgstr "`&str` - āĻāĻ•āϟāĻŋ āĻĒāĻ āύāϝ⧋āĻ—ā§āϝ āĻ¸ā§āĻŸā§āϰāĻŋāĻ‚āĨ¤ āĻ¸ā§āĻŸā§āϰāĻŋāĻ‚ āϞāĻŋāϟāĻžāϰ⧇āϞ⧇ āĻāχ āϧāϰāύ āφāϛ⧇āĨ¤" - -#: src/types-and-values/strings.md -msgid "\"Greetings\"" -msgstr "\"Greetings\"" - -#: src/types-and-values/strings.md -msgid "\"đŸĒ\"" -msgstr "\"đŸĒ\"" - -#: src/types-and-values/strings.md -msgid "\", \"" -msgstr "\", \"" - -#: src/types-and-values/strings.md -msgid "\"final sentence: {}\"" -msgstr "\"final sentence: {}\"" - -#: src/types-and-values/strings.md -#: src/methods-and-traits/traits/associated-types.md -#: src/async/control-flow/join.md -msgid "\"{:?}\"" -msgstr "\"{:?}\"" - -#: src/types-and-values/strings.md -msgid "//println!(\"{:?}\", &sentence[12..13]);" -msgstr "//println!(\"{:?}\", &sentence[12..13]);" - -#: src/types-and-values/strings.md -msgid "" -"This slide introduces strings. Everything here will be covered in more depth " -"later, but this is enough for subsequent slides and exercises to use strings." -msgstr "" -"āĻāχ āĻ¸ā§āϞāĻžāχāĻĄ āĻ¸ā§āĻŸā§āϰāĻŋāĻ‚ āĻ•āĻŋ āϜāĻŋāύāĻŋāϏ āĻāϟāĻž āĻĻ⧇āĻ–āĻžā§ŸāĨ¤ āĻāĻ–āĻžāύ⧇ āϏāĻŦāĻ•āĻŋāϛ⧁ āĻĒāϰ⧇ āφāϰāĻ“ āĻ—āĻ­ā§€āϰāϤāĻžāϝāĻŧ āĻ•āĻ­āĻžāϰ āĻ•āϰāĻž āĻšāĻŦ⧇, " -"āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻ¸ā§āĻŸā§āϰāĻŋāĻ‚ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻžāϰ āϜāĻ¨ā§āϝ,āĻĒāϰāĻŦāĻ°ā§āϤ⧀ āĻ¸ā§āϞāĻžāχāĻĄā§‡āϰ āϜāĻ¨ā§āϝ⧇ āĻāĻŦāĻ‚ āĻ…āύ⧁āĻļā§€āϞāύ⧇āϰ āϜāĻ¨ā§āϝ āĻāϟāĻŋ āϝāĻĨ⧇āĻˇā§āϟāĨ¤" - -#: src/types-and-values/strings.md -msgid "Invalid UTF-8 in a string is UB, and this not allowed in safe Rust." -msgstr "" -"UB āĻāĻ•āϟāĻŋ āχāω.āϟāĻŋ.āĻāĻĢ-ā§Ž āĻ¸ā§āĻŸā§āϰāĻŋāĻ‚-āĻ āĻĨāĻžāĻ•āĻž āϭ⧁āϞ āĻāĻŦāĻ‚ āϏ⧇āχ āϜāĻ¨ā§āϝ⧇ āĻāϟāĻŋ āύāĻŋāϰāĻžāĻĒāĻĻ āϰāĻžāĻ¸ā§āϟ āĻāϰ āϭ⧇āϤāϰ⧇ " -"āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āϝāĻžā§Ÿ āύāĻžāĨ¤" - -#: src/types-and-values/strings.md -msgid "" -"`String` is a user-defined type with a constructor (`::new()`) and methods " -"like `s.push_str(..)`." -msgstr "" -"`String` āĻšāĻšā§āϛ⧇ āĻ•āύāĻ¸ā§āĻŸā§āϰāĻžāĻ•ā§āϟāϰ (`::new()`) āϏāĻš āĻāĻ•āϟāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀-āϏāĻ‚āĻœā§āĻžāĻžāϝāĻŧāĻŋāϤ āĻĒā§āϰāĻ•āĻžāϰ āĻāĻŦāĻ‚ " -"āĻāϤ⧇ `s.push_str(..)` -āϰ āĻŽāϤāύ āĻŽā§‡āĻĨāĻĄ āĻ“ āĻ°ā§Ÿā§‡āϛ⧇āĨ¤" - -#: src/types-and-values/strings.md -msgid "" -"The `&` in `&str` indicates that this is a reference. We will cover " -"references later, so for now just think of `&str` as a unit meaning \"a read-" -"only string\"." -msgstr "" -"`&str` āĻāϟāĻž āϝ⧇ āĻāĻ•āϟāĻž āϰ⧇āĻĢāĻžāϰ⧇āĻ¨ā§āϏ āϏ⧇āϟāĻž āĻāϟāĻžāϤ⧇ āĻĨāĻžāĻ•āĻž `&` āĻĻāĻŋā§Ÿā§‡ āĻŦā§‹āĻāĻž āϝāĻžāĻšā§āϛ⧇āĨ¤ āφāĻŽāϰāĻž āĻĒāϰ⧇ " -"āϰ⧇āĻĢāĻžāϰ⧇āĻ¨ā§āϏ āĻĻ⧇āĻ–āĻŦā§‹ , āϤāĻžāχ āφāĻĒāĻžāϤāϤ āĻļ⧁āϧ⧁ `&str` āϕ⧇ āĻāĻ•āϟāĻŋ āχāωāύāĻŋāϟ āĻšāĻŋāϏ⧇āĻŦ⧇ āĻ­āĻžāĻŦ⧁āύ āϝāĻžāϰ āĻ…āĻ°ā§āĻĨ \"āĻāĻŽāύ " -"āĻāĻ•āϟāĻŋ āĻ¸ā§āĻŸā§āϰāĻŋāĻ‚ āϝāĻž āĻļ⧁āϧ⧁ āĻĒāĻ āύāϝ⧋āĻ—ā§āϝ \"āĨ¤" - -#: src/types-and-values/strings.md -msgid "" -"The commented-out line is indexing into the string by byte position. " -"`12..13` does not end on a character boundary, so the program panics. Adjust " -"it to a range that does, based on the error message." -msgstr "" -"āĻ•āĻŽā§‡āĻ¨ā§āϟ āĻ•āϰāĻž āϞāĻžāχāύ āĻŦāĻžāχāϟ āĻ…āĻŦāĻ¸ā§āĻĨāĻžāύ āĻĻā§āĻŦāĻžāϰāĻž āĻ¸ā§āĻŸā§āϰāĻŋāĻ‚ āĻŽāĻ§ā§āϝ⧇ āχāύāĻĄā§‡āĻ•ā§āϏ āĻ•āϰāϛ⧇āĨ¤ `12..13` āϏ⧀āĻŽāĻžāύāĻžāϝāĻŧ " -"āĻĒā§œā§‡ āύāĻž, āϤāĻžāχ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽ āφāϤāĻ™ā§āĻ•āĻŋāϤ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻĒā§āϰāĻĻāĻ°ā§āĻļāύ āĻ•āϰ⧇āĨ¤ āĻ¤ā§āϰ⧁āϟāĻŋ āĻŦāĻžāĻ°ā§āϤāĻžāϰ āωāĻĒāϰ āĻ­āĻŋāĻ¤ā§āϤāĻŋ āĻ•āϰ⧇ " -"āĻāϟāĻŋāϕ⧇ āĻāĻ•āϟāĻŋ āϏāĻ āĻŋāĻ• āϏ⧀āĻŽāĻžāύāĻžāϰ āĻŽāĻ§ā§āϝ⧇ āύāĻŋā§Ÿā§‡ āφāϏ⧁āύāĨ¤" - -#: src/types-and-values/strings.md -msgid "" -"Raw strings allow you to create a `&str` value with escapes disabled: " -"`r\"\\n\" == \"\\\\n\"`. You can embed double-quotes by using an equal " -"amount of `#` on either side of the quotes:" -msgstr "" -"Raw strings allow you to create a `&str` value with escapes disabled: " -"`r\"\\n\" == \"\\\\n\"`. You can embed double-quotes by using an equal " -"amount of `#` on either side of the quotes:" - -#: src/types-and-values/strings.md -msgid "" -"Using `{:?}` is a convenient way to print array/vector/struct of values for " -"debugging purposes, and it's commonly used in code." -msgstr "" -"`{:?}` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āĻĄāĻŋāĻŦāĻžāĻ—āĻŋāĻ‚ āωāĻĻā§āĻĻ⧇āĻļā§āϝ⧇ āĻŽāĻžāύāϗ⧁āϞāĻŋāϰ āĻ…ā§āϝāĻžāϰ⧇/āϭ⧇āĻ•ā§āϟāϰ/āĻ¸ā§āĻŸā§āϰāĻžāĻ•āϟ āĻĒā§āϰāĻŋāĻ¨ā§āϟ āĻ•āϰāĻžāϰ āĻāĻ•āϟāĻŋ " -"āϏ⧁āĻŦāĻŋāϧāĻžāϜāύāĻ• āωāĻĒāĻžāϝāĻŧ āĻāĻŦāĻ‚ āĻāϟāĻŋ āϏāĻžāϧāĻžāϰāĻŖāϤ āĻ…āύ⧇āĻ• āϕ⧋āĻĄā§‡ āĻŦā§āϝāĻŦāĻšā§ƒāϤ āĻšāϝāĻŧāĨ¤" #: src/types-and-values/inference.md msgid "Rust will look at how the variable is _used_ to determine the type:" msgstr "" -"āĻāĻ•āϟāĻŋ āĻ­ā§āϝāĻžāϰāĻŋā§Ÿā§‡āĻŦāϞ āĻ•āĻŋāĻ­āĻžāĻŦ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āĻšāĻšā§āϛ⧇ āϤāĻž āĻĻ⧇āϖ⧇ āϰāĻžāĻ¸ā§āϟ āϏ⧇āϟāĻŋāϰ āϟāĻžāχāĻĒ āĻ āĻŋāĻ• āĻ•āϰāĻŦ⧇:" #: src/types-and-values/inference.md msgid "" "This slide demonstrates how the Rust compiler infers types based on " "constraints given by variable declarations and usages." msgstr "" -"āĻāχ āĻ¸ā§āϞāĻžāχāĻĄāϟāĻŋ āĻĻ⧇āĻ–āĻžāϝāĻŧ āϝ⧇ āϕ⧀āĻ­āĻžāĻŦ⧇ āϰāĻžāĻ¸ā§āĻŸā§‡āϰ āĻ•āĻŽā§āĻĒāĻžāχāϞāĻžāϰ āĻāĻ•āϟāĻŋ āĻ­ā§āϝāĻžāϰāĻŋā§Ÿā§‡āĻŦāϞ⧇āϰ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύāĻļā§€āϞ āĻ˜ā§‹āώāĻŖāĻž " -"āĻāĻŦāĻ‚ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻĻā§āĻŦāĻžāϰāĻž āϏ⧀āĻŽāĻžāĻŦāĻĻā§āϧāϤāĻžāϰ āωāĻĒāϰ āĻ­āĻŋāĻ¤ā§āϤāĻŋ āĻ•āϰ⧇ āϏ⧇āϟāĻŋāϰ āϟāĻžāχāĻĒ āĻ…āύ⧁āĻŽāĻžāύ āĻ•āϰ⧇āĨ¤" #: src/types-and-values/inference.md msgid "" @@ -3263,10 +4407,6 @@ msgid "" "of a type. The compiler does the job for us and helps us write more concise " "code." msgstr "" -"āĻāϟāĻž āĻœā§‹āϰ āĻĻ⧇āĻ“āϝāĻŧāĻž āϖ⧁āĻŦāχ āϗ⧁āϰ⧁āĻ¤ā§āĻŦāĻĒā§‚āĻ°ā§āĻŖ āϝ⧇ āĻāχāϰāĻ•āĻŽ āĻ˜ā§‹āώāĻŋāϤ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞāϗ⧁āϞāĻŋ āϕ⧋āύ āϧāϰāϪ⧇āϰ āĻĄāĻžāχāύāĻžāĻŽāĻŋāĻ• " -"\"āϝ⧇āϕ⧋āύ āϧāϰāϪ⧇āϰ\" āύāϝāĻŧ āϝāĻž āϕ⧋āύāĻ“ āĻĄā§‡āϟāĻž āϧāĻžāϰāĻŖ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ āĻāχ āϧāϰāύ⧇āϰ āĻ˜ā§‹āώāĻŖāĻž āĻĻā§āĻŦāĻžāϰāĻž āωāĻ¤ā§āĻĒāĻ¨ā§āύ " -"āĻŽā§‡āĻļāĻŋāύ āϕ⧋āĻĄ āĻāĻ•āϟāĻŋ āϟāĻžāχāĻĒ-āĻāϰ āϏ⧁āĻ¸ā§āĻĒāĻˇā§āϟ āĻ˜ā§‹āώāĻŖāĻžāϰ āĻ…āύ⧁āϰ⧂āĻĒāĨ¤ āĻ•āĻŽā§āĻĒāĻžāχāϞāĻžāϰ āφāĻŽāĻžāĻĻ⧇āϰ āϜāĻ¨ā§āϝ āĻāχ āĻ•āĻžāϜ āĻ•āϰ⧇ āĻāĻŦāĻ‚ " -"āφāĻŽāĻžāĻĻ⧇āϰ āφāϰāĻ“ āϏāĻ‚āĻ•ā§āώāĻŋāĻĒā§āϤ āϕ⧋āĻĄ āϞāĻŋāĻ–āϤ⧇ āϏāĻžāĻšāĻžāĻ¯ā§āϝ āĻ•āϰ⧇āĨ¤" #: src/types-and-values/inference.md msgid "" @@ -3274,127 +4414,265 @@ msgid "" "`i32`. This sometimes appears as `{integer}` in error messages. Similarly, " "floating-point literals default to `f64`." msgstr "" -"āϝāĻ–āύ āϕ⧋āύ āĻ•āĻŋāϛ⧁āχ āĻĒā§‚āĻ°ā§āĻŖāϏāĻ‚āĻ–ā§āϝāĻžāϰ āφāĻ•ā§āώāϰāĻŋāϕ⧇āϰ āϧāϰāĻŖāϕ⧇ āĻŦāĻžāϧāĻž āĻĻ⧇āϝāĻŧ āύāĻž, āϤāĻ–āύ āϰāĻžāĻ¸ā§āϟ āϏ⧇āϟāĻžāϕ⧇ `i32` " -"āĻšāĻŋāϏāĻžāĻŦ⧇ āϭ⧇āĻŦ⧇ āύāĻŋā§Ÿā§‡ āĻ•āĻžāϜ āĻ•āϰ⧇āĨ¤ āĻāϟāĻŋ āĻ•āĻ–āύāĻ“ āĻ•āĻ–āύāĻ“ āĻ¤ā§āϰ⧁āϟāĻŋ āĻŦāĻžāĻ°ā§āϤāĻžāϗ⧁āϞāĻŋāϤ⧇ `{integer}` āĻšāĻŋāϏāĻžāĻŦ⧇ " -"āĻĒā§āϰāĻĻāĻ°ā§āĻļāĻŋāϤ āĻšāϝāĻŧāĨ¤ āĻāĻ•āχāĻ­āĻžāĻŦ⧇, āĻĢā§āϞ⧋āϟāĻŋāĻ‚-āĻĒāϝāĻŧ⧇āĻ¨ā§āϟ āϞāĻŋāϟāĻžāϰāĻžāϞ āϕ⧇ `f64` āĻ āϭ⧇āĻŦ⧇ āύ⧇āĻ“ā§ŸāĻž āĻšā§Ÿā§‡āĨ¤" #: src/types-and-values/inference.md -msgid "// ERROR: no implementation for `{float} == {integer}`" -msgstr "// ERROR: no implementation for `{float} == {integer}`" - -#: src/types-and-values/exercise.md -msgid "" -"The first and second Fibonacci numbers are both `1`. For n>2, the n'th " -"Fibonacci number is calculated recursively as the sum of the n-1'th and " -"n-2'th Fibonacci numbers." +msgid "// ERROR: no implementation for `{float} == {integer}`\n" msgstr "" -"āĻĒā§āϰāĻĨāĻŽ āĻāĻŦāĻ‚ āĻĻā§āĻŦāĻŋāϤ⧀āϝāĻŧ āĻĢāĻŋāĻŦā§‹āύāĻžāĻšā§āϚāĻŋ āϏāĻ‚āĻ–ā§āϝāĻž āωāĻ­āϝāĻŧāχ `1`āĨ¤ n>⧍ āĻāϰ āϜāĻ¨ā§āϝ, n'āϤāĻŽ āĻĢāĻŋāĻŦā§‹āύāĻžāĻšā§āϚāĻŋ āϏāĻ‚āĻ–ā§āϝāĻžāϟāĻŋ " -"n-ā§§ āĻāĻŦāĻ‚ n-⧍'āϤāĻŽ āĻĢāĻŋāĻŦā§‹āύāĻžāĻšā§āϚāĻŋ āϏāĻ‚āĻ–ā§āϝāĻžāϰ āϝ⧋āĻ—āĻĢāϞ āĻšāĻŋāϏāĻžāĻŦ⧇ āĻĒ⧁āύāϰāĻžāĻŦ⧃āĻ¤ā§āϤāĻ­āĻžāĻŦ⧇ āĻ—āĻŖāύāĻž āĻ•āϰāĻž āĻšāϝāĻŧāĨ¤" #: src/types-and-values/exercise.md msgid "" -"Write a function `fib(n)` that calculates the n'th Fibonacci number. When " +"The Fibonacci sequence begins with `[0, 1]`. For `n > 1`, the next number is " +"the sum of the previous two." +msgstr "" + +#: src/types-and-values/exercise.md +msgid "" +"Write a function `fib(n)` that calculates the nth Fibonacci number. When " "will this function panic?" msgstr "" -"āĻāĻ•āϟāĻŋ āĻĢāĻžāĻ‚āĻļāύ āϞāĻŋāϖ⧁āύ `fib(n)` āϝāĻž n'th āĻĢāĻŋāĻŦā§‹āύāĻžāĻšā§āϚāĻŋ āϏāĻ‚āĻ–ā§āϝāĻž āĻ—āĻŖāύāĻž āĻ•āϰ⧇āĨ¤ āĻ•āĻ–āύ āĻāχ āĻĢāĻžāĻ‚āĻļāύ " -"āĻĒā§āϝāĻžāύāĻŋāĻ• āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇?" #: src/types-and-values/exercise.md -msgid "// The base case." -msgstr "// The base case." +msgid "// The base case.\n" +msgstr "" #: src/types-and-values/exercise.md src/control-flow-basics/exercise.md msgid "\"Implement this\"" -msgstr "\"Implement this\"" +msgstr "" #: src/types-and-values/exercise.md -msgid "// The recursive case." -msgstr "// The recursive case." +msgid "// The recursive case.\n" +msgstr "" #: src/types-and-values/exercise.md src/types-and-values/solution.md -msgid "\"fib(n) = {}\"" -msgstr "\"fib(n) = {}\"" - -#: src/control-flow-basics.md -msgid "[if Expressions](./control-flow-basics/if.md) (4 minutes)" -msgstr "[if āĻ…āĻ­āĻŋāĻŦā§āϝāĻ•ā§āϤāĻŋ](./control-flow-basics/if.md) (ā§Ē āĻŽāĻŋāύāĻŋāϟ)" - -#: src/control-flow-basics.md -msgid "[Loops](./control-flow-basics/loops.md) (5 minutes)" -msgstr "[āϞ⧁āĻĒ](./control-flow-basics/loops.md) (ā§Ģ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/control-flow-basics.md -msgid "" -"[break and continue](./control-flow-basics/break-continue.md) (4 minutes)" +msgid "\"fib({n}) = {}\"" +msgstr "" + +#: src/types-and-values/exercise.md +msgid "This exercise is a classic introduction to recursion." +msgstr "" + +#: src/types-and-values/exercise.md +msgid "" +"Encourage students to think about the base cases and the recursive step." +msgstr "" + +#: src/types-and-values/exercise.md +msgid "" +"The question \"When will this function panic?\" is a hint to think about " +"integer overflow. The Fibonacci sequence grows quickly!" +msgstr "" + +#: src/types-and-values/exercise.md +msgid "" +"Students might come up with an iterative solution as well, which is a great " +"opportunity to discuss the trade-offs between recursion and iteration (e.g., " +"performance, stack overflow for deep recursion)." +msgstr "" + +#: src/types-and-values/solution.md +msgid "" +"We use the `return` syntax here to return values from the function. Later in " +"the course, we will see that the last expression in a block is automatically " +"returned, allowing us to omit the `return` keyword for a more concise style." +msgstr "" + +#: src/types-and-values/solution.md +msgid "" +"The `if` condition `n < 2` does not need parentheses, which is standard Rust " +"style." +msgstr "" + +#: src/types-and-values/solution.md +msgid "Panic" +msgstr "" + +#: src/types-and-values/solution.md +msgid "" +"The exercise asks when this function will panic. The Fibonacci sequence " +"grows very rapidly. With `u32`, the calculated values will overflow the 32-" +"bit integer limit (4,294,967,295) when `n` reaches 48." +msgstr "" + +#: src/types-and-values/solution.md +msgid "" +"In Rust, integer arithmetic checks for overflow in _debug mode_ (which is " +"the default when using `cargo run`). If an overflow occurs, the program will " +"panic (crash with an error message). In _release mode_ (`cargo run --" +"release`), overflow checks are disabled by default, and the number will wrap " +"around (modular arithmetic), producing incorrect results." +msgstr "" + +#: src/types-and-values/solution.md +msgid "Walk through the solution step-by-step." +msgstr "" + +#: src/types-and-values/solution.md +msgid "Explain the recursive calls and how they lead to the final result." +msgstr "" + +#: src/types-and-values/solution.md +msgid "" +"Discuss the integer overflow issue. With `u32`, the function will panic for " +"`n` around 47. You can demonstrate this by changing the input to `main`." +msgstr "" + +#: src/types-and-values/solution.md +msgid "" +"Show an iterative solution as an alternative and compare its performance and " +"memory usage with the recursive one. An iterative solution will be much more " +"efficient." +msgstr "" + +#: src/types-and-values/solution.md src/control-flow-basics/match.md +#: src/references/dangling.md src/user-defined-types/named-structs.md +#: src/user-defined-types/enums.md src/user-defined-types/static.md +#: src/pattern-matching/infallible.md +#: src/pattern-matching/destructuring-structs.md +#: src/pattern-matching/let-control-flow/let-else.md src/closures/syntax.md +#: src/memory-management/review.md src/memory-management/move.md +#: src/memory-management/copy-types.md src/borrowing/shared.md +#: src/borrowing/borrowck.md src/borrowing/interior-mutability/refcell.md +#: src/lifetimes/borrow-one.md src/iterators/motivation.md +#: src/iterators/iterator.md src/iterators/helpers.md src/iterators/collect.md +#: src/modules/encapsulation.md src/error-handling/result.md +#: src/error-handling/anyhow.md src/concurrency/async/state-machine.md +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md +#: src/idiomatic/leveraging-the-type-system/raii.md +#: src/idiomatic/leveraging-the-type-system/raii/drop_guards.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +#: src/idiomatic/leveraging-the-type-system/token-types/branded-04-in-action.md +msgid "More to Explore" +msgstr "" + +#: src/types-and-values/solution.md +msgid "" +"For a more advanced discussion, you can introduce memoization or dynamic " +"programming to optimize the recursive Fibonacci calculation, although this " +"is beyond the scope of the current topic." +msgstr "" + +#: src/control-flow-basics.md src/methods-and-traits.md src/modules.md +#: src/testing.md +msgid "This segment should take about 45 minutes. It contains:" +msgstr "" + +#: src/control-flow-basics.md +msgid "if Expressions" +msgstr "" + +#: src/control-flow-basics.md src/pattern-matching.md src/concurrency/async.md +#: src/concurrency/async-control-flow.md +msgid "4 minutes" +msgstr "" + +#: src/control-flow-basics.md +msgid "match Expressions" +msgstr "" + +#: src/control-flow-basics.md +msgid "break and continue" +msgstr "" + +#: src/control-flow-basics.md +msgid "We will now cover the many kinds of flow control found in Rust." msgstr "" -"[break āĻāĻŦāĻ‚ continue](./control-flow-basics/break-continue.md) (ā§Ē āĻŽāĻŋāύāĻŋāϟ)" #: src/control-flow-basics.md msgid "" -"[Blocks and Scopes](./control-flow-basics/blocks-and-scopes.md) (5 minutes)" -msgstr "[āĻŦā§āϞāĻ• āĻāĻŦāĻ‚ āĻ¸ā§āϕ⧋āĻĒ](./control-flow-basics/blocks-and-scopes.md) (ā§Ģ āĻŽāĻŋāύāĻŋāϟ)" +"Most of this will be very familiar to what you have seen in other " +"programming languages." +msgstr "" -#: src/control-flow-basics.md -msgid "[Functions](./control-flow-basics/functions.md) (3 minutes)" -msgstr "[āĻĢāĻžāĻ‚āĻļāύ](./control-flow-basics/functions.md) (ā§Š āĻŽāĻŋāύāĻŋāϟ)" - -#: src/control-flow-basics.md -msgid "[Macros](./control-flow-basics/macros.md) (2 minutes)" -msgstr "[āĻŽā§āϝāĻžāĻ•ā§āϰ⧋](./control-flow-basics/macros.md) (⧍ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/control-flow-basics.md +#: src/control-flow-basics/blocks-and-scopes.md msgid "" -"[Exercise: Collatz Sequence](./control-flow-basics/exercise.md) (15 minutes)" -msgstr "[āĻ…āύ⧁āĻļā§€āϞāύ⧀: āĻ•āĻ˛ā§āϝāĻžāϟāϜ āĻāϰ āĻ•ā§āϰāĻŽ](./control-flow-basics/exercise.md) (ā§§ā§Ģ āĻŽāĻŋāύāĻŋāϟ)" +"A block in Rust contains a sequence of expressions, enclosed by braces `{}`." +msgstr "" -#: src/control-flow-basics.md src/generics.md src/modules.md -msgid "This segment should take about 40 minutes" -msgstr "āĻāχ āĻ…āĻ‚āĻļāϟāĻŋ āĻĒā§āϰāĻžāϝāĻŧ ā§Ēā§Ļ āĻŽāĻŋāύāĻŋāϟ āϏāĻŽāϝāĻŧ āύ⧇āĻŦ⧇" +#: src/control-flow-basics/blocks-and-scopes.md +msgid "" +"The final expression of a block determines the value and type of the whole " +"block." +msgstr "" + +#: src/control-flow-basics/blocks-and-scopes.md +msgid "// dbg!(y);\n" +msgstr "" + +#: src/control-flow-basics/blocks-and-scopes.md +msgid "" +"If the last expression ends with `;`, then the resulting value and type is " +"`()`." +msgstr "" + +#: src/control-flow-basics/blocks-and-scopes.md +msgid "A variable's scope is limited to the enclosing block." +msgstr "" + +#: src/control-flow-basics/blocks-and-scopes.md +msgid "" +"You can explain that dbg! is a Rust macro that prints and returns the value " +"of a given expression for quick and dirty debugging." +msgstr "" + +#: src/control-flow-basics/blocks-and-scopes.md +msgid "" +"You can show how the value of the block changes by changing the last line in " +"the block. For instance, adding/removing a semicolon or using a `return`." +msgstr "" + +#: src/control-flow-basics/blocks-and-scopes.md +msgid "" +"Demonstrate that attempting to access `y` outside of its scope won't compile." +msgstr "" + +#: src/control-flow-basics/blocks-and-scopes.md +msgid "" +"Values are effectively \"deallocated\" when they go out of their scope, even " +"if their data on the stack is still there." +msgstr "" #: src/control-flow-basics/if.md msgid "`if` expressions" -msgstr "`if` āĻ…āĻ­āĻŋāĻŦā§āϝāĻ•ā§āϤāĻŋ" +msgstr "" #: src/control-flow-basics/if.md msgid "" "You use [`if` expressions](https://doc.rust-lang.org/reference/expressions/" "if-expr.html#if-expressions) exactly like `if` statements in other languages:" msgstr "" -"[`if` āĻ…āĻ­āĻŋāĻŦā§āϝāĻ•ā§āϤāĻŋ](https://doc.rust-lang.org/reference/expressions/if-expr." -"html#if-expressions) āϰāĻžāĻ¸ā§āϟ āĻ āĻ āĻŋāĻ• āĻ…āĻ¨ā§āϝ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāĻŋāĻ‚ āĻ­āĻžāώāĻžāϰ `if` āĻ…āĻ­āĻŋāĻŦā§āϝāĻ•ā§āϤāĻŋāϰ āĻŽāϤāύ āĻšā§Ÿ " -"āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āĻšā§Ÿā§‡:" #: src/control-flow-basics/if.md msgid "\"zero!\"" -msgstr "\"zero!\"" +msgstr "" #: src/control-flow-basics/if.md msgid "\"biggish\"" -msgstr "\"biggish\"" +msgstr "" #: src/control-flow-basics/if.md msgid "\"huge\"" -msgstr "\"huge\"" +msgstr "" #: src/control-flow-basics/if.md msgid "" "In addition, you can use `if` as an expression. The last expression of each " "block becomes the value of the `if` expression:" msgstr "" -"āωāĻĒāϰāĻ¨ā§āϤ⧁, āφāĻĒāύāĻŋ `if` āϕ⧇āĻ“ āĻāĻ•āϟāĻŋ āĻ…āĻ­āĻŋāĻŦā§āϝāĻ•ā§āϤāĻŋ āĻšāĻŋāϏāĻžāĻŦ⧇ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤ āĻĒā§āϰāϤāĻŋāϟāĻŋ āĻŦā§āϞāϕ⧇āϰ " -"āĻļ⧇āώ āĻ…āĻ­āĻŋāĻŦā§āϝāĻ•ā§āϤāĻŋ `if` āĻ…āĻ­āĻŋāĻŦā§āϝāĻ•ā§āϤāĻŋāϰ āĻŽāĻžāύ āĻšāϝāĻŧ⧇ āϝāĻžāϝāĻŧ:" #: src/control-flow-basics/if.md msgid "\"small\"" -msgstr "\"small\"" +msgstr "" #: src/control-flow-basics/if.md msgid "\"large\"" -msgstr "\"large\"" +msgstr "" #: src/control-flow-basics/if.md msgid "\"number size: {}\"" -msgstr "\"number size: {}\"" +msgstr "" #: src/control-flow-basics/if.md msgid "" @@ -3402,27 +4680,103 @@ msgid "" "branch blocks must have the same type. Show what happens if you add `;` " "after `\"small\"` in the second example." msgstr "" -"āϝ⧇āĻšā§‡āϤ⧁ `if` āĻāĻ•āϟāĻŋ āĻ…āĻ­āĻŋāĻŦā§āϝāĻ•ā§āϤāĻŋ āĻāĻŦāĻ‚ āĻ…āĻŦāĻļā§āϝāχ āĻāϟāĻŋāϰ āĻāĻ•āϟāĻŋ āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ āϟāĻžāχāĻĒ āĻĨāĻžāĻ•āϤ⧇ āĻšāĻŦ⧇, āϤāĻžāχ āωāĻ­āϝāĻŧ " -"āĻļāĻžāĻ–āĻž āĻŦā§āϞāϕ⧇āϰ āĻāĻ•āχ āϟāĻžāχāĻĒ āĻĨāĻžāĻ•āϤ⧇ āĻšāĻŦ⧇āĨ¤ āĻĻā§āĻŦāĻŋāϤ⧀āϝāĻŧ āωāĻĻāĻžāĻšāϰāϪ⧇ `\"small\"` āĻāϰ āĻĒāϰ⧇ `;` āϝ⧋āĻ— " -"āĻ•āϰāϞ⧇ āĻ•āĻŋ āĻšāĻŦ⧇ āϤāĻž āĻĻ⧇āĻ–āĻžāύāĨ¤" #: src/control-flow-basics/if.md msgid "" -"When `if` is used in an expression, the expression must have a `;` to " -"separate it from the next statement. Remove the `;` before `println!` to see " -"the compiler error." +"An `if` expression should be used in the same way as the other expressions. " +"For example, when it is used in a `let` statement, the statement must be " +"terminated with a `;` as well. Remove the `;` before `println!` to see the " +"compiler error." +msgstr "" + +#: src/control-flow-basics/match.md +msgid "`match` can be used to check a value against one or more options:" +msgstr "" + +#: src/control-flow-basics/match.md +msgid "\"one\"" +msgstr "" + +#: src/control-flow-basics/match.md +msgid "\"ten\"" +msgstr "" + +#: src/control-flow-basics/match.md +msgid "\"one hundred\"" +msgstr "" + +#: src/control-flow-basics/match.md +msgid "\"something else\"" +msgstr "" + +#: src/control-flow-basics/match.md +msgid "Like `if` expressions, `match` can also return a value;" +msgstr "" + +#: src/control-flow-basics/match.md +msgid "\"The value of {flag} is {val}\"" +msgstr "" + +#: src/control-flow-basics/match.md +msgid "" +"`match` arms are evaluated from top to bottom, and the first one that " +"matches has its corresponding body executed." +msgstr "" + +#: src/control-flow-basics/match.md +msgid "" +"There is no fall-through between cases the way that `switch` works in other " +"languages." +msgstr "" + +#: src/control-flow-basics/match.md +msgid "" +"The body of a `match` arm can be a single expression or a block. Technically " +"this is the same thing, since blocks are also expressions, but students may " +"not fully understand that symmetry at this point." +msgstr "" + +#: src/control-flow-basics/match.md +msgid "" +"`match` expressions need to be exhaustive, meaning they either need to cover " +"all possible values or they need to have a default case such as `_`. " +"Exhaustiveness is easiest to demonstrate with enums, but enums haven't been " +"introduced yet. Instead we demonstrate matching on a `bool`, which is the " +"simplest primitive type." +msgstr "" + +#: src/control-flow-basics/match.md +msgid "" +"This slide introduces `match` without talking about pattern matching, giving " +"students a chance to get familiar with the syntax without front-loading too " +"much information. We'll be talking about pattern matching in more detail " +"tomorrow, so try not to go into too much detail here." +msgstr "" + +#: src/control-flow-basics/match.md +msgid "" +"To further motivate the usage of `match`, you can compare the examples to " +"their equivalents written with `if`. In the second case, matching on a " +"`bool`, an `if {} else {}` block is pretty similar. But in the first example " +"that checks multiple cases, a `match` expression can be more concise than " +"`if {} else if {} else if {} else`." +msgstr "" + +#: src/control-flow-basics/match.md +msgid "" +"`match` also supports match guards, which allow you to add an arbitrary " +"logical condition that will get evaluated to determine if the match arm " +"should be taken. However talking about match guards requires explaining " +"about pattern matching, which we're trying to avoid on this slide." msgstr "" -"āϝāĻ–āύ āĻāĻ•āϟāĻŋ āĻ…āĻ­āĻŋāĻŦā§āϝāĻ•ā§āϤāĻŋāϤ⧇ `if` āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āĻšāϝāĻŧ, āϤāĻ–āύ āĻ…āĻ­āĻŋāĻŦā§āϝāĻ•ā§āϤāĻŋāϟāĻŋāϰ āĻ…āĻŦāĻļā§āϝāχ āĻļ⧇āώ⧇ āĻāĻ•āϟāĻŋ `;` " -"āĻĨāĻžāĻ•āϤ⧇ āĻšāĻŦ⧇ āϝāĻž āĻĒāϰāĻŦāĻ°ā§āϤ⧀ āĻŦāĻŋāĻŦ⧃āϤāĻŋ āĻĨ⧇āϕ⧇ āϏ⧇āϟāĻŋāϕ⧇ āφāϞāĻžāĻĻāĻž āĻ•āϰāĻŦ⧇āĨ¤ āĻ•āĻŽā§āĻĒāĻžāχāϞāĻžāϰ āĻ¤ā§āϰ⧁āϟāĻŋ āĻĻ⧇āĻ–āϤ⧇ " -"`println!` āĻāϰ āφāϗ⧇ `;` āϏāϰāĻŋā§Ÿā§‡ āĻĻ⧇āϖ⧁āύāĨ¤" #: src/control-flow-basics/loops.md msgid "There are three looping keywords in Rust: `while`, `loop`, and `for`:" -msgstr "āϰāĻžāĻ¸ā§āĻŸā§‡ āϤāĻŋāύāϟāĻŋ āϞ⧁āĻĒāĻŋāĻ‚ āϕ⧀āĻ“āϝāĻŧāĻžāĻ°ā§āĻĄ āϰāϝāĻŧ⧇āϛ⧇: `while`, `loop`, āĻ“ `for`:" +msgstr "" #: src/control-flow-basics/loops.md msgid "`while`" -msgstr "`while`" +msgstr "" #: src/control-flow-basics/loops.md msgid "" @@ -3430,25 +4784,12 @@ msgid "" "expr.html#predicate-loops) works much like in other languages, executing the " "loop body as long as the condition is true." msgstr "" -"[`while` āϕ⧀āĻ“ā§ŸāĻžāĻ°ā§āĻĄ](https://doc.rust-lang.org/reference/expressions/loop-expr." -"html#predicate-loops) āϰāĻžāĻ¸ā§āϟ āĻ āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āĻ­āĻžāώāĻžāϰ `while` āϕ⧀āĻ“ā§ŸāĻžāĻ°ā§āĻĄ āĻāϰ āĻŽāϤ⧋āχ āĻ•āĻžāϜ āĻ•āϰ⧇, " -"āϝāϤāĻ•ā§āώāĻŖ āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āĻļāĻ°ā§āϤāϟāĻŋ āϏāĻ¤ā§āϝ āĻšāϝāĻŧ āϤāϤāĻ•ā§āώāĻŖ āϞ⧁āĻĒ āĻŦāĻĄāĻŋ āĻ•āĻžāĻ°ā§āϝāĻ•āϰ āĻ•āϰ⧇āĨ¤" - -#: src/control-flow-basics/loops.md -msgid "\"Final x: {x}\"" -msgstr "\"Final x: {x}\"" #: src/control-flow-basics/loops/for.md msgid "" "The [`for` loop](https://doc.rust-lang.org/std/keyword.for.html) iterates " "over ranges of values or the items in a collection:" msgstr "" -"[`for` āϞ⧁āĻĒ](https://doc.rust-lang.org/std/keyword.for.html) āĻāĻ•āϟāĻŋ āĻŽāĻžāύ⧇āϰ " -"āĻĒāϰāĻŋāϏ⧀āĻŽāĻž āĻŦāĻž āϏāĻ‚āĻ—ā§āϰāĻšā§‡āϰ āφāχāĻŸā§‡āĻŽāϗ⧁āϞāĻŋāϰ āωāĻĒāϰ āĻĒ⧁āύāϰāĻžāĻŦ⧃āĻ¤ā§āϤāĻŋ āĻ•āϰ⧇:" - -#: src/control-flow-basics/loops/for.md -msgid "\"elem: {elem}\"" -msgstr "\"elem: {elem}\"" #: src/control-flow-basics/loops/for.md msgid "" @@ -3456,186 +4797,66 @@ msgid "" "iterating over different kinds of ranges/collections. Iterators will be " "discussed in more detail later." msgstr "" -"`āĻĢāϰ` āϞ⧁āĻĒāϗ⧁āϞāĻŋ āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āύ āϧāϰāϪ⧇āϰ āϰ⧇āĻžā§āϜ/āϏāĻ‚āĻ—ā§āϰāĻšā§‡āϰ āĻĒ⧁āύāϰāĻžāĻŦ⧃āĻ¤ā§āϤāĻŋ āĻĒāϰāĻŋāϚāĻžāϞāύāĻž āĻ•āϰāϤ⧇ \"āχāϟāĻžāϰ⧇āϟāϰ\" āύāĻžāĻŽāĻ• " -"āĻāĻ•āϟāĻŋ āϧāĻžāϰāĻŖāĻž āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇āĨ¤ āχāϟāĻžāϰ⧇āϟāϰ āĻĒāϰ⧇ āφāϰāĻ“ āĻŦāĻŋāĻļāĻĻ⧇ āφāϞ⧋āϚāύāĻž āĻ•āϰāĻž āĻšāĻŦ⧇āĨ¤" #: src/control-flow-basics/loops/for.md msgid "" -"Note that the `for` loop only iterates to `4`. Show the `1..=5` syntax for " -"an inclusive range." +"Note that the first `for` loop only iterates to `4`. Show the `1..=5` syntax " +"for an inclusive range." msgstr "" -"āχāϟāĻž āϞāĻ•ā§āĻˇā§āϝ āĻ•āϰāĻž āĻĻāϰāĻ•āĻžāϰ āϝ⧇ `for` -āϟāĻŋ āϞ⧁āĻĒ āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ `4` āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āĻĒ⧁āύāϰāĻžāĻŦ⧃āĻ¤ā§āϤāĻŋ āĻ•āϰ⧇āĨ¤ āĻāĻ–āĻžāύ⧇ `5` " -"āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āĻĒ⧁āύāϰāĻžāĻŦ⧃āĻ¤ā§āϤāĻŋ āĻ•āϰāĻŦāĻžāϰ āϜāĻ¨ā§āϝ⧇ `1..=5` āĻ—āĻ āύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āĻĻāϰāĻ•āĻžāϰāĨ¤" #: src/control-flow-basics/loops/loop.md msgid "" "The [`loop` statement](https://doc.rust-lang.org/std/keyword.loop.html) just " "loops forever, until a `break`." msgstr "" -"`break` āύāĻž āĻĒāĻžāĻ“ā§ŸāĻž āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āĻĒ⧁āύāϰāĻžāĻŦ⧃āĻ¤ā§āϤāĻŋ āĻ•āϰāϤ⧇āχ āĻĨāĻžāϕ⧇ āĻāĻ•āϟāĻŋ [`loop` statement](https://" -"doc.rust-lang.org/std/keyword.loop.html)āĨ¤" #: src/control-flow-basics/loops/loop.md -msgid "\"{i}\"" -msgstr "\"{i}\"" +msgid "" +"The `loop` statement works like a `while true` loop. Use it for things like " +"servers that will serve connections forever." +msgstr "" #: src/control-flow-basics/break-continue.md msgid "" "If you want to immediately start the next iteration use [`continue`](https://" "doc.rust-lang.org/reference/expressions/loop-expr.html#continue-expressions)." msgstr "" -"āφāĻĒāύāĻŋ āĻ…āĻŦāĻŋāϞāĻŽā§āĻŦ⧇ āĻĒāϰāĻŦāĻ°ā§āϤ⧀ āĻĒ⧁āύāϰāĻžāĻŦ⧃āĻ¤ā§āϤāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻļ⧁āϰ⧁ āĻ•āϰāϤ⧇ āϝāĻĻāĻŋ āϚāĻžāύ āϤāĻžāĻšāϞ⧇ [`continue`]" -"(https://doc.rust-lang.org/reference/expressions/loop-expr.html#continue-" -"expressions) āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤" #: src/control-flow-basics/break-continue.md msgid "" "If you want to exit any kind of loop early, use [`break`](https://doc.rust-" -"lang.org/reference/expressions/loop-expr.html#break-expressions). For " +"lang.org/reference/expressions/loop-expr.html#break-expressions). With " "`loop`, this can take an optional expression that becomes the value of the " "`loop` expression." msgstr "" -"āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āϕ⧋āύ⧋ āϧāϰāύ⧇āϰ āϞ⧁āĻĒ āĻĨ⧇āϕ⧇ āϤāĻžāĻĄāĻŧāĻžāϤāĻžāĻĄāĻŧāĻŋ āĻĒā§āϰāĻ¸ā§āĻĨāĻžāύ āĻ•āϰāϤ⧇ āϚāĻžāύ āϤāĻŦ⧇ [`break`](https://" -"doc.rust-lang.org/reference/expressions/loop-expr.html#break-expressions) " -"āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧁āύāĨ¤ `loop` āĻāϰ āϜāĻ¨ā§āϝ, āĻāϟāĻŋ āĻāĻ•āϟāĻŋ āϐāĻšā§āĻ›āĻŋāĻ• āĻ…āĻ­āĻŋāĻŦā§āϝāĻ•ā§āϤāĻŋ āύāĻŋāϤ⧇ āĻĒāĻžāϰ⧇ āϝāĻž `loop` " -"āĻ…āĻ­āĻŋāĻŦā§āϝāĻ•ā§āϤāĻŋāϰ āĻŽāĻžāύ āĻšāϝāĻŧ⧇ āϝāĻžāϝāĻŧāĨ¤" -#: src/control-flow-basics/break-continue.md src/std-traits/exercise.md -#: src/std-traits/solution.md src/smart-pointers/trait-objects.md -#: src/modules/exercise.md src/modules/solution.md -#: src/android/build-rules/library.md -#: src/android/interoperability/cpp/rust-bridge.md -#: src/async/pitfalls/cancellation.md -msgid "\"{}\"" -msgstr "\"{}\"" +#: src/control-flow-basics/break-continue.md +msgid "" +"Note that `loop` is the only looping construct that can return a non-trivial " +"value. This is because it's guaranteed to only return at a `break` statement " +"(unlike `while` and `for` loops, which can also return when the condition " +"fails)." +msgstr "" #: src/control-flow-basics/break-continue/labels.md msgid "" -"Both `continue` and `break` can optionally take a label argument which is " +"Both `continue` and `break` can optionally take a label argument that is " "used to break out of nested loops:" msgstr "" -"'continue' āĻāĻŦāĻ‚ 'break' āωāĻ­āϝāĻŧāχ āϐāĻšā§āĻ›āĻŋāĻ•āĻ­āĻžāĻŦ⧇ āĻāĻ•āϟāĻŋ āϞ⧇āĻŦ⧇āϞ āφāĻ°ā§āϗ⧁āĻŽā§‡āĻ¨ā§āϟ āύāĻŋāϤ⧇ āĻĒāĻžāϰ⧇ āϝāĻž āύ⧇āĻ¸ā§āĻŸā§‡āĻĄ " -"āϞ⧁āĻĒāϗ⧁āϞāĻŋ āĻĨ⧇āϕ⧇ āĻŦ⧇āϰāĻŋāϝāĻŧ⧇ āφāϏāϤ⧇ āĻŦā§āϝāĻŦāĻšā§ƒāϤ āĻšāϝāĻŧ:" #: src/control-flow-basics/break-continue/labels.md -msgid "\"elements searched: {elements_searched}\"" -msgstr "\"elements searched: {elements_searched}\"" +msgid "Labeled break also works on arbitrary blocks, e.g." +msgstr "" #: src/control-flow-basics/break-continue/labels.md -msgid "" -"Note that `loop` is the only looping construct which returns a non-trivial " -"value. This is because it's guaranteed to be entered at least once (unlike " -"`while` and `for` loops)." +msgid "\"This line gets skipped\"" msgstr "" -"`while` āĻāĻŦāĻ‚ `for` āĻāϰ āĻŦāĻŋāĻĒāϰ⧀āϤ `loop` āĻ…āĻ¨ā§āϤāϤ āĻāĻ•āĻŦāĻžāϰ āĻĒā§āϰāĻŦ⧇āĻļ āĻ•āϰāĻžāϰ āύāĻŋāĻļā§āϚāϝāĻŧāϤāĻž āĻĻ⧇āĻ“āϝāĻŧāĻžāϰ " -"āĻ•āĻžāϰāϪ⧇ āĻāĻ•āĻŽāĻžāĻ¤ā§āϰ āϞ⧁āĻĒāĻŋāĻ‚ āĻ—āĻ āύ āϝāĻž āĻāĻ•āϟāĻŋ āĻ…-āϤ⧁āĻšā§āĻ› āĻŽāĻžāύ āĻĒā§āϰāĻĻāĻžāύ āĻ•āϰ⧇āĨ¤" - -#: src/control-flow-basics/blocks-and-scopes.md -msgid "Blocks" -msgstr "Blocks" - -#: src/control-flow-basics/blocks-and-scopes.md -msgid "" -"A block in Rust contains a sequence of expressions, enclosed by braces `{}`. " -"Each block has a value and a type, which are those of the last expression of " -"the block:" -msgstr "" -"āϰāĻžāĻ¸ā§āϟ āĻ āĻāĻ•āϟāĻŋ āĻŦā§āϞāϕ⧇ āĻāĻ•ā§āϏāĻĒā§āϰ⧇āĻļāύ⧇āϰ āĻāĻ•āϟāĻŋ āĻ•ā§āϰāĻŽ āϰāϝāĻŧ⧇āϛ⧇ āϝāĻž `{}` āĻŦāĻ¨ā§āϧāύ⧀ āĻĻā§āĻŦāĻžāϰāĻž āφāĻŦāĻĻā§āϧāĨ¤ āĻĒā§āϰāϤāĻŋāϟāĻŋ " -"āĻŦā§āϞāϕ⧇āϰ āĻāĻ•āϟāĻŋ āĻŽāĻžāύ āĻāĻŦāĻ‚ āĻāĻ•āϟāĻŋ āϟāĻžāχāĻĒ āϰāϝāĻŧ⧇āϛ⧇, āϝāĻž āϏ⧇āχ āĻŦā§āϞāϕ⧇āϰ āĻļ⧇āώ āĻ…āĻ­āĻŋāĻŦā§āϝāĻ•ā§āϤāĻŋāϗ⧁āϞāĻŋāϰ āĻĻā§āĻŦāĻžāϰāĻž " -"āϏāĻ‚āĻœā§āĻžāĻžāϝāĻŧāĻŋāϤ:" - -#: src/control-flow-basics/blocks-and-scopes.md -msgid "\"y: {y}\"" -msgstr "\"y: {y}\"" - -#: src/control-flow-basics/blocks-and-scopes.md -msgid "" -"If the last expression ends with `;`, then the resulting value and type is " -"`()`." -msgstr "" -"āϝāĻĻāĻŋ āĻļ⧇āώ āĻāĻ•ā§āϏāĻĒā§āϰ⧇āĻļāύāϟāĻŋ `;` āĻĻāĻŋāϝāĻŧ⧇ āĻļ⧇āώ āĻšāϝāĻŧ, āϤāĻžāĻšāϞ⧇ āĻĢāϞāĻ¸ā§āĻŦāϰ⧂āĻĒ āĻŽāĻžāύ āĻāĻŦāĻ‚ āϟāĻžāχāĻĒ āĻšāĻŦ⧇ `()`āĨ¤" - -#: src/control-flow-basics/blocks-and-scopes.md -msgid "" -"You can show how the value of the block changes by changing the last line in " -"the block. For instance, adding/removing a semicolon or using a `return`." -msgstr "" -"āφāĻĒāύāĻŋ āĻŦā§āϞāϕ⧇āϰ āĻļ⧇āώ āϞāĻžāχāύ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰ⧇ āĻŦā§āϞāϕ⧇āϰ āĻŽāĻžāύ āϕ⧀āĻ­āĻžāĻŦ⧇ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāĻŋāϤ āĻšāϝāĻŧ āϤāĻž āĻĻ⧇āĻ–āĻžāϤ⧇ " -"āĻĒāĻžāϰ⧇āύāĨ¤ āωāĻĻāĻžāĻšāϰāĻŖāĻ¸ā§āĻŦāϰ⧂āĻĒ, āĻāĻ•āϟāĻŋ āϏ⧇āĻŽāĻŋāϕ⧋āϞāύ āϝ⧋āĻ— āĻ•āϰāĻž/āĻŽā§āϛ⧇ āĻĢ⧇āϞāĻž āĻŦāĻž āĻāĻ•āϟāĻŋ `āϰāĻŋāϟāĻžāĻ°ā§āύ` āĻŦā§āϝāĻŦāĻšāĻžāϰ " -"āĻ•āϰāĻžāĨ¤" - -#: src/control-flow-basics/blocks-and-scopes/scopes.md -msgid "A variable's scope is limited to the enclosing block." -msgstr "āĻāĻ•āϟāĻŋ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ⧇āϰ āĻ¸ā§āϕ⧋āĻĒ āϏ⧇āϟāĻŋāϰ āĻ˜ā§‡āϰāĻž āĻŦā§āϞāϕ⧇āϰ āĻŽāĻ§ā§āϝ⧇ āϏ⧀āĻŽāĻžāĻŦāĻĻā§āϧāĨ¤" - -#: src/control-flow-basics/blocks-and-scopes/scopes.md -msgid "" -"You can shadow variables, both those from outer scopes and variables from " -"the same scope:" -msgstr "" -"āφāĻĒāύāĻŋ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞāϗ⧁āϞāĻŋāϕ⧇ āĻ›āĻžāϝāĻŧāĻžāĻŦ⧃āϤ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύ, āĻāϟāĻŋ āĻŦāĻžāχāϰ⧇āϰ āĻ¸ā§āϕ⧋āĻĒ āĻāĻŦāĻ‚ āĻāĻ•āχ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ⧇āϰ " -"āύāĻŋāĻœā§‡āĻ¸ā§āĻŦ āĻ¸ā§āϕ⧋āĻĒ āωāĻ­ā§Ÿā§‡ āĻĨ⧇āϕ⧇āχ āϏāĻŽā§āĻ­āĻŦ:" - -#: src/control-flow-basics/blocks-and-scopes/scopes.md -msgid "\"before: {a}\"" -msgstr "\"before: {a}\"" - -#: src/control-flow-basics/blocks-and-scopes/scopes.md -#: src/std-traits/from-and-into.md src/slices-and-lifetimes/solution.md -msgid "\"hello\"" -msgstr "\"hello\"" - -#: src/control-flow-basics/blocks-and-scopes/scopes.md -msgid "\"inner scope: {a}\"" -msgstr "\"inner scope: {a}\"" - -#: src/control-flow-basics/blocks-and-scopes/scopes.md -msgid "\"shadowed in inner scope: {a}\"" -msgstr "\"shadowed in inner scope: {a}\"" - -#: src/control-flow-basics/blocks-and-scopes/scopes.md -msgid "\"after: {a}\"" -msgstr "\"after: {a}\"" - -#: src/control-flow-basics/blocks-and-scopes/scopes.md -msgid "" -"Show that a variable's scope is limited by adding a `b` in the inner block " -"in the last example, and then trying to access it outside that block." -msgstr "" -"āφāϗ⧇āϰ āωāĻĻāĻžāĻšāϰāϪ⧇ āϭ⧇āϤāϰ⧇āϰ āĻŦā§āϞāϕ⧇ āĻāĻ•āϟāĻŋ `b` āϞāĻžāĻ—āĻŋā§Ÿā§‡ āϏ⧇āϟāĻžāϕ⧇ āĻŦāĻžāχāϰ⧇ āĻĨ⧇āϕ⧇ āĻ…ā§āϝāĻžāĻ•ā§āϏ⧇āϏ āĻ•āϰāĻŦāĻžāϰ " -"āĻšā§‡āĻˇā§āϟāĻž āĻ•āϰ⧇ āĻāϟāĻž āĻĻ⧇āĻ–āĻžāύ āϝ⧇ āĻāĻ•āϟāĻŋ āĻ­ā§āϝāĻžāϰāĻŋā§Ÿā§‡āĻŦāϞ⧇āϰ āĻ¸ā§āϕ⧋āĻĒ āϏ⧀āĻŽāĻžāĻŦāĻĻā§āϧ āĻĨāĻžāϕ⧇āĨ¤" - -#: src/control-flow-basics/blocks-and-scopes/scopes.md -msgid "" -"Shadowing is different from mutation, because after shadowing both " -"variable's memory locations exist at the same time. Both are available under " -"the same name, depending where you use it in the code." -msgstr "" -"āĻ›āĻžāϝāĻŧāĻžāĻŦ⧃āϤ āĻ•āϰāĻž āĻāĻŦāĻ‚ āĻĒāϰāĻŋāĻŦā§āϝāĻ•ā§āϤāĻŋāϰ āĻŽāĻ§ā§āϝ⧇ āϤāĻĢāĻžā§Ž āφāϛ⧇, āĻ•āĻžāϰāĻŖ āĻ›āĻžā§ŸāĻžāĻŦ⧃āϤ āĻ•āϰāĻŦāĻžāϰ āĻĒāϰ⧇ āωāĻ­āϝāĻŧ āϭ⧇āϰāĻŋāϝāĻŧ⧇āĻŦāϞ⧇āϰ-" -"āχ āĻŽā§‡āĻŽāϰāĻŋ āĻ…āĻŦāĻ¸ā§āĻĨāĻžāύ āĻāĻ•āχ āϏāĻŽāϝāĻŧ⧇ āĻŦāĻŋāĻĻā§āϝāĻŽāĻžāύ āĻĨāĻžāϕ⧇āĨ¤ āφāĻĒāύāĻŋ āϕ⧋āĻĄā§‡ āϕ⧋āĻĨāĻžāϝāĻŧ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇āύ āϤāĻžāϰ āωāĻĒāϰ " -"āύāĻŋāĻ°ā§āĻ­āϰ āĻ•āϰ⧇ āωāĻ­āϝāĻŧāχ āĻāĻ•āχ āύāĻžāĻŽā§‡ āωāĻĒāϞāĻŦā§āϧāĨ¤" - -#: src/control-flow-basics/blocks-and-scopes/scopes.md -msgid "A shadowing variable can have a different type." -msgstr "" -"āĻāĻ•āϟāĻŋ āĻ­ā§āϝāĻžāϰāĻŋā§Ÿā§‡āĻŦāϞ āϝ⧇āϟāĻŋ āĻ…āĻ¨ā§āϝ āĻ­ā§āϝāĻžāϰāĻŋā§Ÿā§‡āĻŦāϞ⧇āϰ āĻ›āĻžā§ŸāĻž āĻšāĻŋāϏ⧇āĻŦ⧇ āĻŦāĻžāύāĻžāύ⧋ āĻšā§Ÿā§‡āϛ⧇ āϏ⧇āϟāĻŋāϰ āĻĨ⧇āϕ⧇ " -"āφāϞāĻžāĻĻāĻž āϟāĻžāχāĻĒ āϧāĻžāϰāĻŖ āĻ•āϰāϤ⧇āχ āĻĒāĻžāϰ⧇āĨ¤" - -#: src/control-flow-basics/blocks-and-scopes/scopes.md -msgid "" -"Shadowing looks obscure at first, but is convenient for holding on to values " -"after `.unwrap()`." -msgstr "" -"āĻ›āĻžā§ŸāĻž āĻ•āϰāĻž āĻĒā§āϰāĻĨāĻŽā§‡ āĻ…āĻ¸ā§āĻĒāĻˇā§āϟ āĻĻ⧇āĻ–āĻžāϝāĻŧ, āĻ•āĻŋāĻ¨ā§āϤ⧁ `.unwrap()` āĻāϰ āĻĒāϰ⧇ āĻŽāĻžāύ āϧāϰ⧇ āϰāĻžāĻ–āĻžāϰ āϜāĻ¨ā§āϝ " -"āϏ⧁āĻŦāĻŋāϧāĻžāϜāύāĻ•āĨ¤" #: src/control-flow-basics/functions.md msgid "" "Declaration parameters are followed by a type (the reverse of some " "programming languages), then a return type." msgstr "" -"āĻ˜ā§‹āώāĻŋāϤ āĻĒāϰāĻžāĻŽāĻŋāϤāĻŋāϰ āĻĒāϰ⧇ āϤāĻžāϰ āϟāĻžāχāĻĒ āϞāĻžāĻ—āĻžāύ⧋ āĻšā§Ÿā§‡ (āĻāχ āϜāĻŋāύāĻŋāϏ āϤāĻž āĻ…āύ⧇āĻ• āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽāĻŋāĻ‚ āĻ­āĻžāώāĻžāϰ " -"āϤ⧁āϞāύāĻžā§Ÿ āĻŦāĻŋāĻĒāϰ⧀āϤ) āĻāĻŦāĻ‚ āϤāĻžāϰ āĻĒāϰ⧇ āĻāĻ•āϟāĻŋ āϰāĻŋāϟāĻžāĻ°ā§āύ āϟāĻžāχāĻĒ āĻĻ⧇āĻ“ā§ŸāĻž āĻšā§Ÿā§‡āĨ¤" #: src/control-flow-basics/functions.md msgid "" @@ -3644,40 +4865,29 @@ msgid "" "keyword can be used for early return, but the \"bare value\" form is " "idiomatic at the end of a function (refactor `gcd` to use a `return`)." msgstr "" -"āĻāĻ•āϟāĻŋ āĻĢāĻžāĻ‚āĻļāύ āĻŦāĻĄāĻŋ (āĻŦāĻž āϝ⧇āϕ⧋āύ⧋ āĻŦā§āϞāĻ•) āĻāϰ āĻļ⧇āώ āĻ…āĻ­āĻŋāĻŦā§āϝāĻ•ā§āϤāĻŋ āϏ⧇āϟāĻŋāϰ āĻĢ⧇āϰāϤāĻ—āĻžāĻŽā§€ āĻŽāĻžāύ āĻšāϝāĻŧ⧇ āϝāĻžāϝāĻŧāĨ¤ " -"āĻļ⧁āϧ⧁ āĻ…āĻ­āĻŋāĻŦā§āϝāĻ•ā§āϤāĻŋāϰ āĻļ⧇āώ⧇ `;` āĻŦāĻžāĻĻ āĻĻāĻŋāύāĨ¤ `return` āϕ⧀āĻ“āϝāĻŧāĻžāĻ°ā§āĻĄāϟāĻŋ āĻĒā§āϰāĻžāĻĨāĻŽāĻŋāĻ• āϰāĻŋāϟāĻžāĻ°ā§āύ⧇āϰ āϜāĻ¨ā§āϝ " -"āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āϝ⧇āϤ⧇ āĻĒāĻžāϰ⧇, āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻāĻ•āϟāĻŋ āĻĢāĻžāĻ‚āĻļāύ⧇āϰ āĻļ⧇āώ⧇ \"āĻŦ⧇āϝāĻŧāĻžāϰ āĻ­ā§āϝāĻžāϞ⧁\" āĻĢāĻ°ā§āĻŽāϟāĻŋ " -"āĻŦāĻžāĻ—ā§āĻŦ⧈āĻļāĻŋāĻˇā§āĻŸā§āϝāϏāĻŽā§āĻŽāϤ (`gcd` āϟāĻžāϤ⧇ `return` āϞāĻžāĻ—āĻŋā§Ÿā§‡ āφāĻŦāĻžāϰ āϞāĻŋāϖ⧇ āĻĻ⧇āϖ⧁āύ)āĨ¤" #: src/control-flow-basics/functions.md msgid "" "Some functions have no return value, and return the 'unit type', `()`. The " -"compiler will infer this if the `-> ()` return type is omitted." +"compiler will infer this if the return type is omitted." msgstr "" -"āĻ…āύ⧇āĻ• āĻĢāĻžāĻ‚āĻļāύ⧇āϰ āϰāĻŋāϟāĻžāĻ°ā§āύ āϟāĻžāχāĻĒ āĻĨāĻžāϕ⧇ āύāĻž āĻāĻŦāĻ‚ āϤāĻžāϰāĻž 'āĻāĻ•āĻ• āĻŦāĻž āχāωāύāĻŋāϟ āϟāĻžāχāĻĒ ' āĻŦāĻž `()` " -"āϰāĻŋāϟāĻžāĻ°ā§āύ āĻ•āϰ⧇ āĻĨāĻžāϕ⧇āĨ¤ āĻ•āĻŽā§āĻĒāĻžāχāϞāĻžāϰ āĻāϟāĻŋ āύāĻŋāĻœā§‡-āύāĻŋāĻœā§‡āχ āĻ…āύ⧁āĻŽāĻžāύ āĻ•āϰ⧇ āύāĻŋāϤ⧇ āĻĒāĻžāϰāĻŦ⧇ āϝāĻĻāĻŋ `-> ()` " -"āϰāĻŋāϟāĻžāĻ°ā§āύ āϟāĻžāχāĻĒ āĻŦāĻžāĻĻ āĻĻ⧇āĻ“āϝāĻŧāĻž āĻšāϝāĻŧāĨ¤" #: src/control-flow-basics/functions.md msgid "" "Overloading is not supported -- each function has a single implementation." -msgstr "āĻ“āĻ­āĻžāϰāϞ⧋āĻĄāĻŋāĻ‚ āϏāĻŽāĻ°ā§āĻĨāĻŋāϤ āύāϝāĻŧ -- āĻĒā§āϰāϤāĻŋāϟāĻŋ āĻĢāĻžāĻ‚āĻļāύ⧇āϰ āĻļ⧁āϧ⧁ āĻāĻ•āϟāĻŋ āĻŦāĻžāĻ¸ā§āϤāĻŦāĻžāϝāĻŧāύ āĻĨāĻžāĻ•āϤ⧇ āĻĒāĻžāϰ⧇āĨ¤" +msgstr "" #: src/control-flow-basics/functions.md msgid "" "Always takes a fixed number of parameters. Default arguments are not " "supported. Macros can be used to support variadic functions." msgstr "" -"āϏāĻ°ā§āĻŦāĻĻāĻž āĻāĻ•āϟāĻŋ āύāĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āϟ āϏāĻ‚āĻ–ā§āϝāĻ• āĻĒāϰāĻžāĻŽāĻŋāϤāĻŋ āϞāĻžāϗ⧇āĨ¤ āϰ⧇āĻ¸ā§āϟ āĻ āĻĄāĻŋāĻĢāĻ˛ā§āϟ āφāĻ°ā§āϗ⧁āĻŽā§‡āĻ¨ā§āϟ āϏāĻŽāĻ°ā§āĻĨāĻŋāϤ āύāϝāĨ¤ " -"āĻŽā§āϝāĻžāĻ•ā§āϰ⧋ āĻĻāĻŋā§Ÿā§‡ āĻŦ⧈āϚāĻŋāĻ¤ā§āĻ°ā§āϝāĻŽāϝāĻŧ āĻŦāĻž āĻ­ā§āϝāĻžāϰāĻŋ⧟āĻžāĻĄāĻŋāĻ• āĻĢāĻžāĻ‚āĻļāύ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āϝ⧇āϤ⧇ āĻĒāĻžāϰ⧇āĨ¤" #: src/control-flow-basics/functions.md msgid "" "Always takes a single set of parameter types. These types can be generic, " "which will be covered later." msgstr "" -"āϏāĻ°ā§āĻŦāĻĻāĻž āĻĒāϰāĻžāĻŽāĻŋāϤāĻŋāϰ āϟāĻžāχāĻĒ āĻāĻ•āϟāĻŋ āĻāĻ•āĻ• āϏ⧇āϟ-āχ āϞāĻžāϗ⧇āĨ¤ āĻāχ āϟāĻžāχāĻĒāϗ⧁āϞāĻŋ āĻœā§‡āύ⧇āϰāĻŋāĻ• āĻšāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ " -"āĻœā§‡āύ⧇āϰāĻŋāĻ• āĻĒāϰ⧇ āφāϞ⧋āϚāύāĻž āĻ•āϰāĻž āĻšāĻŦ⧇āĨ¤" #: src/control-flow-basics/macros.md msgid "" @@ -3685,49 +4895,32 @@ msgid "" "variable number of arguments. They are distinguished by a `!` at the end. " "The Rust standard library includes an assortment of useful macros." msgstr "" -"āϏāĻ‚āĻ•āϞāύ⧇āϰ āϏāĻŽāϝāĻŧ āĻŽā§āϝāĻžāĻ•ā§āϰ⧋āϗ⧁āϞāĻŋāϕ⧇ āϰāĻžāĻ¸ā§āϟ āϕ⧋āĻĄā§‡ āĻĒā§āϰāϏāĻžāϰāĻŋāϤ āĻ•āϰāĻž āĻšāϝāĻŧ āĻāĻŦāĻ‚ āĻāĻ•āϟāĻŋ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύāĻļā§€āϞ āϏāĻ‚āĻ–ā§āϝāĻ• " -"āφāĻ°ā§āϗ⧁āĻŽā§‡āĻ¨ā§āϟ āύāĻŋāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ āĻŽā§āϝāĻžāĻ•ā§āϰ⧋āϰ āĻļ⧇āώ⧇ āĻāĻ•āϟāĻŋ `!` āĻĻāĻŋā§Ÿā§‡ āϏ⧇āϟāĻŋ āĻ…āĻ¨ā§āϝ āϕ⧋āĻĄā§‡āϰ āĻĨ⧇āϕ⧇ āĻĒāĻžāĻ°ā§āĻĨāĻ•ā§āϝ āĻ•āϰāĻž " -"āĻšā§Ÿā§‡āĨ¤ āϰāĻžāĻ¸ā§āϟ āĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄ āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋāϤ⧇ āĻĻāϰāĻ•āĻžāϰ⧀ āĻŽā§āϝāĻžāĻ•ā§āϰ⧋āϗ⧁āϞāĻŋāϰ āĻāĻ•āϟāĻŋ āĻ­āĻžāĻŖā§āĻĄāĻžāϰ āĻ…āĻ¨ā§āϤāĻ°ā§āϭ⧁āĻ•ā§āϤ āϰāϝāĻŧ⧇āϛ⧇āĨ¤" #: src/control-flow-basics/macros.md msgid "" "`println!(format, ..)` prints a line to standard output, applying formatting " "described in [`std::fmt`](https://doc.rust-lang.org/std/fmt/index.html)." msgstr "" -"[`std::fmt`](https://doc.rust-lang.org/std/fmt/index.html) āĻ āĻŦāĻ°ā§āĻŖāĻŋāϤ āĻŦāĻŋāĻ¨ā§āϝāĻžāϏ " -"āĻĒā§āϰāϝāĻŧā§‹āĻ— āĻ•āϰ⧇ `println!(format, ..)` āĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄ āφāωāϟāĻĒ⧁āĻŸā§‡ āĻāĻ•āϟāĻŋ āϞāĻžāχāύ āĻĒā§āϰāĻŋāĻ¨ā§āϟ āĻ•āϰ⧇āĨ¤" #: src/control-flow-basics/macros.md msgid "" "`format!(format, ..)` works just like `println!` but returns the result as a " "string." msgstr "" -"`format!(format, ..)` āĻ āĻŋāĻ• `println!` āĻāϰ āĻŽāϤ⧋ āĻ•āĻžāϜ āĻ•āϰ⧇ āĻ•āĻŋāĻ¨ā§āϤ⧁ āĻāĻ•āϟāĻŋ āĻ¸ā§āĻŸā§āϰāĻŋāĻ‚ āĻšāĻŋāϏ⧇āĻŦ⧇ " -"āĻĢāϞāĻžāĻĢāϞ āĻĒā§āϰāĻĻāĻžāύ āĻ•āϰ⧇āĨ¤" #: src/control-flow-basics/macros.md msgid "`dbg!(expression)` logs the value of the expression and returns it." -msgstr "`dbg!(expression)` āĻ…āĻ­āĻŋāĻŦā§āϝāĻ•ā§āϤāĻŋāϰ āĻŽāĻžāύ āϞāĻ— āĻ•āϰ⧇ āĻāĻŦāĻ‚ āϏ⧇āϟāĻŋāϕ⧇ āĻĢ⧇āϰāϤ āĻĻ⧇āϝāĻŧāĨ¤" +msgstr "" #: src/control-flow-basics/macros.md msgid "" "`todo!()` marks a bit of code as not-yet-implemented. If executed, it will " "panic." msgstr "" -"`todo!()` āϕ⧋āĻĄā§‡āϰ āĻāĻ•āϟāĻŋ āĻŦā§āϞāĻ•āϕ⧇ āĻāĻ–āύ⧋-āĻŦāĻžāĻ¸ā§āϤāĻŦāĻžāϝāĻŧāĻŋāϤ āĻšāϝāĻŧāύāĻŋ āĻŦāϞ⧇ āϚāĻŋāĻšā§āύāĻŋāϤ āĻ•āϰ⧇āĨ¤ āĻāχ āϕ⧋āĻĄ āϚāĻžāϞāĻžāϞ⧇ " -"āϰāĻžāĻ¸ā§āϟ āφāϤāĻ™ā§āĻ•āĻŋāϤ āĻšāĻŦ⧇āĨ¤" - -#: src/control-flow-basics/macros.md -msgid "" -"`unreachable!()` marks a bit of code as unreachable. If executed, it will " -"panic." -msgstr "" -"`unreachable!()` āĻāĻ•āϟāĻŋ āϕ⧋āĻĄā§‡āϰ āĻ…āĻ‚āĻļ āϕ⧇ āĻĒ⧌āρāĻ›āĻžāύ⧋ āϝāĻžāϝāĻŧ āύāĻž āĻŦāϞ⧇ āϚāĻŋāĻšā§āύāĻŋāϤ āĻ•āϰ⧇āĨ¤ āĻāχ āϕ⧋āĻĄ " -"āϚāĻžāϞāĻžāϞ⧇ āϰāĻžāĻ¸ā§āϟ āφāϤāĻ™ā§āĻ•āĻŋāϤ āĻšāĻŦ⧇āĨ¤" #: src/control-flow-basics/macros.md msgid "\"{n}! = {}\"" -msgstr "\"{n}! = {}\"" +msgstr "" #: src/control-flow-basics/macros.md msgid "" @@ -3735,168 +4928,93 @@ msgid "" "how to use them. Why they are defined as macros, and what they expand to, is " "not especially critical." msgstr "" -"āĻāχ āĻŦāĻŋāĻ­āĻžāĻ— āĻĨ⧇āϕ⧇ āĻŦā§‹āĻāĻž āϝāĻžā§Ÿ āϝ⧇ āĻāχ āϏāĻžāϧāĻžāϰāĻŖ āϏ⧁āĻŦāĻŋāϧāĻžāϗ⧁āϞāĻŋ āĻŦāĻŋāĻĻā§āϝāĻŽāĻžāύ, āĻāĻŦāĻ‚ āϕ⧀āĻ­āĻžāĻŦ⧇ āϏ⧇āϗ⧁āϞāĻŋ " -"āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰāĻž āϝāĻžāϝāĻŧāĨ¤ āϕ⧇āύ āϏ⧇āϗ⧁āϞāĻŋ āĻŽā§āϝāĻžāĻ•ā§āϰ⧋ āĻšāĻŋāϏāĻžāĻŦ⧇ āϏāĻ‚āĻœā§āĻžāĻžāϝāĻŧāĻŋāϤ āĻ•āϰāĻž āφāϛ⧇, āĻāĻŦāĻ‚ āϏ⧇āϗ⧁āϞāĻŋ āĻ•āĻŋ " -"āĻĒā§āϰāϏāĻžāϰāĻŋāϤ āĻšāϝāĻŧ, āĻŦāĻŋāĻļ⧇āώ āĻ•āϰ⧇ āϏāĻŽāĻžāϞ⧋āϚāύāĻžāĻŽā§‚āϞāĻ• āύāϝāĻŧāĨ¤" #: src/control-flow-basics/macros.md msgid "" "The course does not cover defining macros, but a later section will describe " "use of derive macros." msgstr "" -"āϕ⧋āĻ°ā§āϏāϟāĻŋ āĻŽā§āϝāĻžāĻ•ā§āϰ⧋ āĻ•āĻŋāĻ­āĻžāĻŦ⧇ āϏāĻ‚āĻœā§āĻžāĻžāϝāĻŧāĻŋāϤ āϏ⧇āϟāĻž āφāϞ⧋āϚāύāĻž āĻ•āϰ⧇ āύāĻž, āϤāĻŦ⧇ āĻĒāϰāĻŦāĻ°ā§āϤ⧀ āĻāĻ•āϟāĻŋ āĻŦāĻŋāĻ­āĻžāϗ⧇ " -"āĻĄā§‡āϰāĻžāχāĻ­ āĻŽā§āϝāĻžāĻ•ā§āϰ⧋āϰ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻŦāĻ°ā§āĻŖāύāĻž āĻ•āϰāĻž āĻšāĻŦ⧇āĨ¤" + +#: src/control-flow-basics/macros.md src/pattern-matching/match.md +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "More To Explore" +msgstr "" + +#: src/control-flow-basics/macros.md +msgid "" +"There are a number of other useful macros provided by the standard library. " +"Some other examples you can share with students if they want to know more:" +msgstr "" + +#: src/control-flow-basics/macros.md +msgid "" +"[`assert!`](https://doc.rust-lang.org/stable/std/macro.assert.html) and " +"related macros can be used to add assertions to your code. These are used " +"heavily in writing tests." +msgstr "" + +#: src/control-flow-basics/macros.md +msgid "" +"[`unreachable!`](https://doc.rust-lang.org/stable/std/macro.unreachable." +"html) is used to mark a branch of control flow that should never be hit." +msgstr "" + +#: src/control-flow-basics/macros.md +msgid "" +"[`eprintln!`](https://doc.rust-lang.org/stable/std/macro.eprintln.html) " +"allows you to print to stderr." +msgstr "" #: src/control-flow-basics/exercise.md msgid "" "The [Collatz Sequence](https://en.wikipedia.org/wiki/Collatz_conjecture) is " -"defined as follows, for an arbitrary n" -msgstr "" -"[Collatz āϏāĻŋāϕ⧋āϝāĻŧ⧇āĻ¨ā§āϏ](https://en.wikipedia.org/wiki/Collatz_conjecture) āύāĻŋāĻŽā§āύāϰ⧂āĻĒ " -"āϏāĻ‚āĻœā§āĻžāĻžāϝāĻŧāĻŋāϤ āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇, āĻāĻ•āϟāĻŋ āύāĻŋāĻ°ā§āĻŦāĻŋāϚāĻžāϰ⧇ n āĻāϰ āϜāĻ¨ā§āϝ" - -#: src/control-flow-basics/exercise.md -msgid "1" -msgstr "ā§§" - -#: src/control-flow-basics/exercise.md -msgid " greater than zero:" -msgstr "āĻļā§‚āĻ¨ā§āϝ⧇āϰ āĻšā§‡āϝāĻŧ⧇ āĻŦāĻĄāĻŧ:" - -#: src/control-flow-basics/exercise.md -msgid "If _n" -msgstr "If _n" - -#: src/control-flow-basics/exercise.md -msgid "i" -msgstr "i" - -#: src/control-flow-basics/exercise.md -msgid "_ is 1, then the sequence terminates at _n" -msgstr "1 āĻšāϞ⧇, āĻ•ā§āϰāĻŽāϟāĻŋ _n āĻļ⧇āώ āĻšā§Ÿā§‡" - -#: src/control-flow-basics/exercise.md -msgid "_." -msgstr "_." - -#: src/control-flow-basics/exercise.md -msgid "_ is even, then _n" -msgstr "_ āĻœā§‹āĻĄāĻŧ āĻšāϞ⧇ , āϤāĻžāĻšāϞ⧇ _n" - -#: src/control-flow-basics/exercise.md -msgid "i+1" -msgstr "i+1" - -#: src/control-flow-basics/exercise.md -msgid " = n" -msgstr " = n" - -#: src/control-flow-basics/exercise.md -msgid " / 2_." -msgstr " /2_." - -#: src/control-flow-basics/exercise.md -msgid "_ is odd, then _n" -msgstr "_ āĻŦāĻŋāĻœā§‹āĻĄāĻŧ āϝāĻĻāĻŋ āĻšā§Ÿā§‡, āϤāĻžāĻšāϞ⧇ _n" - -#: src/control-flow-basics/exercise.md -msgid " = 3 * n" -msgstr " = 3 * n" - -#: src/control-flow-basics/exercise.md -msgid " + 1_." -msgstr " + 1_." - -#: src/control-flow-basics/exercise.md -msgid "For example, beginning with _n" -msgstr "āωāĻĻāĻžāĻšāϰāĻŖāĻ¸ā§āĻŦāϰ⧂āĻĒ, _n āĻĻāĻŋāϝāĻŧ⧇ āĻļ⧁āϰ⧁ āĻšāϞ⧇" - -#: src/control-flow-basics/exercise.md -msgid "_ = 3:" -msgstr "_ = 3:" - -#: src/control-flow-basics/exercise.md -msgid "3 is odd, so _n" -msgstr "3 āĻŦāĻŋāĻœā§‹āĻĄāĻŧ, āϤāĻžāχ _n" - -#: src/control-flow-basics/exercise.md -msgid "2" -msgstr "2" - -#: src/control-flow-basics/exercise.md -msgid "_ = 3 * 3 + 1 = 10;" -msgstr "_ = 3 * 3 + 1 = 10;" - -#: src/control-flow-basics/exercise.md -msgid "10 is even, so _n" -msgstr "10 āĻœā§‹āĻĄāĻŧ, āϤāĻžāχ _n" - -#: src/control-flow-basics/exercise.md src/bare-metal/aps/better-uart.md -msgid "3" -msgstr "3" - -#: src/control-flow-basics/exercise.md -msgid "_ = 10 / 2 = 5;" -msgstr "_ = 10 / 2 = 5;" - -#: src/control-flow-basics/exercise.md -msgid "5 is odd, so _n" -msgstr "" - -#: src/control-flow-basics/exercise.md src/bare-metal/aps/better-uart.md -msgid "4" +"defined as follows, for an arbitrary n1 greater than zero:" msgstr "" #: src/control-flow-basics/exercise.md -msgid "_ = 3 * 5 + 1 = 16;" +msgid "" +"If _ni_ is 1, then the sequence terminates at _ni_." msgstr "" #: src/control-flow-basics/exercise.md -msgid "16 is even, so _n" +msgid "If _ni_ is even, then _ni+1 = ni / 2_." msgstr "" #: src/control-flow-basics/exercise.md -msgid "5" +msgid "" +"If _ni_ is odd, then _ni+1 = 3 * ni + 1_." msgstr "" #: src/control-flow-basics/exercise.md -msgid "_ = 16 / 2 = 8;" +msgid "For example, beginning with _n1_ = 3:" msgstr "" #: src/control-flow-basics/exercise.md -msgid "8 is even, so _n" -msgstr "" - -#: src/control-flow-basics/exercise.md src/bare-metal/aps/better-uart.md -msgid "6" +msgid "3 is odd, so _n2_ = 3 * 3 + 1 = 10;" msgstr "" #: src/control-flow-basics/exercise.md -msgid "_ = 8 / 2 = 4;" +msgid "10 is even, so _n3_ = 10 / 2 = 5;" msgstr "" #: src/control-flow-basics/exercise.md -msgid "4 is even, so _n" +msgid "5 is odd, so _n4_ = 3 * 5 + 1 = 16;" msgstr "" #: src/control-flow-basics/exercise.md -msgid "7" +msgid "16 is even, so _n5_ = 16 / 2 = 8;" msgstr "" #: src/control-flow-basics/exercise.md -msgid "_ = 4 / 2 = 2;" +msgid "8 is even, so _n6_ = 8 / 2 = 4;" msgstr "" #: src/control-flow-basics/exercise.md -msgid "2 is even, so _n" -msgstr "" - -#: src/control-flow-basics/exercise.md src/bare-metal/aps/better-uart.md -msgid "8" +msgid "4 is even, so _n7_ = 4 / 2 = 2;" msgstr "" #: src/control-flow-basics/exercise.md -msgid "_ = 1; and" +msgid "2 is even, so _n8_ = 1; and" msgstr "" #: src/control-flow-basics/exercise.md @@ -3905,109 +5023,93 @@ msgstr "" #: src/control-flow-basics/exercise.md msgid "" -"Write a function to calculate the length of the collatz sequence for a given " +"Write a function to calculate the length of the Collatz sequence for a given " "initial `n`." msgstr "" #: src/control-flow-basics/exercise.md src/control-flow-basics/solution.md msgid "/// Determine the length of the collatz sequence beginning at `n`.\n" -msgstr "/// Determine the length of the collatz sequence beginning at `n`.\n" +msgstr "" -#: src/control-flow-basics/solution.md src/concurrency/scoped-threads.md +#: src/control-flow-basics/exercise.md src/control-flow-basics/solution.md +#: src/idiomatic/polymorphism/refresher/trait-bounds.md msgid "\"Length: {}\"" -msgstr "\"Length: {}\"" +msgstr "" + +#: src/control-flow-basics/exercise.md src/control-flow-basics/solution.md +msgid "// should be 15\n" +msgstr "" + +#: src/control-flow-basics/solution.md +msgid "This solution demonstrates a few key Rust features:" +msgstr "" + +#: src/control-flow-basics/solution.md +msgid "" +"**`mut` arguments:** The `n` argument is declared as `mut n`. This makes the " +"local variable `n` mutable within the function scope. It does _not_ affect " +"the caller's value, as integers are `Copy` types passed by value." +msgstr "" + +#: src/control-flow-basics/solution.md +msgid "" +"**`if` expressions:** Rust's `if` is an expression, meaning it produces a " +"value. We assign the result of the `if`/`else` block directly to `n`. This " +"is more concise than writing `n = ...` inside each branch." +msgstr "" + +#: src/control-flow-basics/solution.md +msgid "" +"**Implicit return:** The function ends with `len` (without a semicolon), " +"which is automatically returned." +msgstr "" + +#: src/control-flow-basics/solution.md +msgid "" +"Note that `n` must be strictly greater than 0 for the Collatz sequence to be " +"valid. The function signature takes `i32`, but the problem description " +"implies positive integers. A more robust implementation might use `u32` or " +"return an `Option` or `Result` to handle invalid inputs (0 or negative " +"numbers), but panic or infinite loops are potential outcomes here if `n <= " +"0`." +msgstr "" + +#: src/control-flow-basics/solution.md +msgid "" +"The overflow is a potential issue if `n` grows too large, similar to the " +"Fibonacci exercise." +msgstr "" #: src/welcome-day-1-afternoon.md src/welcome-day-2-afternoon.md #: src/welcome-day-3-afternoon.md src/welcome-day-4-afternoon.md msgid "Welcome Back" -msgstr "āĻ¸ā§āĻŦāĻžāĻ—āϤāĻŽ" - -#: src/welcome-day-1-afternoon.md -msgid "[Tuples and Arrays](./tuples-and-arrays.md) (35 minutes)" -msgstr "[āϟāĻŋāωāĻĒ⧇āϞ āĻāĻŦāĻ‚ āĻ…ā§āϝāĻžāϰ⧇](./tuples-and-arrays.md) (ā§Šā§Ģ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/welcome-day-1-afternoon.md -msgid "[References](./references.md) (35 minutes)" -msgstr "[āϰ⧇āĻĢāĻžāϰ⧇āĻ¨ā§āϏ](./references.md)(ā§Šā§Ģ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/welcome-day-1-afternoon.md -msgid "[User-Defined Types](./user-defined-types.md) (50 minutes)" -msgstr "[āĻŦā§āϝāĻŦāĻšāĻžāϰāĻ•āĻžāϰ⧀āϰ āĻĻā§āĻŦāĻžāϰāĻž āϏāĻ‚āĻœā§āĻžāĻžāϝāĻŧāĻŋāϤ āϟāĻžāχāĻĒ](./user-defined-types.md) (ā§Ģā§Ļ āĻŽāĻŋāύāĻŋāϟ)" - -#: src/welcome-day-1-afternoon.md -msgid "" -"Including 10 minute breaks, this session should take about 2 hours and 15 " -"minutes" -msgstr "ā§§ā§Ļ āĻŽāĻŋāύāĻŋāϟ āĻŦāĻŋāϰāϤāĻŋāϏāĻš āĻāχ āĻ…āϧāĻŋāĻŦ⧇āĻļāύ āĻļ⧇āώ āĻ•āϰāϤ⧇ ⧍ āϘāĻ¨ā§āϟāĻž ā§§ā§Ģ āĻŽāĻŋāύāĻŋāϟ āϞāĻžāĻ—āĻŦ⧇" - -#: src/tuples-and-arrays.md -msgid "" -"[Tuples and Arrays](./tuples-and-arrays/tuples-and-arrays.md) (10 minutes)" msgstr "" -"[āϟāĻŋāωāĻĒ⧇āϞ āĻāĻŦāĻ‚ āĻ…ā§āϝāĻžāϰ⧇](./tuples-and-arrays/tuples-and-arrays.md) (ā§§ā§Ļ āĻŽāĻŋāύāĻŋāϟ)" + +#: src/welcome-day-1-afternoon.md +msgid "" +"Including 10 minute breaks, this session should take about 2 hours and 45 " +"minutes. It contains:" +msgstr "" #: src/tuples-and-arrays.md -msgid "[Array Iteration](./tuples-and-arrays/iteration.md) (3 minutes)" +msgid "This segment should take about 35 minutes. It contains:" msgstr "" #: src/tuples-and-arrays.md msgid "" -"[Patterns and Destructuring](./tuples-and-arrays/destructuring.md) (5 " -"minutes)" +"We have seen how primitive types work in Rust. Now it's time for you to " +"start building new composite types." msgstr "" -#: src/tuples-and-arrays.md -msgid "[Exercise: Nested Arrays](./tuples-and-arrays/exercise.md) (15 minutes)" -msgstr "" - -#: src/tuples-and-arrays.md src/references.md -msgid "This segment should take about 35 minutes" -msgstr "" - -#: src/tuples-and-arrays/tuples-and-arrays.md +#: src/tuples-and-arrays/arrays.md msgid "" -"Tuples and arrays are the first \"compound\" types we have seen. All " -"elements of an array have the same type, while tuples can accommodate " -"different types. Both types have a size fixed at compile time." +"Arrays can also be initialized using the shorthand syntax, e.g. `[0; 1024]`. " +"This can be useful when you want to initialize all elements to the same " +"value, or if you have a large array that would be hard to initialize " +"manually." msgstr "" -#: src/tuples-and-arrays/tuples-and-arrays.md -msgid "Arrays" -msgstr "Arrays" - -#: src/tuples-and-arrays/tuples-and-arrays.md -msgid "`[T; N]`" -msgstr "`[T; N]`" - -#: src/tuples-and-arrays/tuples-and-arrays.md -msgid "`[20, 30, 40]`, `[0; 3]`" -msgstr "`[20, 30, 40]`, `[0; 3]`" - -#: src/tuples-and-arrays/tuples-and-arrays.md -msgid "Tuples" -msgstr "Tuples" - -#: src/tuples-and-arrays/tuples-and-arrays.md -msgid "`()`, `(T,)`, `(T1, T2)`, ..." -msgstr "`()`, `(T,)`, `(T1, T2)`, ..." - -#: src/tuples-and-arrays/tuples-and-arrays.md -msgid "`()`, `('x',)`, `('x', 1.2)`, ..." -msgstr "`()`, `('x',)`, `('x', 1.2)`, ..." - -#: src/tuples-and-arrays/tuples-and-arrays.md -msgid "Array assignment and access:" -msgstr "āĻ…ā§āϝāĻžāϰ⧇ āĻ…ā§āϝāĻžāϏāĻžāχāύāĻŽā§‡āĻ¨ā§āϟ āĻāĻŦāĻ‚ āĻ…ā§āϝāĻžāĻ•ā§āϏ⧇āϏ:" - -#: src/tuples-and-arrays/tuples-and-arrays.md -msgid "Tuple assignment and access:" -msgstr "Tuple assignment and access:" - -#: src/tuples-and-arrays/tuples-and-arrays.md -msgid "Arrays:" -msgstr "āĻ…ā§āϝāĻžāϰ⧇:" - -#: src/tuples-and-arrays/tuples-and-arrays.md +#: src/tuples-and-arrays/arrays.md msgid "" "A value of the array type `[T; N]` holds `N` (a compile-time constant) " "elements of the same type `T`. Note that the length of the array is _part of " @@ -4016,18 +5118,49 @@ msgid "" "covered later." msgstr "" -#: src/tuples-and-arrays/tuples-and-arrays.md +#: src/tuples-and-arrays/arrays.md msgid "" -"Try accessing an out-of-bounds array element. Array accesses are checked at " -"runtime. Rust can usually optimize these checks away, and they can be " -"avoided using unsafe Rust." +"Try accessing an out-of-bounds array element. The compiler is able to " +"determine that the index is unsafe, and will not compile the code:" msgstr "" -#: src/tuples-and-arrays/tuples-and-arrays.md +#: src/tuples-and-arrays/arrays.md +msgid "\"a: {a:?}\"" +msgstr "" + +#: src/tuples-and-arrays/arrays.md +msgid "" +"Array accesses are checked at runtime. Rust optimizes these checks away when " +"possible; meaning if the compiler can prove the access is safe, it removes " +"the runtime check for better performance. They can be avoided using unsafe " +"Rust. The optimization is so good that it's hard to give an example of " +"runtime checks failing. The following code will compile but panic at runtime:" +msgstr "" + +#: src/tuples-and-arrays/arrays.md msgid "We can use literals to assign values to arrays." msgstr "" -#: src/tuples-and-arrays/tuples-and-arrays.md +#: src/tuples-and-arrays/arrays.md +msgid "" +"Arrays are not heap-allocated. They are regular values with a fixed size " +"known at compile time, meaning they go on the stack. This can be different " +"from what students expect if they come from a garbage-collected language, " +"where arrays may be heap allocated by default." +msgstr "" + +#: src/tuples-and-arrays/arrays.md +msgid "" +"There is no way to remove elements from an array, nor add elements to an " +"array. The length of an array is fixed at compile-time, and so its length " +"cannot change at runtime." +msgstr "" + +#: src/tuples-and-arrays/arrays.md +msgid "Debug Printing" +msgstr "" + +#: src/tuples-and-arrays/arrays.md msgid "" "The `println!` macro asks for the debug implementation with the `?` format " "parameter: `{}` gives the default output, `{:?}` gives the debug output. " @@ -4036,42 +5169,44 @@ msgid "" "here." msgstr "" -#: src/tuples-and-arrays/tuples-and-arrays.md +#: src/tuples-and-arrays/arrays.md msgid "" "Adding `#`, eg `{a:#?}`, invokes a \"pretty printing\" format, which can be " "easier to read." msgstr "" -#: src/tuples-and-arrays/tuples-and-arrays.md -msgid "Tuples:" -msgstr "Tuples:" - -#: src/tuples-and-arrays/tuples-and-arrays.md +#: src/tuples-and-arrays/tuples.md msgid "Like arrays, tuples have a fixed length." msgstr "" -#: src/tuples-and-arrays/tuples-and-arrays.md +#: src/tuples-and-arrays/tuples.md msgid "Tuples group together values of different types into a compound type." msgstr "" -#: src/tuples-and-arrays/tuples-and-arrays.md +#: src/tuples-and-arrays/tuples.md msgid "" "Fields of a tuple can be accessed by the period and the index of the value, " "e.g. `t.0`, `t.1`." msgstr "" -#: src/tuples-and-arrays/tuples-and-arrays.md +#: src/tuples-and-arrays/tuples.md msgid "" -"The empty tuple `()` is also known as the \"unit type\". It is both a type, " -"and the only valid value of that type --- that is to say both the type and " -"its value are expressed as `()`. It is used to indicate, for example, that a " -"function or expression has no return value, as we'll see in a future slide." +"The empty tuple `()` is referred to as the \"unit type\" and signifies " +"absence of a return value, akin to `void` in other languages." msgstr "" -#: src/tuples-and-arrays/tuples-and-arrays.md +#: src/tuples-and-arrays/tuples.md msgid "" -"You can think of it as `void` that can be familiar to you from other " -"programming languages." +"Unlike arrays, tuples cannot be used in a `for` loop. This is because a " +"`for` loop requires all the elements to have the same type, which may not be " +"the case for a tuple." +msgstr "" + +#: src/tuples-and-arrays/tuples.md +msgid "" +"There is no way to add or remove elements from a tuple. The number of " +"elements and their types are fixed at compile time and cannot be changed at " +"runtime." msgstr "" #: src/tuples-and-arrays/iteration.md @@ -4087,33 +5222,26 @@ msgstr "" #: src/tuples-and-arrays/iteration.md msgid "" "The `assert_ne!` macro is new here. There are also `assert_eq!` and `assert!" -"` macros. These are always checked while, debug-only variants like " +"` macros. These are always checked, while debug-only variants like " "`debug_assert!` compile to nothing in release builds." msgstr "" #: src/tuples-and-arrays/destructuring.md msgid "" -"When working with tuples and other structured values it's common to want to " -"extract the inner values into local variables. This can be done manually by " -"directly accessing the inner values:" +"Rust supports using pattern matching to destructure a larger value like a " +"tuple into its constituent parts:" msgstr "" #: src/tuples-and-arrays/destructuring.md -msgid "\"left: {left}, right: {right}\"" +msgid "\"{tuple:?}: {}\"" msgstr "" #: src/tuples-and-arrays/destructuring.md -msgid "" -"However, Rust also supports using pattern matching to destructure a larger " -"value into its constituent parts:" +msgid "\"ordered\"" msgstr "" #: src/tuples-and-arrays/destructuring.md -msgid "This works with any kind of structured value:" -msgstr "" - -#: src/tuples-and-arrays/destructuring.md -msgid "\"a: {a}, b: {b}\"" +msgid "\"unordered\"" msgstr "" #: src/tuples-and-arrays/destructuring.md @@ -4152,27 +5280,14 @@ msgstr "" #: src/tuples-and-arrays/exercise.md msgid "" -"Use an array such as the above to write a function `transpose` which will " -"transpose a matrix (turn rows into columns):" -msgstr "" - -#: src/tuples-and-arrays/exercise.md -msgid "Hard-code both functions to operate on 3 × 3 matrices." +"Use an array such as the above to write a function `transpose` that " +"transposes a matrix (turns rows into columns):" msgstr "" #: src/tuples-and-arrays/exercise.md msgid "" "Copy the code below to and implement the " -"functions:" -msgstr "" - -#: src/tuples-and-arrays/exercise.md src/borrowing/exercise.md -#: src/unsafe-rust/exercise.md -msgid "// TODO: remove this when you're done with your implementation." -msgstr "" - -#: src/tuples-and-arrays/exercise.md src/tuples-and-arrays/solution.md -msgid "//\n" +"function. This function only operates on 3×3 matrices." msgstr "" #: src/tuples-and-arrays/exercise.md src/tuples-and-arrays/solution.md @@ -4180,30 +5295,77 @@ msgid "// <-- the comment makes rustfmt add a newline\n" msgstr "" #: src/tuples-and-arrays/exercise.md src/tuples-and-arrays/solution.md -msgid "\"matrix: {:#?}\"" +msgid "\"Original:\"" msgstr "" #: src/tuples-and-arrays/exercise.md src/tuples-and-arrays/solution.md -msgid "\"transposed: {:#?}\"" +msgid "\"{row:?}\"" msgstr "" -#: src/references.md -msgid "[Shared References](./references/shared.md) (10 minutes)" +#: src/tuples-and-arrays/exercise.md src/tuples-and-arrays/solution.md +msgid "\"\\nTransposed:\"" msgstr "" -#: src/references.md -msgid "[Exclusive References](./references/exclusive.md) (10 minutes)" +#: src/tuples-and-arrays/solution.md +msgid "" +"**Array Types:** The type `[[i32; 3]; 3]` represents an array of size 3, " +"where each element is itself an array of 3 `i32`s. This is how multi-" +"dimensional arrays are typically represented in Rust." msgstr "" -#: src/references.md -msgid "[Exercise: Geometry](./references/exercise.md) (15 minutes)" +#: src/tuples-and-arrays/solution.md +msgid "" +"**Initialization:** We initialize `result` with zeros (`[[0; 3]; 3]`) before " +"filling it. Rust requires all variables to be initialized before use; there " +"is no concept of \"uninitialized memory\" in safe Rust." +msgstr "" + +#: src/tuples-and-arrays/solution.md +msgid "" +"**Copy Semantics:** Arrays of `Copy` types (like `i32`) are themselves " +"`Copy`. When we pass `matrix` to the function, it is copied by value. The " +"`result` variable is a new, separate array." +msgstr "" + +#: src/tuples-and-arrays/solution.md +msgid "" +"**Iteration:** We use standard `for` loops with ranges (`0..3`) to iterate " +"over indices. Rust also has powerful iterators, which we will see later, but " +"indexing is straightforward for this matrix transposition." +msgstr "" + +#: src/tuples-and-arrays/solution.md +msgid "" +"Mention that `[i32; 3]` is a distinct type from `[i32; 4]`. Array sizes are " +"part of the type signature." +msgstr "" + +#: src/tuples-and-arrays/solution.md +msgid "" +"Ask students what would happen if they tried to return `matrix` directly " +"after modifying it (if they changed the signature to `mut matrix`). (Answer: " +"It would work, but it would return a modified _copy_, leaving the original " +"in `main` unchanged)." +msgstr "" + +#: src/references.md src/smart-pointers.md src/iterators.md +#: src/error-handling.md src/concurrency/async-pitfalls.md +msgid "This segment should take about 55 minutes. It contains:" msgstr "" #: src/references/shared.md msgid "" -"A reference provides a way to access another value without taking " -"responsibility for the value, and is also called \"borrowing\". Shared " -"references are read-only, and the referenced data cannot change." +"A reference provides a way to access another value without taking ownership " +"of the value, and is also called \"borrowing\". Shared references are read-" +"only, and the referenced data cannot change." +msgstr "" + +#: src/references/shared.md src/std-traits/solution.md +msgid "'A'" +msgstr "" + +#: src/references/shared.md +msgid "'B'" msgstr "" #: src/references/shared.md @@ -4214,7 +5376,8 @@ msgid "" msgstr "" #: src/references/shared.md -msgid "Rust will statically forbid dangling references:" +msgid "" +"References can never be null in Rust, so null checking is not necessary." msgstr "" #: src/references/shared.md @@ -4236,8 +5399,8 @@ msgstr "" #: src/references/shared.md msgid "" -"Rust does not automatically create references for you - the `&` is always " -"required." +"Explicit referencing with `&` is required, except when invoking methods, " +"where Rust performs automatic referencing and dereferencing." msgstr "" #: src/references/shared.md @@ -4264,13 +5427,13 @@ msgstr "" #: src/references/shared.md msgid "" "Rust is tracking the lifetimes of all references to ensure they live long " -"enough. Dangling references cannot occur in safe Rust. `x_axis` would return " -"a reference to `point`, but `point` will be deallocated when the function " -"returns, so this will not compile." +"enough. Dangling references cannot occur in safe Rust." msgstr "" #: src/references/shared.md -msgid "We will talk more about borrowing when we get to ownership." +msgid "" +"We will talk more about borrowing and preventing dangling references when we " +"get to ownership." msgstr "" #: src/references/exclusive.md @@ -4291,9 +5454,191 @@ msgstr "" #: src/references/exclusive.md msgid "" "Be sure to note the difference between `let mut x_coord: &i32` and `let " -"x_coord: &mut i32`. The first one represents a shared reference which can be " -"bound to different values, while the second represents an exclusive " -"reference to a mutable value." +"x_coord: &mut i32`. The first one is a shared reference that can be bound to " +"different values, while the second is an exclusive reference to a mutable " +"value." +msgstr "" + +#: src/references/slices.md +msgid "A slice gives you a view into a larger collection:" +msgstr "" + +#: src/references/slices.md +msgid "Slices borrow data from the sliced type." +msgstr "" + +#: src/references/slices.md +msgid "" +"We create a slice by borrowing `a` and specifying the starting and ending " +"indexes in brackets." +msgstr "" + +#: src/references/slices.md +msgid "" +"If the slice starts at index 0, Rust’s range syntax allows us to drop the " +"starting index, meaning that `&a[0..a.len()]` and `&a[..a.len()]` are " +"identical." +msgstr "" + +#: src/references/slices.md +msgid "" +"The same is true for the last index, so `&a[2..a.len()]` and `&a[2..]` are " +"identical." +msgstr "" + +#: src/references/slices.md +msgid "" +"To easily create a slice of the full array, we can therefore use `&a[..]`." +msgstr "" + +#: src/references/slices.md +msgid "" +"`s` is a reference to a slice of `i32`s. Notice that the type of `s` " +"(`&[i32]`) no longer mentions the array length. This allows us to perform " +"computation on slices of different sizes." +msgstr "" + +#: src/references/slices.md +msgid "" +"Slices always borrow from another object. In this example, `a` has to remain " +"'alive' (in scope) for at least as long as our slice." +msgstr "" + +#: src/references/slices.md +msgid "You can't \"grow\" a slice once it's created:" +msgstr "" + +#: src/references/slices.md +msgid "" +"You can't append elements of the slice, since it doesn't own the backing " +"buffer." +msgstr "" + +#: src/references/slices.md +msgid "" +"You can't grow a slice to point to a larger section of the backing buffer. A " +"slice does not have information about the length of the underlying buffer " +"and so you can't know how large the slice can be grown." +msgstr "" + +#: src/references/slices.md +msgid "" +"To get a larger slice you have to go back to the original buffer and create " +"a larger slice from there." +msgstr "" + +#: src/references/strings.md +msgid "We can now understand the two string types in Rust:" +msgstr "" + +#: src/references/strings.md +msgid "`&str` is a slice of UTF-8 encoded bytes, similar to `&[u8]`." +msgstr "" + +#: src/references/strings.md +msgid "" +"`String` is an owned buffer of UTF-8 encoded bytes, similar to `Vec`." +msgstr "" + +#: src/references/strings.md src/std-traits/read-and-write.md +msgid "\"World\"" +msgstr "" + +#: src/references/strings.md +msgid "\"s1: {s1}\"" +msgstr "" + +#: src/references/strings.md +msgid "\"Hello \"" +msgstr "" + +#: src/references/strings.md +msgid "\"s2: {s2}\"" +msgstr "" + +#: src/references/strings.md +msgid "\"s3: {s3}\"" +msgstr "" + +#: src/references/strings.md +msgid "" +"`&str` introduces a string slice, which is an immutable reference to UTF-8 " +"encoded string data stored in a block of memory. String literals " +"(`\"Hello\"`), are stored in the program’s binary." +msgstr "" + +#: src/references/strings.md +msgid "" +"Rust's `String` type is a wrapper around a vector of bytes. As with a " +"`Vec`, it is owned." +msgstr "" + +#: src/references/strings.md +msgid "" +"As with many other types `String::from()` creates a string from a string " +"literal; `String::new()` creates a new empty string, to which string data " +"can be added using the `push()` and `push_str()` methods." +msgstr "" + +#: src/references/strings.md +msgid "" +"The `format!()` macro is a convenient way to generate an owned string from " +"dynamic values. It accepts the same format specification as `println!()`." +msgstr "" + +#: src/references/strings.md +msgid "" +"You can borrow `&str` slices from `String` via `&` and optionally range " +"selection. If you select a byte range that is not aligned to character " +"boundaries, the expression will panic. The `chars` iterator iterates over " +"characters and is preferred over trying to get character boundaries right." +msgstr "" + +#: src/references/strings.md +msgid "" +"For C++ programmers: think of `&str` as `std::string_view` from C++, but the " +"one that always points to a valid string in memory. Rust `String` is a rough " +"equivalent of `std::string` from C++ (main difference: it can only contain " +"UTF-8 encoded bytes and will never use a small-string optimization)." +msgstr "" + +#: src/references/strings.md +msgid "Byte strings literals allow you to create a `&[u8]` value directly:" +msgstr "" + +#: src/references/strings.md +msgid "" +"Raw strings allow you to create a `&str` value with escapes disabled: " +"`r\"\\n\" == \"\\\\n\"`. You can embed double-quotes by using an equal " +"amount of `#` on either side of the quotes:" +msgstr "" + +#: src/references/dangling.md +msgid "" +"Rust enforces a number of rules for references that make them always safe to " +"use. One rule is that references can never be `null`, making them safe to " +"use without `null` checks. The other rule we'll look at for now is that " +"references can't _outlive_ the data they point to." +msgstr "" + +#: src/references/dangling.md +msgid "" +"This slide gets students thinking about references as not simply being " +"pointers, since Rust has different rules for references than other languages." +msgstr "" + +#: src/references/dangling.md +msgid "" +"We'll look at the rest of Rust's borrowing rules on day 3 when we talk about " +"Rust's ownership system." +msgstr "" + +#: src/references/dangling.md +msgid "" +"Rust's equivalent of nullability is the `Option` type, which can be used to " +"make any type \"nullable\" (not just references/pointers). We haven't yet " +"introduced enums or pattern matching, though, so try not to go into too much " +"detail about this here." msgstr "" #: src/references/exercise.md @@ -4306,30 +5651,20 @@ msgstr "" #: src/references/exercise.md msgid "" "// Calculate the magnitude of a vector by summing the squares of its " -"coordinates" -msgstr "" - -#: src/references/exercise.md -msgid "" +"coordinates\n" "// and taking the square root. Use the `sqrt()` method to calculate the " -"square" -msgstr "" - -#: src/references/exercise.md -msgid "// root, like `v.sqrt()`." +"square\n" +"// root, like `v.sqrt()`.\n" msgstr "" #: src/references/exercise.md msgid "" -"// Normalize a vector by calculating its magnitude and dividing all of its" +"// Normalize a vector by calculating its magnitude and dividing all of its\n" +"// coordinates by that magnitude.\n" msgstr "" #: src/references/exercise.md -msgid "// coordinates by that magnitude." -msgstr "" - -#: src/references/exercise.md -msgid "// Use the following `main` to test your work." +msgid "// Use the following `main` to test your work.\n" msgstr "" #: src/references/exercise.md src/references/solution.md @@ -4354,34 +5689,24 @@ msgid "" "direction.\n" msgstr "" -#: src/user-defined-types.md -msgid "[Named Structs](./user-defined-types/named-structs.md) (10 minutes)" -msgstr "" - -#: src/user-defined-types.md -msgid "[Tuple Structs](./user-defined-types/tuple-structs.md) (10 minutes)" -msgstr "" - -#: src/user-defined-types.md -msgid "[Enums](./user-defined-types/enums.md) (5 minutes)" -msgstr "" - -#: src/user-defined-types.md +#: src/references/solution.md msgid "" -"[Static and Const](./user-defined-types/static-and-const.md) (5 minutes)" +"Note that in `normalize` we were able to do `*item /= mag` to modify each " +"element. This is because we're iterating using a mutable reference to an " +"array, which causes the `for` loop to give mutable references to each " +"element." msgstr "" -#: src/user-defined-types.md -msgid "[Type Aliases](./user-defined-types/aliases.md) (2 minutes)" -msgstr "" - -#: src/user-defined-types.md +#: src/references/solution.md msgid "" -"[Exercise: Elevator Events](./user-defined-types/exercise.md) (15 minutes)" +"It is also possible to take slice references here, e.g., `fn " +"magnitude(vector: &[f64]) -> f64`. This makes the function more general, at " +"the cost of a runtime length check." msgstr "" -#: src/user-defined-types.md src/borrowing.md -msgid "This segment should take about 50 minutes" +#: src/user-defined-types.md src/std-types.md src/std-traits.md +#: src/memory-management.md +msgid "This segment should take about 1 hour. It contains:" msgstr "" #: src/user-defined-types/named-structs.md @@ -4401,10 +5726,6 @@ msgstr "" msgid "\"Avery\"" msgstr "" -#: src/user-defined-types/named-structs.md -msgid "\"Jackie\"" -msgstr "" - #: src/user-defined-types/named-structs.md src/user-defined-types/enums.md #: src/pattern-matching/match.md src/methods-and-traits/methods.md msgid "Key Points:" @@ -4449,9 +5770,29 @@ msgstr "" #: src/user-defined-types/named-structs.md msgid "" -"The syntax `..avery` allows us to copy the majority of the fields from the " -"old struct without having to explicitly type it all out. It must always be " -"the last element." +"Struct fields do not support default values. Default values are specified by " +"implementing the `Default` trait which we will cover later." +msgstr "" + +#: src/user-defined-types/named-structs.md +msgid "You can also demonstrate the struct update syntax here:" +msgstr "" + +#: src/user-defined-types/named-structs.md +msgid "\"Jackie\"" +msgstr "" + +#: src/user-defined-types/named-structs.md +msgid "" +"It allows us to copy the majority of the fields from the old struct without " +"having to explicitly type it all out. It must always be the last element." +msgstr "" + +#: src/user-defined-types/named-structs.md +msgid "" +"It is mainly used in combination with the `Default` trait. We will talk " +"about struct update syntax in more detail on the slide on the `Default` " +"trait, so we don't need to talk about it here unless students ask about it." msgstr "" #: src/user-defined-types/tuple-structs.md @@ -4472,8 +5813,13 @@ msgstr "" #: src/user-defined-types/tuple-structs.md #: src/android/interoperability/cpp/cpp-bridge.md -#: src/async/pitfalls/cancellation.md -msgid "// ..." +#: src/bare-metal/microcontrollers/type-state.md +#: src/concurrency/async-pitfalls/cancellation.md +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/who-are-you-writing-for.md +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-why-not-how-where.md +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-impl.md +#: src/unsafe-deep-dive/pinning/drop-and-not-unpin-worked-example.md +msgid "// ...\n" msgstr "" #: src/user-defined-types/tuple-structs.md @@ -4492,6 +5838,12 @@ msgid "" "to validate it again at every use: `PhoneNumber(String)` or `OddNumber(u32)`." msgstr "" +#: src/user-defined-types/tuple-structs.md +msgid "" +"The newtype pattern is covered extensively in the [\"Idiomatic Rust\" module]" +"(../idiomatic/leveraging-the-type-system/newtype-pattern.md)." +msgstr "" + #: src/user-defined-types/tuple-structs.md msgid "" "Demonstrate how to add a `f64` value to a `Newtons` type by accessing the " @@ -4500,12 +5852,28 @@ msgstr "" #: src/user-defined-types/tuple-structs.md msgid "" -"Rust generally doesn’t like inexplicit things, like automatic unwrapping or " -"for instance using booleans as integers." +"Rust generally avoids implicit conversions, like automatic unwrapping or " +"using booleans as integers." msgstr "" #: src/user-defined-types/tuple-structs.md -msgid "Operator overloading is discussed on Day 3 (generics)." +msgid "" +"Operator overloading is discussed on Day 2 ([Standard Library Traits](../std-" +"traits.md))." +msgstr "" + +#: src/user-defined-types/tuple-structs.md +msgid "" +"When a tuple struct has zero fields, the `()` can be omitted. The result is " +"a zero-sized type (ZST), of which there is only one value (the name of the " +"type)." +msgstr "" + +#: src/user-defined-types/tuple-structs.md +msgid "" +"This is common for types that implement some behavior but have no data " +"(imagine a `NullReader` that implements some reader behavior by always " +"returning EOF)." msgstr "" #: src/user-defined-types/tuple-structs.md @@ -4521,25 +5889,24 @@ msgid "" msgstr "" #: src/user-defined-types/enums.md -msgid "// Simple variant" +msgid "// Simple variant\n" msgstr "" #: src/user-defined-types/enums.md -msgid "// Tuple variant" +msgid "// Tuple variant\n" msgstr "" #: src/user-defined-types/enums.md -msgid "// Struct variant" +msgid "// Struct variant\n" msgstr "" #: src/user-defined-types/enums.md -msgid "\"On this turn: {:?}\"" +msgid "\"On this turn: {player_move:?}\"" msgstr "" #: src/user-defined-types/enums.md -#, fuzzy msgid "Enumerations allow you to collect a set of values under one type." -msgstr "Byte strings allow you to create a `&[u8]` value directly:" +msgstr "" #: src/user-defined-types/enums.md msgid "" @@ -4598,12 +5965,6 @@ msgid "" "bytes." msgstr "" -#: src/user-defined-types/enums.md src/user-defined-types/static-and-const.md -#: src/memory-management/review.md src/memory-management/move.md -#: src/smart-pointers/box.md src/borrowing/shared.md -msgid "More to Explore" -msgstr "" - #: src/user-defined-types/enums.md msgid "" "Rust has several optimizations it can employ to make enums take up less " @@ -4624,55 +5985,67 @@ msgid "" "guarantees regarding this representation, therefore this is totally unsafe." msgstr "" -#: src/user-defined-types/static-and-const.md +#: src/user-defined-types/aliases.md msgid "" -"Static and constant variables are two different ways to create globally-" -"scoped values that cannot be moved or reallocated during the execution of " -"the program." +"A type alias creates a name for another type. The two types can be used " +"interchangeably." msgstr "" -#: src/user-defined-types/static-and-const.md +#: src/user-defined-types/aliases.md +msgid "// Aliases are more useful with long, complex types:\n" +msgstr "" + +#: src/user-defined-types/aliases.md +msgid "" +"A [newtype](tuple-structs.html) is often a better alternative since it " +"creates a distinct type. Prefer `struct InventoryCount(usize)` to `type " +"InventoryCount = usize`." +msgstr "" + +#: src/user-defined-types/aliases.md +msgid "C programmers will recognize this as similar to a `typedef`." +msgstr "" + +#: src/user-defined-types/const.md msgid "`const`" msgstr "" -#: src/user-defined-types/static-and-const.md +#: src/user-defined-types/const.md msgid "" -"Constant variables are evaluated at compile time and their values are " -"inlined wherever they are used:" +"Constants are evaluated at compile time and their values are [inlined]" +"(https://rust-lang.github.io/rfcs/0246-const-vs-static.html) wherever they " +"are used:" msgstr "" -#: src/user-defined-types/static-and-const.md -msgid "" -"According to the [Rust RFC Book](https://rust-lang.github.io/rfcs/0246-const-" -"vs-static.html) these are inlined upon use." -msgstr "" - -#: src/user-defined-types/static-and-const.md +#: src/user-defined-types/const.md msgid "" "Only functions marked `const` can be called at compile time to generate " "`const` values. `const` functions can however be called at runtime." msgstr "" -#: src/user-defined-types/static-and-const.md +#: src/user-defined-types/const.md +msgid "Mention that `const` behaves semantically similar to C++'s `constexpr`" +msgstr "" + +#: src/user-defined-types/static.md msgid "`static`" msgstr "" -#: src/user-defined-types/static-and-const.md +#: src/user-defined-types/static.md msgid "" "Static variables will live during the whole execution of the program, and " "therefore will not move:" msgstr "" -#: src/user-defined-types/static-and-const.md -#, fuzzy +#: src/user-defined-types/static.md msgid "\"Welcome to RustOS 3.14\"" -msgstr "āĻĒā§āϰāĻĨāĻŽ āĻĻāĻŋāύ⧇ āφāĻĒāύāĻžāϕ⧇ āĻ¸ā§āĻŦāĻžāĻ—āϤāĻŽ" +msgstr "" -#: src/user-defined-types/static-and-const.md +#: src/user-defined-types/static.md msgid "\"{BANNER}\"" msgstr "" -#: src/user-defined-types/static-and-const.md +#: src/user-defined-types/static.md msgid "" "As noted in the [Rust RFC Book](https://rust-lang.github.io/rfcs/0246-const-" "vs-static.html), these are not inlined upon use and have an actual " @@ -4682,110 +6055,32 @@ msgid "" "`const` is generally preferred." msgstr "" -#: src/user-defined-types/static-and-const.md -msgid "Mention that `const` behaves semantically similar to C++'s `constexpr`." +#: src/user-defined-types/static.md +msgid "`static` is similar to mutable global variables in C++." msgstr "" -#: src/user-defined-types/static-and-const.md -msgid "" -"`static`, on the other hand, is much more similar to a `const` or mutable " -"global variable in C++." -msgstr "" - -#: src/user-defined-types/static-and-const.md +#: src/user-defined-types/static.md msgid "" "`static` provides object identity: an address in memory and state as " "required by types with interior mutability such as `Mutex`." msgstr "" -#: src/user-defined-types/static-and-const.md -msgid "" -"It isn't super common that one would need a runtime evaluated constant, but " -"it is helpful and safer than using a static." -msgstr "" - -#: src/user-defined-types/static-and-const.md -msgid "Properties table:" -msgstr "" - -#: src/user-defined-types/static-and-const.md -#: src/chromium/adding-third-party-crates.md -msgid "Property" -msgstr "" - -#: src/user-defined-types/static-and-const.md -msgid "Static" -msgstr "" - -#: src/user-defined-types/static-and-const.md -msgid "Constant" -msgstr "" - -#: src/user-defined-types/static-and-const.md -msgid "Has an address in memory" -msgstr "" - -#: src/user-defined-types/static-and-const.md -#: src/chromium/adding-third-party-crates/resolving-problems.md -msgid "Yes" -msgstr "" - -#: src/user-defined-types/static-and-const.md -msgid "No (inlined)" -msgstr "" - -#: src/user-defined-types/static-and-const.md -msgid "Lives for the entire duration of the program" -msgstr "" - -#: src/user-defined-types/static-and-const.md -#: src/chromium/adding-third-party-crates/resolving-problems.md -msgid "No" -msgstr "" - -#: src/user-defined-types/static-and-const.md -msgid "Can be mutable" -msgstr "" - -#: src/user-defined-types/static-and-const.md -msgid "Yes (unsafe)" -msgstr "" - -#: src/user-defined-types/static-and-const.md -msgid "Evaluated at compile time" -msgstr "" - -#: src/user-defined-types/static-and-const.md -msgid "Yes (initialised at compile time)" -msgstr "" - -#: src/user-defined-types/static-and-const.md -msgid "Inlined wherever it is used" -msgstr "" - -#: src/user-defined-types/static-and-const.md +#: src/user-defined-types/static.md msgid "" "Because `static` variables are accessible from any thread, they must be " "`Sync`. Interior mutability is possible through a [`Mutex`](https://doc.rust-" "lang.org/std/sync/struct.Mutex.html), atomic or similar." msgstr "" -#: src/user-defined-types/static-and-const.md -msgid "Thread-local data can be created with the macro `std::thread_local`." -msgstr "" - -#: src/user-defined-types/aliases.md +#: src/user-defined-types/static.md msgid "" -"A type alias creates a name for another type. The two types can be used " -"interchangeably." +"It is common to use `OnceLock` in a static as a way to support " +"initialization on first use. `OnceCell` is not `Sync` and thus cannot be " +"used in this context." msgstr "" -#: src/user-defined-types/aliases.md -msgid "// Aliases are more useful with long, complex types:" -msgstr "" - -#: src/user-defined-types/aliases.md -msgid "C programmers will recognize this as similar to a `typedef`." +#: src/user-defined-types/static.md +msgid "Thread-local data can be created with the macro `std::thread_local`." msgstr "" #: src/user-defined-types/exercise.md @@ -4809,7 +6104,7 @@ msgid "" msgstr "" #: src/user-defined-types/exercise.md -msgid "// TODO: add required variants" +msgid "// TODO: add required variants\n" msgstr "" #: src/user-defined-types/exercise.md src/user-defined-types/solution.md @@ -4862,6 +6157,15 @@ msgstr "" msgid "\"The car has arrived on the 3rd floor: {:?}\"" msgstr "" +#: src/user-defined-types/exercise.md +msgid "" +"If students ask about `#![allow(dead_code)]` at the top of the exercise, " +"it's necessary because the only thing we do with the `Event` type is print " +"it out. Due to a nuance of how the compiler checks for dead code this causes " +"it to think the code is unused. They can ignore it for the purpose of this " +"exercise." +msgstr "" + #: src/user-defined-types/solution.md msgid "/// A button was pressed.\n" msgstr "" @@ -4894,89 +6198,281 @@ msgstr "" msgid "/// A floor button within the car.\n" msgstr "" +#: src/user-defined-types/solution.md +msgid "" +"**Enums with Data:** Rust `enum` variants can carry data. " +"`CarArrived(Floor)` carries an integer, and `ButtonPressed(Button)` carries " +"a nested `Button` enum. This allows `Event` to represent a rich set of " +"states in a type-safe way." +msgstr "" + +#: src/user-defined-types/solution.md +msgid "" +"**Type Aliases:** `type Floor = i32` gives a semantic name to `i32`. This " +"improves readability, but `Floor` is still just an `i32` to the compiler." +msgstr "" + +#: src/user-defined-types/solution.md +msgid "" +"**`#[derive(Debug)]`:** We use this attribute to automatically generate code " +"to format the enums for printing with `{:?}`. Without this, we would have to " +"manually implement the `fmt::Debug` trait." +msgstr "" + +#: src/user-defined-types/solution.md +msgid "" +"**Nested Enums:** The `Button` enum is nested inside `Event::ButtonPressed`. " +"This hierarchical structure is common in Rust for modeling complex domains." +msgstr "" + +#: src/user-defined-types/solution.md +msgid "" +"Note that `Event::CarDoorOpened` is a \"unit variant\" (it carries no data), " +"while `Event::CarArrived` is a \"tuple variant\"." +msgstr "" + +#: src/user-defined-types/solution.md +msgid "" +"You might discuss why `Button` is a separate enum rather than just having " +"`LobbyCallButtonPressed` and `CarFloorButtonPressed` variants on `Event`. " +"Both are valid, but grouping related concepts (like buttons) can make the " +"code cleaner." +msgstr "" + #: src/welcome-day-2.md msgid "Welcome to Day 2" msgstr "" #: src/welcome-day-2.md -msgid "" -"Now that we have seen a fair amount of Rust, today will focus on Rust's type " -"system:" +msgid "We have covered the foundations of Rust:" msgstr "" #: src/welcome-day-2.md -msgid "Pattern matching: extracting data from structures." +msgid "**Basic Types:** Integers, booleans, characters, tuples, and arrays." msgstr "" #: src/welcome-day-2.md -msgid "Methods: associating functions with types." +msgid "**Control Flow:** `if` expressions, loops, and `match` expressions." msgstr "" #: src/welcome-day-2.md -msgid "Traits: behaviors shared by multiple types." +msgid "**Functions:** How to define and call functions." msgstr "" #: src/welcome-day-2.md -msgid "Generics: parameterizing types on other types." +msgid "**User-Defined Types:** Model data with `struct` and `enum`." msgstr "" #: src/welcome-day-2.md -msgid "" -"Standard library types and traits: a tour of Rust's rich standard library." +msgid "**References:** Basic borrowing with `&` and `&mut`." msgstr "" #: src/welcome-day-2.md -msgid "[Welcome](./welcome-day-2.md) (3 minutes)" +msgid "You can now construct any type in Rust and implement basic logic!" msgstr "" -#: src/welcome-day-2.md -msgid "[Pattern Matching](./pattern-matching.md) (1 hour)" -msgstr "" - -#: src/welcome-day-2.md -msgid "[Methods and Traits](./methods-and-traits.md) (45 minutes)" -msgstr "" - -#: src/welcome-day-2.md -msgid "[Generics](./generics.md) (40 minutes)" -msgstr "" - -#: src/welcome-day-2.md src/welcome-day-4.md +#: src/welcome-day-2.md src/welcome-day-2-afternoon.md src/welcome-day-4.md msgid "" "Including 10 minute breaks, this session should take about 2 hours and 50 " -"minutes" +"minutes. It contains:" msgstr "" -#: src/pattern-matching.md -msgid "[Matching Values](./pattern-matching/match.md) (10 minutes)" +#: src/pattern-matching.md src/generics.md +msgid "This segment should take about 50 minutes. It contains:" msgstr "" -#: src/pattern-matching.md -msgid "[Destructuring](./pattern-matching/destructuring.md) (10 minutes)" -msgstr "" - -#: src/pattern-matching.md -msgid "[Let Control Flow](./pattern-matching/let-control-flow.md) (10 minutes)" -msgstr "" - -#: src/pattern-matching.md +#: src/pattern-matching/infallible.md msgid "" -"[Exercise: Expression Evaluation](./pattern-matching/exercise.md) (30 " -"minutes)" +"In day 1 we briefly saw how patterns can be used to _destructure_ compound " +"values. Let's review that and talk about a few other things patterns can " +"express:" msgstr "" -#: src/pattern-matching.md src/memory-management.md src/testing.md -msgid "This segment should take about 1 hour" +#: src/pattern-matching/infallible.md +#: src/pattern-matching/let-control-flow/if-let.md +#: src/pattern-matching/let-control-flow/while-let.md +#: src/pattern-matching/let-control-flow/let-else.md src/closures/syntax.md +#: src/closures/capturing.md src/closures/traits.md src/closures/exercise.md +#: src/closures/solution.md src/borrowing/interior-mutability/cell.md +#: src/borrowing/interior-mutability/refcell.md src/lifetimes/simple-borrows.md +#: src/lifetimes/returning-borrows.md src/lifetimes/multiple-borrows.md +#: src/lifetimes/borrow-both.md src/lifetimes/borrow-one.md +#: src/unsafe-rust/unsafe-functions/rust.md +#: src/unsafe-rust/unsafe-functions/extern-c.md +#: src/unsafe-rust/unsafe-functions/calling.md +#: src/android/interoperability/with-c/rust-library.md +#: src/bare-metal/aps/uart/using.md src/bare-metal/aps/safemmio/driver.md +#: src/bare-metal/aps/safemmio/using.md src/bare-metal/aps/aarch64-rt.md +#: src/concurrency/async/state-machine.md +#: src/idiomatic/foundations-api-design/meaningful-doc-comments.md +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/who-are-you-writing-for.md +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/anatomy-of-a-doc-comment.md +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/name-drop-signpost.md +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-isnt-docs.md +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-why-not-how-where.md +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/exercise.md +#: src/idiomatic/foundations-api-design/predictable-api.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/new.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/get.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/push.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/is.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/mut.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-constructor.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-copy-setter.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-closure.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-word.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/try.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/from.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into_inner.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/by.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/unchecked.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/raw_parts.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/exercise.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/debug.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialeq-eq.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialord-ord.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/hash.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/clone.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/copy.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/serde.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/from-into.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/try-from-into.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/display.md +#: src/idiomatic/leveraging-the-type-system/newtype-pattern.md +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/semantic-confusion.md +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/parse-don-t-validate.md +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/is-it-encapsulated.md +#: src/idiomatic/leveraging-the-type-system/raii.md +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +#: src/idiomatic/leveraging-the-type-system/raii/mutex.md +#: src/idiomatic/leveraging-the-type-system/raii/drop_guards.md +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb_forget.md +#: src/idiomatic/leveraging-the-type-system/raii/forget_and_drop.md +#: src/idiomatic/leveraging-the-type-system/raii/scope_guard.md +#: src/idiomatic/leveraging-the-type-system/raii/drop_option.md +#: src/idiomatic/leveraging-the-type-system/extension-traits.md +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-foreign-types.md +#: src/idiomatic/leveraging-the-type-system/extension-traits/method-resolution-conflicts.md +#: src/idiomatic/leveraging-the-type-system/extension-traits/trait-method-conflicts.md +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +#: src/idiomatic/leveraging-the-type-system/extension-traits/should-i-define-an-extension-trait.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-example.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-advanced.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/root.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/struct.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/property.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/complete.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-01-types.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-02-types-implemented.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-04-borrowedfd.md +#: src/idiomatic/leveraging-the-type-system/token-types.md +#: src/idiomatic/leveraging-the-type-system/token-types/permission-tokens.md +#: src/idiomatic/leveraging-the-type-system/token-types/mutex-guard.md +#: src/idiomatic/leveraging-the-type-system/token-types/branded-01-motivation.md +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +#: src/idiomatic/leveraging-the-type-system/token-types/branded-03-impl.md +#: src/idiomatic/leveraging-the-type-system/token-types/branded-04-in-action.md +#: src/idiomatic/polymorphism.md src/idiomatic/polymorphism/refresher.md +#: src/idiomatic/polymorphism/refresher/traits.md +#: src/idiomatic/polymorphism/refresher/trait-bounds.md +#: src/idiomatic/polymorphism/refresher/deriving-traits.md +#: src/idiomatic/polymorphism/refresher/default-impls.md +#: src/idiomatic/polymorphism/refresher/supertraits.md +#: src/idiomatic/polymorphism/refresher/blanket-impls.md +#: src/idiomatic/polymorphism/refresher/conditional-methods.md +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +#: src/idiomatic/polymorphism/refresher/sized.md +#: src/idiomatic/polymorphism/refresher/monomorphization.md +#: src/idiomatic/polymorphism/from-oop-to-rust/why-no-inheritance.md +#: src/idiomatic/polymorphism/from-oop-to-rust/switch-perspective.md +#: src/idiomatic/polymorphism/from-oop-to-rust/supertraits.md +#: src/idiomatic/polymorphism/from-oop-to-rust/composition.md +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-trait.md +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-compatible.md +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-vs-generics.md +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/limits.md +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/heterogeneous.md +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/any-trait.md +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/pitfalls.md +#: src/idiomatic/polymorphism/from-oop-to-rust/sealed-traits.md +#: src/idiomatic/polymorphism/from-oop-to-rust/sealing-with-enums.md +#: src/idiomatic/polymorphism/from-oop-to-rust/sticking-with-traits.md +#: src/idiomatic/polymorphism/from-oop-to-rust/problem-solving.md +msgid "// Copyright 2025 Google LLC\n" +msgstr "" + +#: src/pattern-matching/infallible.md +msgid "// This does the same thing as above.\n" +msgstr "" + +#: src/pattern-matching/infallible.md +msgid "// Ignore the first element, only bind the second and third.\n" +msgstr "" + +#: src/pattern-matching/infallible.md +msgid "// Ignore everything but the last element.\n" +msgstr "" + +#: src/pattern-matching/infallible.md src/pattern-matching/match.md +#: src/generics/exercise.md src/generics/solution.md src/std-traits/solution.md +msgid "'a'" +msgstr "" + +#: src/pattern-matching/infallible.md +msgid "" +"All of the demonstrated patterns are _irrefutable_, meaning that they will " +"always match the value on the right hand side." +msgstr "" + +#: src/pattern-matching/infallible.md +msgid "" +"Patterns are type-specific, including irrefutable patterns. Try adding or " +"removing an element to the tuple and look at the resulting compiler errors." +msgstr "" + +#: src/pattern-matching/infallible.md +msgid "" +"Variable names are patterns that always match and bind the matched value " +"into a new variable with that name." +msgstr "" + +#: src/pattern-matching/infallible.md +msgid "" +"`_` is a pattern that always matches any value, discarding the matched value." +msgstr "" + +#: src/pattern-matching/infallible.md +msgid "`..` allows you to ignore multiple values at once." +msgstr "" + +#: src/pattern-matching/infallible.md +msgid "" +"You can also demonstrate more advanced usages of `..`, such as ignoring the " +"middle elements of a tuple." +msgstr "" + +#: src/pattern-matching/infallible.md +msgid "All of these patterns work with arrays as well:" msgstr "" #: src/pattern-matching/match.md msgid "" "The `match` keyword lets you match a value against one or more _patterns_. " -"The comparisons are done from top to bottom and the first match wins." -msgstr "" - -#: src/pattern-matching/match.md -msgid "The patterns can be simple values, similarly to `switch` in C and C++:" +"The patterns can be simple values, similarly to `switch` in C and C++, but " +"they can also be used to express more complex conditions:" msgstr "" #: src/pattern-matching/match.md @@ -4991,11 +6487,6 @@ msgstr "" msgid "\"Quitting\"" msgstr "" -#: src/pattern-matching/match.md src/std-traits/solution.md -#: src/error-handling/exercise.md src/error-handling/solution.md -msgid "'a'" -msgstr "" - #: src/pattern-matching/match.md msgid "'s'" msgstr "" @@ -5012,13 +6503,11 @@ msgstr "" msgid "\"Moving around\"" msgstr "" -#: src/pattern-matching/match.md src/error-handling/exercise.md -#: src/error-handling/solution.md +#: src/pattern-matching/match.md msgid "'0'" msgstr "" -#: src/pattern-matching/match.md src/error-handling/exercise.md -#: src/error-handling/solution.md +#: src/pattern-matching/match.md msgid "'9'" msgstr "" @@ -5034,28 +6523,17 @@ msgstr "" msgid "\"Something else\"" msgstr "" -#: src/pattern-matching/match.md -msgid "" -"The `_` pattern is a wildcard pattern which matches any value. The " -"expressions _must_ be exhaustive, meaning that it covers every possibility, " -"so `_` is often used as the final catch-all case." -msgstr "" - -#: src/pattern-matching/match.md -msgid "" -"Match can be used as an expression. Just like `if`, each match arm must have " -"the same type. The type is the last expression of the block, if any. In the " -"example above, the type is `()`." -msgstr "" - #: src/pattern-matching/match.md msgid "" "A variable in the pattern (`key` in this example) will create a binding that " -"can be used within the match arm." +"can be used within the match arm. We will learn more about this on the next " +"slide." msgstr "" #: src/pattern-matching/match.md -msgid "A match guard causes the arm to match only if the condition is true." +msgid "" +"A match guard causes the arm to match only if the condition is true. If the " +"condition is false the match will continue checking later cases." msgstr "" #: src/pattern-matching/match.md @@ -5069,7 +6547,7 @@ msgid "`|` as an `or`" msgstr "" #: src/pattern-matching/match.md -msgid "`..` can expand as much as it needs to be" +msgid "`..` matches any number of items" msgstr "" #: src/pattern-matching/match.md @@ -5089,10 +6567,19 @@ msgstr "" #: src/pattern-matching/match.md msgid "" -"They are not the same as separate `if` expression inside of the match arm. " -"An `if` expression inside of the branch block (after `=>`) happens after the " -"match arm is selected. Failing the `if` condition inside of that block won't " -"result in other arms of the original `match` expression being considered." +"Match guards are different from `if` expressions after the `=>`. An `if` " +"expression is evaluated after the match arm is selected. Failing the `if` " +"condition inside of that block won't result in other arms of the original " +"`match` expression being considered. In the following example, the wildcard " +"pattern `_ =>` is never even attempted." +msgstr "" + +#: src/pattern-matching/match.md +msgid "\"Uppercase\"" +msgstr "" + +#: src/pattern-matching/match.md +msgid "\"Bug: this is never printed\"" msgstr "" #: src/pattern-matching/match.md @@ -5101,105 +6588,171 @@ msgid "" "with an `|`." msgstr "" -#: src/pattern-matching/destructuring.md -msgid "Like tuples, structs and enums can also be destructured by matching:" +#: src/pattern-matching/match.md +msgid "" +"Note that you can't use an existing variable as the condition in a match " +"arm, as it will instead be interpreted as a variable name pattern, which " +"creates a new variable that will shadow the existing one. For example:" msgstr "" -#: src/pattern-matching/destructuring.md +#: src/pattern-matching/match.md +msgid "\"Expected value is 5, actual is {expected}\"" +msgstr "" + +#: src/pattern-matching/match.md +msgid "\"Value was something else\"" +msgstr "" + +#: src/pattern-matching/match.md +msgid "" +"Here we're trying to match on the number 123, where we want the first case " +"to check if the value is 5. The naive expectation is that the first case " +"won't match because the value isn't 5, but instead this is interpreted as a " +"variable pattern which always matches, meaning the first branch will always " +"be taken. If a constant is used instead this will then work as expected." +msgstr "" + +#: src/pattern-matching/match.md +msgid "" +"Another piece of pattern syntax you can show students is the `@` syntax " +"which binds a part of a pattern to a variable. For example:" +msgstr "" + +#: src/pattern-matching/match.md +msgid "\"outer: {outer:?}, inner: {inner}\"" +msgstr "" + +#: src/pattern-matching/match.md +msgid "" +"In this example `inner` has the value 123 which it pulled from the `Option` " +"via destructuring, `outer` captures the entire `Some(inner)` expression, so " +"it contains the full `Option::Some(123)`. This is rarely used but can be " +"useful in more complex patterns." +msgstr "" + +#: src/pattern-matching/destructuring-structs.md msgid "Structs" -msgstr "Structs" - -#: src/pattern-matching/destructuring.md -msgid "\"x.0 = 1, b = {b}, y = {y}\"" msgstr "" -#: src/pattern-matching/destructuring.md -msgid "\"y = 2, x = {i:?}\"" +#: src/pattern-matching/destructuring-structs.md +msgid "Like tuples, structs can also be destructured by matching:" msgstr "" -#: src/pattern-matching/destructuring.md -msgid "\"y = {y}, other fields were ignored\"" +#: src/pattern-matching/destructuring-structs.md +msgid "\"Standing still\"" msgstr "" -#: src/pattern-matching/destructuring.md +#: src/pattern-matching/destructuring-structs.md +msgid "\"{repeat} step x: {x}\"" +msgstr "" + +#: src/pattern-matching/destructuring-structs.md +msgid "\"Single step y: {y}\"" +msgstr "" + +#: src/pattern-matching/destructuring-structs.md +msgid "\"Other move\"" +msgstr "" + +#: src/pattern-matching/destructuring-structs.md +msgid "Change the literal values in `m` to match with the other patterns." +msgstr "" + +#: src/pattern-matching/destructuring-structs.md +msgid "" +"Add a new field to `Movement` and make changes to the pattern as needed." +msgstr "" + +#: src/pattern-matching/destructuring-structs.md +msgid "Note how `delta: (x, 0)` is a nested pattern." +msgstr "" + +#: src/pattern-matching/destructuring-structs.md +msgid "" +"Try `match &m` and check the type of captures. The pattern syntax remains " +"the same, but the captures become shared references. This is [match " +"ergonomics](https://rust-lang.github.io/rfcs/2005-match-ergonomics.html) and " +"is often useful with `match self` when implementing methods on an enum." +msgstr "" + +#: src/pattern-matching/destructuring-structs.md +msgid "" +"The same effect occurs with `match &mut m`: the captures become exclusive " +"references." +msgstr "" + +#: src/pattern-matching/destructuring-structs.md +msgid "" +"The distinction between a capture and a constant expression can be hard to " +"spot. Try changing the `10` in the first arm to a variable, and see that it " +"subtly doesn't work. Change it to a `const` and see it working again." +msgstr "" + +#: src/pattern-matching/destructuring-enums.md +msgid "Like tuples, enums can also be destructured by matching:" +msgstr "" + +#: src/pattern-matching/destructuring-enums.md msgid "" "Patterns can also be used to bind variables to parts of your values. This is " "how you inspect the structure of your types. Let us start with a simple " "`enum` type:" msgstr "" -#: src/pattern-matching/destructuring.md +#: src/pattern-matching/destructuring-enums.md msgid "\"cannot divide {n} into two equal parts\"" msgstr "" -#: src/pattern-matching/destructuring.md +#: src/pattern-matching/destructuring-enums.md msgid "\"{n} divided in two is {half}\"" msgstr "" -#: src/pattern-matching/destructuring.md +#: src/pattern-matching/destructuring-enums.md msgid "\"sorry, an error happened: {msg}\"" msgstr "" -#: src/pattern-matching/destructuring.md +#: src/pattern-matching/destructuring-enums.md msgid "" "Here we have used the arms to _destructure_ the `Result` value. In the first " "arm, `half` is bound to the value inside the `Ok` variant. In the second " "arm, `msg` is bound to the error message." msgstr "" -#: src/pattern-matching/destructuring.md -msgid "Change the literal values in `foo` to match with the other patterns." -msgstr "" - -#: src/pattern-matching/destructuring.md -msgid "Add a new field to `Foo` and make changes to the pattern as needed." -msgstr "" - -#: src/pattern-matching/destructuring.md -msgid "" -"The distinction between a capture and a constant expression can be hard to " -"spot. Try changing the `2` in the second arm to a variable, and see that it " -"subtly doesn't work. Change it to a `const` and see it working again." -msgstr "" - -#: src/pattern-matching/destructuring.md +#: src/pattern-matching/destructuring-enums.md msgid "" "The `if`/`else` expression is returning an enum that is later unpacked with " "a `match`." msgstr "" -#: src/pattern-matching/destructuring.md +#: src/pattern-matching/destructuring-enums.md msgid "" "You can try adding a third variant to the enum definition and displaying the " "errors when running the code. Point out the places where your code is now " "inexhaustive and how the compiler tries to give you hints." msgstr "" -#: src/pattern-matching/destructuring.md +#: src/pattern-matching/destructuring-enums.md msgid "" "The values in the enum variants can only be accessed after being pattern " "matched." msgstr "" -#: src/pattern-matching/destructuring.md +#: src/pattern-matching/destructuring-enums.md msgid "" "Demonstrate what happens when the search is inexhaustive. Note the advantage " "the Rust compiler provides by confirming when all cases are handled." msgstr "" -#: src/pattern-matching/destructuring.md +#: src/pattern-matching/destructuring-enums.md msgid "" -"Save the result of `divide_in_two` in the `result` variable and `match` it " -"in a loop. That won't compile because `msg` is consumed when matched. To fix " -"it, match `&result` instead of `result`. That will make `msg` a reference so " -"it won't be consumed. This [\"match ergonomics\"](https://rust-lang.github." -"io/rfcs/2005-match-ergonomics.html) appeared in Rust 2018. If you want to " -"support older Rust, replace `msg` with `ref msg` in the pattern." +"Demonstrate the syntax for a struct-style variant by adding one to the enum " +"definition and the `match`. Point out how this is syntactically similar to " +"matching on a struct." msgstr "" #: src/pattern-matching/let-control-flow.md msgid "" -"Rust has a few control flow constructs which differ from other languages. " +"Rust has a few control flow constructs that differ from other languages. " "They are used for pattern matching:" msgstr "" @@ -5208,68 +6761,59 @@ msgid "`if let` expressions" msgstr "" #: src/pattern-matching/let-control-flow.md -#, fuzzy msgid "`while let` expressions" -msgstr "while let āĻāĻ•ā§āϏāĻĒā§āϰ⧇āĻļāύ" - -#: src/pattern-matching/let-control-flow.md -msgid "`match` expressions" msgstr "" #: src/pattern-matching/let-control-flow.md +msgid "`let else` expressions" +msgstr "" + +#: src/pattern-matching/let-control-flow/if-let.md msgid "" "The [`if let` expression](https://doc.rust-lang.org/reference/expressions/if-" "expr.html#if-let-expressions) lets you execute different code depending on " "whether a value matches a pattern:" msgstr "" -#: src/pattern-matching/let-control-flow.md -msgid "\"slept for {:?}\"" +#: src/pattern-matching/let-control-flow/if-let.md +msgid "\"slept for {duration:?}\"" msgstr "" -#: src/pattern-matching/let-control-flow.md -#, fuzzy -msgid "`let else` expressions" -msgstr "while let āĻāĻ•ā§āϏāĻĒā§āϰ⧇āĻļāύ" - -#: src/pattern-matching/let-control-flow.md +#: src/pattern-matching/let-control-flow/if-let.md msgid "" -"For the common case of matching a pattern and returning from the function, " -"use [`let else`](https://doc.rust-lang.org/rust-by-example/flow_control/" -"let_else.html). The \"else\" case must diverge (`return`, `break`, or panic " -"- anything but falling off the end of the block)." +"Unlike `match`, `if let` does not have to cover all branches. This can make " +"it more concise than `match`." msgstr "" -#: src/pattern-matching/let-control-flow.md -msgid "\"got None\"" +#: src/pattern-matching/let-control-flow/if-let.md +msgid "A common usage is handling `Some` values when working with `Option`." msgstr "" -#: src/pattern-matching/let-control-flow.md -msgid "\"got empty string\"" +#: src/pattern-matching/let-control-flow/if-let.md +msgid "" +"Unlike `match`, `if let` does not support guard clauses for pattern matching." msgstr "" -#: src/pattern-matching/let-control-flow.md -msgid "\"not a hex digit\"" +#: src/pattern-matching/let-control-flow/if-let.md +msgid "With an `else` clause, this can be used as an expression." msgstr "" -#: src/pattern-matching/let-control-flow.md src/pattern-matching/solution.md -msgid "\"result: {:?}\"" -msgstr "" - -#: src/pattern-matching/let-control-flow.md src/generics/trait-bounds.md -#: src/smart-pointers/solution.md src/testing/googletest.md -#: src/testing/solution.md -msgid "\"foo\"" -msgstr "" - -#: src/pattern-matching/let-control-flow.md +#: src/pattern-matching/let-control-flow/while-let.md msgid "" "Like with `if let`, there is a [`while let`](https://doc.rust-lang.org/" -"reference/expressions/loop-expr.html#predicate-pattern-loops) variant which " +"reference/expressions/loop-expr.html#predicate-pattern-loops) variant that " "repeatedly tests a value against a pattern:" msgstr "" -#: src/pattern-matching/let-control-flow.md +#: src/pattern-matching/let-control-flow/while-let.md +msgid "\"Comprehensive Rust đŸĻ€\"" +msgstr "" + +#: src/pattern-matching/let-control-flow/while-let.md +msgid "// (There are more efficient ways to reverse a string!)\n" +msgstr "" + +#: src/pattern-matching/let-control-flow/while-let.md msgid "" "Here [`String::pop`](https://doc.rust-lang.org/stable/std/string/struct." "String.html#method.pop) returns `Some(c)` until the string is empty, after " @@ -5277,61 +6821,112 @@ msgid "" "all items." msgstr "" -#: src/pattern-matching/let-control-flow.md -msgid "if-let" -msgstr "" - -#: src/pattern-matching/let-control-flow.md -msgid "" -"Unlike `match`, `if let` does not have to cover all branches. This can make " -"it more concise than `match`." -msgstr "" - -#: src/pattern-matching/let-control-flow.md -msgid "A common usage is handling `Some` values when working with `Option`." -msgstr "" - -#: src/pattern-matching/let-control-flow.md -msgid "" -"Unlike `match`, `if let` does not support guard clauses for pattern matching." -msgstr "" - -#: src/pattern-matching/let-control-flow.md -msgid "let-else" -msgstr "" - -#: src/pattern-matching/let-control-flow.md -msgid "" -"`if-let`s can pile up, as shown. The `let-else` construct supports " -"flattening this nested code. Rewrite the awkward version for students, so " -"they can see the transformation." -msgstr "" - -#: src/pattern-matching/let-control-flow.md -msgid "The rewritten version is:" -msgstr "" - -#: src/pattern-matching/let-control-flow.md -msgid "while-let" -msgstr "" - -#: src/pattern-matching/let-control-flow.md +#: src/pattern-matching/let-control-flow/while-let.md msgid "" "Point out that the `while let` loop will keep going as long as the value " "matches the pattern." msgstr "" -#: src/pattern-matching/let-control-flow.md +#: src/pattern-matching/let-control-flow/while-let.md msgid "" "You could rewrite the `while let` loop as an infinite loop with an if " "statement that breaks when there is no value to unwrap for `name.pop()`. The " "`while let` provides syntactic sugar for the above scenario." msgstr "" +#: src/pattern-matching/let-control-flow/while-let.md +msgid "" +"This form cannot be used as an expression, because it may have no value if " +"the condition is false." +msgstr "" + +#: src/pattern-matching/let-control-flow/let-else.md +msgid "`let else` Statements" +msgstr "" + +#: src/pattern-matching/let-control-flow/let-else.md +msgid "" +"For the common case of matching a pattern and returning from the function, " +"use [`let else`](https://doc.rust-lang.org/rust-by-example/flow_control/" +"let_else.html). The \"else\" case must diverge (`return`, `break`, or panic " +"- anything but falling off the end of the block)." +msgstr "" + +#: src/pattern-matching/let-control-flow/let-else.md +msgid "\"got None\"" +msgstr "" + +#: src/pattern-matching/let-control-flow/let-else.md +msgid "\"got empty string\"" +msgstr "" + +#: src/pattern-matching/let-control-flow/let-else.md +msgid "\"not a hex digit\"" +msgstr "" + +#: src/pattern-matching/let-control-flow/let-else.md +msgid "\"result: {:?}\"" +msgstr "" + +#: src/pattern-matching/let-control-flow/let-else.md +#: src/generics/trait-bounds.md src/testing/solution.md src/android/testing.md +#: src/android/testing/googletest.md +msgid "\"foo\"" +msgstr "" + +#: src/pattern-matching/let-control-flow/let-else.md +msgid "" +"This early return-based control flow is common in Rust error handling code, " +"where you try to get a value out of a `Result`, returning an error if the " +"`Result` was `Err`." +msgstr "" + +#: src/pattern-matching/let-control-flow/let-else.md +msgid "" +"If students ask, you can also demonstrate how real error handling code would " +"be written with `?`." +msgstr "" + #: src/pattern-matching/exercise.md msgid "Let's write a simple recursive evaluator for arithmetic expressions." msgstr "" +#: src/pattern-matching/exercise.md +msgid "" +"An example of a small arithmetic expression could be `10 + 20`, which " +"evaluates to `30`. We can represent the expression as a tree:" +msgstr "" + +#: src/pattern-matching/exercise.md +msgid "" +"A bigger and more complex expression would be `(10 * 9) + ((3 - 4) * 5)`, " +"which evaluates to `85`. We represent this as a much bigger tree:" +msgstr "" + +#: src/pattern-matching/exercise.md +msgid "In code, we will represent the tree with two types:" +msgstr "" + +#: src/pattern-matching/exercise.md src/pattern-matching/solution.md +#: src/error-handling/exercise.md src/error-handling/solution.md +msgid "/// An operation to perform on two subexpressions.\n" +msgstr "" + +#: src/pattern-matching/exercise.md src/pattern-matching/solution.md +#: src/error-handling/exercise.md src/error-handling/solution.md +msgid "/// An expression, in tree form.\n" +msgstr "" + +#: src/pattern-matching/exercise.md src/pattern-matching/solution.md +#: src/error-handling/exercise.md src/error-handling/solution.md +msgid "/// An operation on two subexpressions.\n" +msgstr "" + +#: src/pattern-matching/exercise.md src/pattern-matching/solution.md +#: src/error-handling/exercise.md src/error-handling/solution.md +msgid "/// A literal value\n" +msgstr "" + #: src/pattern-matching/exercise.md msgid "" "The `Box` type here is a smart pointer, and will be covered in detail later " @@ -5340,15 +6935,6 @@ msgid "" "\"unbox\" it: `eval(*boxed_expr)`." msgstr "" -#: src/pattern-matching/exercise.md -msgid "" -"Some expressions cannot be evaluated and will return an error. The standard " -"[`Result`](https://doc.rust-lang.org/std/result/enum.Result." -"html) type is an enum that represents either a successful value " -"(`Ok(Value)`) or an error (`Err(String)`). We will cover this type in detail " -"later." -msgstr "" - #: src/pattern-matching/exercise.md msgid "" "Copy and paste the code into the Rust playground, and begin implementing " @@ -5357,53 +6943,6 @@ msgid "" "temporarily with `#[ignore]`:" msgstr "" -#: src/pattern-matching/exercise.md -msgid "" -"If you finish early, try writing a test that results in division by zero or " -"integer overflow. How could you handle this with `Result` instead of a panic?" -msgstr "" - -#: src/pattern-matching/exercise.md src/pattern-matching/solution.md -msgid "/// An operation to perform on two subexpressions.\n" -msgstr "" - -#: src/pattern-matching/exercise.md src/pattern-matching/solution.md -msgid "/// An expression, in tree form.\n" -msgstr "" - -#: src/pattern-matching/exercise.md src/pattern-matching/solution.md -msgid "/// An operation on two subexpressions.\n" -msgstr "" - -#: src/pattern-matching/exercise.md src/pattern-matching/solution.md -msgid "/// A literal value\n" -msgstr "" - -#: src/pattern-matching/exercise.md src/pattern-matching/solution.md -msgid "\"division by zero\"" -msgstr "" - -#: src/pattern-matching/solution.md -msgid "\"expr: {:?}\"" -msgstr "" - -#: src/methods-and-traits.md -msgid "[Methods](./methods-and-traits/methods.md) (10 minutes)" -msgstr "" - -#: src/methods-and-traits.md -msgid "[Traits](./methods-and-traits/traits.md) (10 minutes)" -msgstr "" - -#: src/methods-and-traits.md -msgid "[Deriving](./methods-and-traits/deriving.md) (3 minutes)" -msgstr "" - -#: src/methods-and-traits.md -msgid "" -"[Exercise: Generic Logger](./methods-and-traits/exercise.md) (20 minutes)" -msgstr "" - #: src/methods-and-traits/methods.md msgid "" "Rust allows you to associate functions with your new types. You do this with " @@ -5411,15 +6950,15 @@ msgid "" msgstr "" #: src/methods-and-traits/methods.md -msgid "// No receiver, a static method" +msgid "// No receiver, a static method\n" msgstr "" #: src/methods-and-traits/methods.md -msgid "// Exclusive borrowed read-write access to self" +msgid "// Exclusive borrowed read-write access to self\n" msgstr "" #: src/methods-and-traits/methods.md -msgid "// Shared and read-only borrowed access to self" +msgid "// Shared and read-only borrowed access to self\n" msgstr "" #: src/methods-and-traits/methods.md @@ -5431,7 +6970,7 @@ msgid "\"Lap {idx}: {lap} sec\"" msgstr "" #: src/methods-and-traits/methods.md -msgid "// Exclusive ownership of self" +msgid "// Exclusive ownership of self (covered later)\n" msgstr "" #: src/methods-and-traits/methods.md @@ -5443,7 +6982,7 @@ msgid "\"Monaco Grand Prix\"" msgstr "" #: src/methods-and-traits/methods.md -msgid "// race.add_lap(42);" +msgid "// race.add_lap(42);\n" msgstr "" #: src/methods-and-traits/methods.md @@ -5479,7 +7018,7 @@ msgstr "" #: src/methods-and-traits/methods.md msgid "" "No receiver: this becomes a static method on the struct. Typically used to " -"create constructors which are called `new` by convention." +"create constructors that are called `new` by convention." msgstr "" #: src/methods-and-traits/methods.md @@ -5499,6 +7038,12 @@ msgid "" "all the implementation code in one predictable place." msgstr "" +#: src/methods-and-traits/methods.md +msgid "" +"Note that methods can also be called like associated functions by explicitly " +"passing the receiver in, e.g. `CarRace::add_lap(&mut race, 20)`." +msgstr "" + #: src/methods-and-traits/methods.md msgid "Point out the use of the keyword `self`, a method receiver." msgstr "" @@ -5540,11 +7085,11 @@ msgid "" msgstr "" #: src/methods-and-traits/traits.md -msgid "/// Return a sentence from this pet." +msgid "/// Return a sentence from this pet.\n" msgstr "" #: src/methods-and-traits/traits.md -msgid "/// Print a string to the terminal greeting this pet." +msgid "/// Print a string to the terminal greeting this pet.\n" msgstr "" #: src/methods-and-traits/traits.md @@ -5559,21 +7104,16 @@ msgid "" "that is generic over all types implementing a trait." msgstr "" -#: src/methods-and-traits/traits/implementing.md -#, fuzzy -msgid "Implementing Traits" -msgstr "āĻ…āύāĻŋāϰāĻžāĻĒāĻĻ Traits āĻŦāĻžāĻ¸ā§āϤāĻŦāĻžāϝāĻŧāύ" - #: src/methods-and-traits/traits/implementing.md msgid "\"Oh you're a cutie! What's your name? {}\"" msgstr "" -#: src/methods-and-traits/traits/implementing.md +#: src/methods-and-traits/traits/implementing.md src/generics/dyn-trait.md #: src/smart-pointers/trait-objects.md msgid "\"Woof, my name is {}!\"" msgstr "" -#: src/methods-and-traits/traits/implementing.md +#: src/methods-and-traits/traits/implementing.md src/generics/dyn-trait.md #: src/smart-pointers/trait-objects.md msgid "\"Fido\"" msgstr "" @@ -5598,10 +7138,48 @@ msgid "" "`greet` is provided, and relies on `talk`." msgstr "" +#: src/methods-and-traits/traits/implementing.md +msgid "" +"Multiple `impl` blocks are allowed for a given type. This includes both " +"inherent `impl` blocks and trait `impl` blocks. Likewise multiple traits can " +"be implemented for a given type (and often types implement many traits!). " +"`impl` blocks can even be spread across multiple modules/files." +msgstr "" + +#: src/methods-and-traits/traits/supertraits.md +msgid "" +"A trait can require that types implementing it also implement other traits, " +"called _supertraits_. Here, any type implementing `Pet` must implement " +"`Animal`." +msgstr "" + +#: src/methods-and-traits/traits/supertraits.md +msgid "\"Rex\"" +msgstr "" + +#: src/methods-and-traits/traits/supertraits.md +msgid "\"{} has {} legs\"" +msgstr "" + +#: src/methods-and-traits/traits/supertraits.md +msgid "" +"This is sometimes called \"trait inheritance\" but students should not " +"expect this to behave like OO inheritance. It just specifies an additional " +"requirement on implementations of a trait." +msgstr "" + #: src/methods-and-traits/traits/associated-types.md msgid "" -"Associated types allow are placeholder types which are filled in by the " -"trait implementation." +"Associated types are placeholder types that are supplied by the trait " +"implementation." +msgstr "" + +#: src/methods-and-traits/traits/associated-types.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/debug.md +#: src/idiomatic/polymorphism/refresher/monomorphization.md +#: src/unsafe-deep-dive/safety-preconditions/determining.md +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "\"{:?}\"" msgstr "" #: src/methods-and-traits/traits/associated-types.md @@ -5623,11 +7201,11 @@ msgid "" msgstr "" #: src/methods-and-traits/deriving.md -msgid "// Default trait adds `default` constructor." +msgid "// Default trait adds `default` constructor.\n" msgstr "" #: src/methods-and-traits/deriving.md -msgid "// Clone trait adds `clone` method." +msgid "// Clone trait adds `clone` method.\n" msgstr "" #: src/methods-and-traits/deriving.md @@ -5635,11 +7213,11 @@ msgid "\"EldurScrollz\"" msgstr "" #: src/methods-and-traits/deriving.md -msgid "// Debug trait adds support for printing with `{:?}`." +msgid "// Debug trait adds support for printing with `{:?}`.\n" msgstr "" #: src/methods-and-traits/deriving.md -msgid "\"{:?} vs. {:?}\"" +msgid "\"{p1:?} vs. {p2:?}\"" msgstr "" #: src/methods-and-traits/deriving.md @@ -5649,12 +7227,30 @@ msgid "" "serialization support for a struct using `#[derive(Serialize)]`." msgstr "" +#: src/methods-and-traits/deriving.md +msgid "" +"Derivation is usually provided for traits that have a common boilerplate " +"implementation that is correct for most cases. For example, demonstrate how " +"a manual `Clone` impl can be repetitive compared to deriving the trait:" +msgstr "" + +#: src/methods-and-traits/deriving.md +msgid "" +"Not all of the `.clone()`s in the above are necessary in this case, but this " +"demonstrates the generally boilerplate-y pattern that manual impls would " +"follow, which should help make the use of `derive` clear to students." +msgstr "" + +#: src/methods-and-traits/exercise.md +msgid "Exercise: Logger Trait" +msgstr "" + #: src/methods-and-traits/exercise.md msgid "" "Let's design a simple logging utility, using a trait `Logger` with a `log` " -"method. Code which might log its progress can then take an `&impl Logger`. " -"In testing, this might put messages in the test logfile, while in a " -"production build it would send messages to a log server." +"method. Code that might log its progress can then take an `&impl Logger`. In " +"testing, this might put messages in the test logfile, while in a production " +"build it would send messages to a log server." msgstr "" #: src/methods-and-traits/exercise.md @@ -5667,52 +7263,53 @@ msgstr "" #: src/methods-and-traits/exercise.md msgid "" "This is a common pattern: a struct wrapping a trait implementation and " -"implementing that same trait, adding behavior in the process. What other " -"kinds of wrappers might be useful in a logging utility?" +"implementing that same trait, adding behavior in the process. In the " +"\"Generics\" segment, we will see how to make the wrapper generic over the " +"wrapped type." msgstr "" #: src/methods-and-traits/exercise.md src/methods-and-traits/solution.md +#: src/generics/generic-data.md src/closures/exercise.md +#: src/closures/solution.md msgid "/// Log a message at the given verbosity level.\n" msgstr "" #: src/methods-and-traits/exercise.md src/methods-and-traits/solution.md +#: src/generics/generic-data.md src/closures/exercise.md +#: src/closures/solution.md msgid "\"verbosity={verbosity}: {message}\"" msgstr "" #: src/methods-and-traits/exercise.md src/methods-and-traits/solution.md +#: src/generics/generic-data.md +msgid "/// Only log messages up to the given verbosity level.\n" +msgstr "" + +#: src/methods-and-traits/exercise.md +msgid "// TODO: Implement the `Logger` trait for `VerbosityFilter`.\n" +msgstr "" + +#: src/methods-and-traits/exercise.md src/methods-and-traits/solution.md +#: src/generics/generic-data.md src/closures/exercise.md +#: src/closures/solution.md msgid "\"FYI\"" msgstr "" #: src/methods-and-traits/exercise.md src/methods-and-traits/solution.md +#: src/generics/generic-data.md msgid "\"Uhoh\"" msgstr "" -#: src/methods-and-traits/exercise.md -msgid "// TODO: Define and implement `VerbosityFilter`." -msgstr "" - -#: src/methods-and-traits/solution.md -msgid "/// Only log messages up to the given verbosity level.\n" +#: src/generics.md +msgid "impl Trait" msgstr "" #: src/generics.md -msgid "[Generic Functions](./generics/generic-functions.md) (5 minutes)" +msgid "dyn Trait" msgstr "" #: src/generics.md -msgid "[Generic Data Types](./generics/generic-data.md) (10 minutes)" -msgstr "" - -#: src/generics.md -msgid "[Trait Bounds](./generics/trait-bounds.md) (10 minutes)" -msgstr "" - -#: src/generics.md -msgid "[impl Trait](./generics/impl-trait.md) (5 minutes)" -msgstr "" - -#: src/generics.md -msgid "[Exercise: Generic min](./generics/exercise.md) (10 minutes)" +msgid "Exercise: Generic min" msgstr "" #: src/generics/generic-functions.md @@ -5721,24 +7318,28 @@ msgid "" "structures (such as sorting or a binary tree) over the types used or stored." msgstr "" -#: src/generics/generic-functions.md -msgid "/// Pick `even` or `odd` depending on the value of `n`." -msgstr "" - #: src/generics/generic-functions.md msgid "\"picked a number: {:?}\"" msgstr "" #: src/generics/generic-functions.md -msgid "\"picked a tuple: {:?}\"" +msgid "\"picked a string: {:?}\"" msgstr "" #: src/generics/generic-functions.md -msgid "\"dog\"" +msgid "'L'" msgstr "" #: src/generics/generic-functions.md -msgid "\"cat\"" +msgid "'R'" +msgstr "" + +#: src/generics/generic-functions.md +msgid "" +"It can be helpful to show the monomorphized versions of `pick`, either " +"before talking about the generic `pick` in order to show how generics can " +"reduce code duplication, or after talking about generics to show how " +"monomorphization works." msgstr "" #: src/generics/generic-functions.md @@ -5747,13 +7348,19 @@ msgid "" "value." msgstr "" +#: src/generics/generic-functions.md +msgid "" +"In this example we only use the primitive types `i32` and `char` for `T`, " +"but we can use any type here, including user-defined types:" +msgstr "" + #: src/generics/generic-functions.md msgid "" "This is similar to C++ templates, but Rust partially compiles the generic " "function immediately, so that function must be valid for all types matching " -"the constraints. For example, try modifying `pick` to return `even + odd` if " -"`n == 0`. Even if only the `pick` instantiation with integers is used, Rust " -"still considers it invalid. C++ would let you do this." +"the constraints. For example, try modifying `pick` to return `left + right` " +"if `cond` is false. Even if only the `pick` instantiation with integers is " +"used, Rust still considers it invalid. C++ would let you do this." msgstr "" #: src/generics/generic-functions.md @@ -5763,55 +7370,6 @@ msgid "" "hand-coded the data structures without the abstraction." msgstr "" -#: src/generics/generic-data.md -msgid "You can use generics to abstract over the concrete field type:" -msgstr "" - -#: src/generics/generic-data.md -msgid "// fn set_x(&mut self, x: T)" -msgstr "" - -#: src/generics/generic-data.md -msgid "\"{integer:?} and {float:?}\"" -msgstr "" - -#: src/generics/generic-data.md -msgid "\"coords: {:?}\"" -msgstr "" - -#: src/generics/generic-data.md -msgid "" -"_Q:_ Why `T` is specified twice in `impl Point {}`? Isn't that " -"redundant?" -msgstr "" - -#: src/generics/generic-data.md -msgid "" -"This is because it is a generic implementation section for generic type. " -"They are independently generic." -msgstr "" - -#: src/generics/generic-data.md -msgid "It means these methods are defined for any `T`." -msgstr "" - -#: src/generics/generic-data.md -msgid "It is possible to write `impl Point { .. }`." -msgstr "" - -#: src/generics/generic-data.md -msgid "" -"`Point` is still generic and you can use `Point`, but methods in this " -"block will only be available for `Point`." -msgstr "" - -#: src/generics/generic-data.md -msgid "" -"Try declaring a new variable `let p = Point { x: 5, y: 10.0 };`. Update the " -"code to allow points that have elements of different types, by using two " -"type variables, e.g., `T` and `U`." -msgstr "" - #: src/generics/trait-bounds.md msgid "" "When working with generics, you often want to require the types to implement " @@ -5819,11 +7377,7 @@ msgid "" msgstr "" #: src/generics/trait-bounds.md -msgid "You can do this with `T: Trait` or `impl Trait`:" -msgstr "" - -#: src/generics/trait-bounds.md -msgid "// struct NotClonable;" +msgid "You can do this with `T: Trait`:" msgstr "" #: src/generics/trait-bounds.md @@ -5831,7 +7385,7 @@ msgid "\"{pair:?}\"" msgstr "" #: src/generics/trait-bounds.md -msgid "Try making a `NonClonable` and passing it to `duplicate`." +msgid "Try making a `NotCloneable` and passing it to `duplicate`." msgstr "" #: src/generics/trait-bounds.md @@ -5862,6 +7416,92 @@ msgid "" "original `duplicate`, it is invalid to add a specialized `duplicate(a: u32)`." msgstr "" +#: src/generics/generic-data.md +msgid "" +"You can use generics to abstract over the concrete field type. Returning to " +"the exercise for the previous segment:" +msgstr "" + +#: src/generics/generic-data.md +msgid "" +"_Q:_ Why is `L` specified twice in `impl .. VerbosityFilter`? " +"Isn't that redundant?" +msgstr "" + +#: src/generics/generic-data.md +msgid "" +"This is because it is a generic implementation section for generic type. " +"They are independently generic." +msgstr "" + +#: src/generics/generic-data.md +msgid "It means these methods are defined for any `L`." +msgstr "" + +#: src/generics/generic-data.md +msgid "It is possible to write `impl VerbosityFilter { .. }`." +msgstr "" + +#: src/generics/generic-data.md +msgid "" +"`VerbosityFilter` is still generic and you can use `VerbosityFilter`, " +"but methods in this block will only be available for " +"`VerbosityFilter`." +msgstr "" + +#: src/generics/generic-data.md +msgid "" +"Note that we don't put a trait bound on the `VerbosityFilter` type itself. " +"You can put bounds there as well, but generally in Rust we only put the " +"trait bounds on the impl blocks." +msgstr "" + +#: src/generics/generic-traits.md +msgid "" +"Traits can also be generic, just like types and functions. A trait's " +"parameters get concrete types when it is used. For example the [`From`]" +"(https://doc.rust-lang.org/std/convert/trait.From.html) trait is used to " +"define type conversions:" +msgstr "" + +#: src/generics/generic-traits.md +msgid "\"Converted from integer: {from}\"" +msgstr "" + +#: src/generics/generic-traits.md +msgid "\"Converted from bool: {from}\"" +msgstr "" + +#: src/generics/generic-traits.md +msgid "" +"The `From` trait will be covered later in the course, but its [definition in " +"the `std` docs](https://doc.rust-lang.org/std/convert/trait.From.html) is " +"simple, and copied here for reference." +msgstr "" + +#: src/generics/generic-traits.md +msgid "" +"Implementations of the trait do not need to cover all possible type " +"parameters. Here, `Foo::from(\"hello\")` would not compile because there is " +"no `From<&str>` implementation for `Foo`." +msgstr "" + +#: src/generics/generic-traits.md +msgid "" +"Generic traits take types as \"input\", while associated types are a kind of " +"\"output\" type. A trait can have multiple implementations for different " +"input types." +msgstr "" + +#: src/generics/generic-traits.md +msgid "" +"In fact, Rust requires that at most one implementation of a trait match for " +"any type T. Unlike some other languages, Rust has no heuristic for choosing " +"the \"most specific\" match. There is work on adding this support, called " +"[specialization](https://rust-lang.github.io/rfcs/1210-impl-specialization." +"html)." +msgstr "" + #: src/generics/impl-trait.md msgid "" "Similar to trait bounds, an `impl Trait` syntax can be used in function " @@ -5869,29 +7509,15 @@ msgid "" msgstr "" #: src/generics/impl-trait.md -msgid "// Syntactic sugar for:" -msgstr "" - -#: src/generics/impl-trait.md -msgid "// fn add_42_millions>(x: T) -> i32 {" -msgstr "" - -#: src/generics/impl-trait.md -msgid "\"{many}\"" -msgstr "" - -#: src/generics/impl-trait.md -msgid "\"{many_more}\"" -msgstr "" - -#: src/generics/impl-trait.md -msgid "\"debuggable: {debuggable:?}\"" +msgid "" +"// Syntactic sugar for:\n" +"// fn add_42_millions>(x: T) -> i32 {\n" msgstr "" #: src/generics/impl-trait.md msgid "" -"`impl Trait` allows you to work with types which you cannot name. The " -"meaning of `impl Trait` is a bit different in the different positions." +"`impl Trait` allows you to work with types that you cannot name. The meaning " +"of `impl Trait` is a bit different in the different positions." msgstr "" #: src/generics/impl-trait.md @@ -5923,76 +7549,408 @@ msgid "" "the error message shows." msgstr "" +#: src/generics/dyn-trait.md +msgid "" +"In addition to using traits for static dispatch via generics, Rust also " +"supports using them for type-erased, dynamic dispatch via trait objects:" +msgstr "" + +#: src/generics/dyn-trait.md src/smart-pointers/trait-objects.md +msgid "\"Miau!\"" +msgstr "" + +#: src/generics/dyn-trait.md +msgid "// Uses generics and static dispatch.\n" +msgstr "" + +#: src/generics/dyn-trait.md src/smart-pointers/trait-objects.md +msgid "\"Hello, who are you? {}\"" +msgstr "" + +#: src/generics/dyn-trait.md +msgid "// Uses type-erasure and dynamic dispatch.\n" +msgstr "" + +#: src/generics/dyn-trait.md +msgid "" +"Generics, including `impl Trait`, use monomorphization to create a " +"specialized instance of the function for each different type that the " +"generic is instantiated with. This means that calling a trait method from " +"within a generic function still uses static dispatch, as the compiler has " +"full type information and can resolve that type's trait implementation to " +"use." +msgstr "" + +#: src/generics/dyn-trait.md +msgid "" +"When using `dyn Trait`, it instead uses dynamic dispatch through a [virtual " +"method table](https://en.wikipedia.org/wiki/Virtual_method_table) (vtable). " +"This means that there's a single version of `fn dynamic` that is used " +"regardless of what type of `Pet` is passed in." +msgstr "" + +#: src/generics/dyn-trait.md +msgid "" +"When using `dyn Trait`, the trait object needs to be behind some kind of " +"indirection. In this case it's a reference, though smart pointer types like " +"`Box` can also be used (this will be demonstrated on day 3)." +msgstr "" + +#: src/generics/dyn-trait.md +msgid "" +"At runtime, a `&dyn Pet` is represented as a \"fat pointer\", i.e. a pair of " +"two pointers: One pointer points to the concrete object that implements " +"`Pet`, and the other points to the vtable for the trait implementation for " +"that type. When calling the `talk` method on `&dyn Pet` the compiler looks " +"up the function pointer for `talk` in the vtable and then invokes the " +"function, passing the pointer to the `Dog` or `Cat` into that function. The " +"compiler doesn't need to know the concrete type of the `Pet` in order to do " +"this." +msgstr "" + +#: src/generics/dyn-trait.md +msgid "" +"A `dyn Trait` is considered to be \"type-erased\", because we no longer have " +"compile-time knowledge of what the concrete type is." +msgstr "" + #: src/generics/exercise.md msgid "" "In this short exercise, you will implement a generic `min` function that " -"determines the minimum of two values, using a `LessThan` trait." -msgstr "" - -#: src/generics/exercise.md src/generics/solution.md -msgid "/// Return true if self is less than other.\n" +"determines the minimum of two values, using the [`Ord`](https://doc.rust-" +"lang.org/stable/std/cmp/trait.Ord.html) trait." msgstr "" #: src/generics/exercise.md -msgid "// TODO: implement the `min` function used in `main`." +msgid "// TODO: implement the `min` function used in the tests.\n" msgstr "" #: src/generics/exercise.md src/generics/solution.md -msgid "\"Shapiro\"" +msgid "'z'" msgstr "" #: src/generics/exercise.md src/generics/solution.md -msgid "\"Baumann\"" +msgid "'7'" msgstr "" -#: src/welcome-day-2-afternoon.md -msgid "[Standard Library Types](./std-types.md) (1 hour and 20 minutes)" +#: src/generics/exercise.md src/generics/solution.md +msgid "'1'" msgstr "" -#: src/welcome-day-2-afternoon.md -msgid "[Standard Library Traits](./std-traits.md) (1 hour and 40 minutes)" +#: src/generics/exercise.md src/generics/solution.md +#: src/std-traits/from-and-into.md +#: src/idiomatic/leveraging-the-type-system/raii/drop_option.md +msgid "\"hello\"" msgstr "" -#: src/welcome-day-2-afternoon.md +#: src/generics/exercise.md src/generics/solution.md +msgid "\"goodbye\"" +msgstr "" + +#: src/generics/exercise.md src/generics/solution.md +msgid "\"bat\"" +msgstr "" + +#: src/generics/exercise.md src/generics/solution.md +msgid "\"armadillo\"" +msgstr "" + +#: src/generics/exercise.md msgid "" -"Including 10 minute breaks, this session should take about 3 hours and 10 " -"minutes" +"Show students the [`Ord`](https://doc.rust-lang.org/stable/std/cmp/trait.Ord." +"html) trait and [`Ordering`](https://doc.rust-lang.org/stable/std/cmp/enum." +"Ordering.html) enum." +msgstr "" + +#: src/closures.md src/concurrency/threads.md src/concurrency/shared-state.md +msgid "This segment should take about 30 minutes. It contains:" +msgstr "" + +#: src/closures/syntax.md +msgid "Closures are created with vertical bars: `|..| ..`." +msgstr "" + +#: src/closures/syntax.md +msgid "// Argument and return type can be inferred for lightweight syntax:\n" +msgstr "" + +#: src/closures/syntax.md +msgid "// Or we can specify types and bracket the body to be fully explicit:\n" +msgstr "" + +#: src/closures/syntax.md +msgid "" +"The arguments go between the `|..|`. The body can be surrounded by `{ .. }`, " +"but if it is a single expression these can be omitted." +msgstr "" + +#: src/closures/syntax.md +msgid "" +"Argument types are optional, and are inferred if not given. The return type " +"is also optional, but can only be written if using `{ .. }` around the body." +msgstr "" + +#: src/closures/syntax.md +msgid "" +"The examples can both be written as mere nested functions instead -- they do " +"not capture any variables from their lexical environment. We will see " +"captures next." +msgstr "" + +#: src/closures/syntax.md +msgid "" +"The ability to store functions in variables doesn't just apply to closures, " +"regular functions can be put in variables and then invoked the same way that " +"closures can: [Example in the playground](https://play.rust-lang.org/?" +"version=stable&mode=debug&edition=2024&gist=817cbeeefc49f3d0d180a3d6d54c8bda)." +msgstr "" + +#: src/closures/syntax.md +msgid "" +"The linked example also demonstrates that closures that don't capture " +"anything can also coerce to a regular function pointer." +msgstr "" + +#: src/closures/capturing.md +msgid "" +"A closure can capture variables from the environment where it was defined." +msgstr "" + +#: src/closures/capturing.md +msgid "" +"By default, a closure captures values by reference. Here `max_value` is " +"captured by `clamp`, but still available to `main` for printing. Try making " +"`max_value` mutable, changing it, and printing the clamped values again. Why " +"doesn't this work?" +msgstr "" + +#: src/closures/capturing.md +msgid "" +"If a closure mutates values, it will capture them by mutable reference. Try " +"adding `max_value += 1` to `clamp`." +msgstr "" + +#: src/closures/capturing.md +msgid "" +"You can force a closure to move values instead of referencing them with the " +"`move` keyword. This can help with lifetimes, for example if the closure " +"must outlive the captured values (more on lifetimes later)." +msgstr "" + +#: src/closures/capturing.md +msgid "" +"This looks like `move |v| ..`. Try adding this keyword and see if `main` can " +"still access `max_value` after defining `clamp`." +msgstr "" + +#: src/closures/capturing.md +msgid "" +"By default, closures will capture each variable from an outer scope by the " +"least demanding form of access they can (by shared reference if possible, " +"then exclusive reference, then by move). The `move` keyword forces capture " +"by value." +msgstr "" + +#: src/closures/traits.md +msgid "Closure traits" +msgstr "" + +#: src/closures/traits.md +msgid "" +"Closures or lambda expressions have types that cannot be named. However, " +"they implement special [`Fn`](https://doc.rust-lang.org/std/ops/trait.Fn." +"html), [`FnMut`](https://doc.rust-lang.org/std/ops/trait.FnMut.html), and " +"[`FnOnce`](https://doc.rust-lang.org/std/ops/trait.FnOnce.html) traits:" +msgstr "" + +#: src/closures/traits.md +msgid "" +"The special types `fn(..) -> T` refer to function pointers - either the " +"address of a function, or a closure that captures nothing." +msgstr "" + +#: src/closures/traits.md +msgid "\"Calling {func_name}({input}): {}\"" +msgstr "" + +#: src/closures/traits.md +msgid "\"-itis\"" +msgstr "" + +#: src/closures/traits.md +msgid "\"{x}{suffix}\"" +msgstr "" + +#: src/closures/traits.md +msgid "\"add_suffix\"" +msgstr "" + +#: src/closures/traits.md +msgid "\"senior\"" +msgstr "" + +#: src/closures/traits.md +msgid "\"appendix\"" +msgstr "" + +#: src/closures/traits.md +msgid "\"/\"" +msgstr "" + +#: src/closures/traits.md +msgid "\"accumulate\"" +msgstr "" + +#: src/closures/traits.md +msgid "\"red\"" +msgstr "" + +#: src/closures/traits.md +msgid "\"green\"" +msgstr "" + +#: src/closures/traits.md +msgid "\"blue\"" +msgstr "" + +#: src/closures/traits.md +msgid "\"take_and_reverse\"" +msgstr "" + +#: src/closures/traits.md +msgid "\"reversed: \"" +msgstr "" + +#: src/closures/traits.md +msgid "" +"An `Fn` (e.g. `add_suffix`) neither consumes nor mutates captured values. It " +"can be called needing only a shared reference to the closure, which means " +"the closure can be executed repeatedly and even concurrently." +msgstr "" + +#: src/closures/traits.md +msgid "" +"An `FnMut` (e.g. `accumulate`) might mutate captured values. The closure " +"object is accessed via exclusive reference, so it can be called repeatedly " +"but not concurrently." +msgstr "" + +#: src/closures/traits.md +msgid "" +"If you have an `FnOnce` (e.g. `take_and_reverse`), you may only call it " +"once. Doing so consumes the closure and any values captured by move." +msgstr "" + +#: src/closures/traits.md +msgid "" +"`FnMut` is a subtype of `FnOnce`. `Fn` is a subtype of `FnMut` and `FnOnce`. " +"I.e. you can use an `FnMut` wherever an `FnOnce` is called for, and you can " +"use an `Fn` wherever an `FnMut` or `FnOnce` is called for." +msgstr "" + +#: src/closures/traits.md +msgid "" +"When you define a function that takes a closure, you should take `FnOnce` if " +"you can (i.e. you call it once), or `FnMut` else, and last `Fn`. This allows " +"the most flexibility for the caller." +msgstr "" + +#: src/closures/traits.md +msgid "" +"In contrast, when you have a closure, the most flexible you can have is `Fn` " +"(which can be passed to a consumer of any of the three closure traits), then " +"`FnMut`, and lastly `FnOnce`." +msgstr "" + +#: src/closures/traits.md +msgid "" +"The compiler also infers `Copy` (e.g. for `add_suffix`) and `Clone` (e.g. " +"`take_and_reverse`), depending on what the closure captures. Function " +"pointers (references to `fn` items) implement `Copy` and `Fn`." +msgstr "" + +#: src/closures/exercise.md +msgid "" +"Building on the generic logger from this morning, implement a `Filter` that " +"uses a closure to filter log messages, sending those that pass the filtering " +"predicate to an inner logger." +msgstr "" + +#: src/closures/exercise.md +msgid "// TODO: Define and implement `Filter`.\n" +msgstr "" + +#: src/closures/exercise.md src/closures/solution.md +msgid "\"yikes\"" +msgstr "" + +#: src/closures/exercise.md src/closures/solution.md +msgid "\"yikes, something went wrong\"" +msgstr "" + +#: src/closures/exercise.md src/closures/solution.md +msgid "\"uhoh\"" +msgstr "" + +#: src/closures/solution.md +msgid "/// Only log messages matching a filtering predicate.\n" +msgstr "" + +#: src/closures/solution.md +msgid "" +"**Storing Closures:** To store a closure in a struct, we use a generic type " +"parameter (here `P`). This is because every closure in Rust has a unique, " +"anonymous type generated by the compiler." +msgstr "" + +#: src/closures/solution.md +msgid "" +"**`Fn` Trait Bound:** The bound `P: Fn(u8, &str) -> bool` tells the compiler " +"that `P` can be called as a function with the specified arguments and return " +"type. We use `Fn` (instead of `FnMut` or `FnOnce`) because `log` takes " +"`&self`, so we can only access the predicate immutably." +msgstr "" + +#: src/closures/solution.md +msgid "" +"**Calling fields:** We invoke the closure using `(self.predicate)(...)`. The " +"parentheses around `self.predicate` are necessary to disambiguate between " +"calling a method named `predicate` and calling the field itself." +msgstr "" + +#: src/closures/solution.md +msgid "" +"Discuss why `Fn` is required. If we used `FnMut`, `log` would need to take " +"`&mut self`, which conflicts with the `Logger` trait signature. If we used " +"`FnOnce`, we could only log a single message!" +msgstr "" + +#: src/closures/solution.md +msgid "" +"The `impl` block for `new` also includes the bounds. While technically not " +"strictly required for the struct definition itself (bounds can be placed " +"only on `impl` blocks that use them), putting them on `new` helps type " +"inference." +msgstr "" + +#: src/std-types.md src/std-types/option.md +msgid "Option" +msgstr "" + +#: src/std-types.md src/std-types/result.md src/error-handling.md +msgid "Result" +msgstr "" + +#: src/std-types.md src/std-types/string.md +msgid "String" msgstr "" #: src/std-types.md -msgid "[Standard Library](./std-types/std.md) (3 minutes)" +msgid "Vec" msgstr "" #: src/std-types.md -msgid "[Documentation](./std-types/docs.md) (5 minutes)" -msgstr "" - -#: src/std-types.md -msgid "[Option](./std-types/option.md) (10 minutes)" -msgstr "" - -#: src/std-types.md -msgid "[Result](./std-types/result.md) (10 minutes)" -msgstr "" - -#: src/std-types.md -msgid "[String](./std-types/string.md) (10 minutes)" -msgstr "" - -#: src/std-types.md -msgid "[Vec](./std-types/vec.md) (10 minutes)" -msgstr "" - -#: src/std-types.md -msgid "[HashMap](./std-types/hashmap.md) (10 minutes)" -msgstr "" - -#: src/std-types.md -msgid "[Exercise: Counter](./std-types/exercise.md) (20 minutes)" -msgstr "" - -#: src/std-types.md -msgid "This segment should take about 1 hour and 20 minutes" +msgid "HashMap" msgstr "" #: src/std-types.md @@ -6003,7 +7961,7 @@ msgstr "" #: src/std-types/std.md msgid "" -"Rust comes with a standard library which helps establish a set of common " +"Rust comes with a standard library that helps establish a set of common " "types used by Rust libraries and programs. This way, two libraries can work " "together smoothly because they both use the same `String` type." msgstr "" @@ -6022,13 +7980,13 @@ msgstr "" #: src/std-types/std.md msgid "" -"`alloc` includes types which require a global heap allocator, such as `Vec`, " +"`alloc` includes types that require a global heap allocator, such as `Vec`, " "`Box` and `Arc`." msgstr "" #: src/std-types/std.md msgid "" -"Embedded Rust applications often only use `core`, and sometimes `alloc`." +"Embedded Rust applications typically only use `core`, and sometimes `alloc`." msgstr "" #: src/std-types/docs.md @@ -6054,22 +8012,20 @@ msgid "" "std/collections/struct.BinaryHeap.html)." msgstr "" +#: src/std-types/docs.md +msgid "Use `rustup doc --std` or to view the documentation." +msgstr "" + #: src/std-types/docs.md msgid "In fact, you can document your own code:" msgstr "" #: src/std-types/docs.md msgid "" -"/// Determine whether the first argument is divisible by the second argument." -msgstr "" - -#: src/std-types/docs.md src/testing/other.md -#: src/unsafe-rust/unsafe-functions.md -msgid "///" -msgstr "" - -#: src/std-types/docs.md -msgid "/// If the second argument is zero, the result is false." +"/// Determine whether the first argument is divisible by the second " +"argument.\n" +"///\n" +"/// If the second argument is zero, the result is false.\n" msgstr "" #: src/std-types/docs.md @@ -6088,7 +8044,8 @@ msgstr "" #: src/std-types/docs.md msgid "" -"//! This module contains functionality relating to divisibility of integers." +"//! This module contains functionality relating to divisibility of " +"integers.\n" msgstr "" #: src/std-types/docs.md @@ -6097,11 +8054,6 @@ msgid "" "rand>." msgstr "" -#: src/std-types/option.md -#, fuzzy -msgid "Option" -msgstr "āĻŦā§āϝāϤāĻŋāĻ•ā§āϰāĻŽ" - #: src/std-types/option.md msgid "" "We have already seen some use of `Option`. It stores either a value of " @@ -6117,10 +8069,6 @@ msgstr "" msgid "'Ê'" msgstr "" -#: src/std-types/option.md -msgid "\"find returned {position:?}\"" -msgstr "" - #: src/std-types/option.md msgid "'Z'" msgstr "" @@ -6153,35 +8101,33 @@ msgstr "" #: src/std-types/option.md msgid "" -"The niche optimization means that `Option` often has the same size in " -"memory as `T`." -msgstr "" - -#: src/std-types/result.md -msgid "Result" +"The \"niche optimization\" means that `Option` typically has the same " +"size in memory as `T`, if there is some representation that is not a valid " +"value of T. For example, a reference cannot be NULL, so `Option<&T>` " +"automatically uses NULL to represent the `None` variant, and thus can be " +"stored in the same memory as `&T`." msgstr "" #: src/std-types/result.md msgid "" "`Result` is similar to `Option`, but indicates the success or failure of an " -"operation, each with a different type. This is similar to the `Res` defined " -"in the expression exercise, but generic: `Result` where `T` is used in " -"the `Ok` variant and `E` appears in the `Err` variant." +"operation, each with a different enum variant. It is generic: `Result` " +"where `T` is used in the `Ok` variant and `E` appears in the `Err` variant." msgstr "" -#: src/std-types/result.md +#: src/std-types/result.md src/error-handling/result.md msgid "\"diary.txt\"" msgstr "" -#: src/std-types/result.md +#: src/std-types/result.md src/error-handling/result.md msgid "\"Dear diary: {contents} ({bytes} bytes)\"" msgstr "" -#: src/std-types/result.md +#: src/std-types/result.md src/error-handling/result.md msgid "\"Could not read file content\"" msgstr "" -#: src/std-types/result.md +#: src/std-types/result.md src/error-handling/result.md msgid "\"The diary could not be opened: {err}\"" msgstr "" @@ -6196,29 +8142,25 @@ msgstr "" #: src/std-types/result.md msgid "" "`Result` documentation is a recommended read. Not during the course, but it " -"is worth mentioning. It contains a lot of convenience methods and functions " -"that help functional-style programming." +"is worth mentioning. It contains many convenience methods and functions that " +"help functional-style programming." msgstr "" #: src/std-types/result.md msgid "" "`Result` is the standard type to implement error handling as we will see on " -"Day 3." +"Day 4." msgstr "" -#: src/std-types/string.md -msgid "String" -msgstr "String" - #: src/std-types/string.md msgid "" -"[`String`](https://doc.rust-lang.org/std/string/struct.String.html) is the " -"standard heap-allocated growable UTF-8 string buffer:" +"[`String`](https://doc.rust-lang.org/std/string/struct.String.html) is a " +"growable UTF-8 encoded string:" msgstr "" -#: src/std-types/string.md src/std-traits/read-and-write.md -#: src/memory-management/review.md src/testing/unit-tests.md -#: src/concurrency/scoped-threads.md +#: src/std-types/string.md src/std-traits/comparisons.md +#: src/std-traits/read-and-write.md src/memory-management/review.md +#: src/testing/unit-tests.md src/concurrency/threads/scoped.md msgid "\"Hello\"" msgstr "" @@ -6344,11 +8286,11 @@ msgid "\"v2: len = {}, capacity = {}\"" msgstr "" #: src/std-types/vec.md -msgid "// Canonical macro to initialize a vector with elements." +msgid "// Canonical macro to initialize a vector with elements.\n" msgstr "" #: src/std-types/vec.md -msgid "// Retain only the even elements." +msgid "// Retain only the even elements.\n" msgstr "" #: src/std-types/vec.md @@ -6356,7 +8298,7 @@ msgid "\"{v3:?}\"" msgstr "" #: src/std-types/vec.md -msgid "// Remove consecutive duplicates." +msgid "// Remove consecutive duplicates.\n" msgstr "" #: src/std-types/vec.md @@ -6393,12 +8335,6 @@ msgid "" "remove the last element." msgstr "" -#: src/std-types/vec.md -msgid "" -"Slices are covered on day 3. For now, students only need to know that a " -"value of type `Vec` gives access to all of the documented slice methods, too." -msgstr "" - #: src/std-types/hashmap.md msgid "Standard hash map with protection against HashDoS attacks:" msgstr "" @@ -6436,11 +8372,7 @@ msgid "\"{book} is unknown.\"" msgstr "" #: src/std-types/hashmap.md -msgid "// Use the .entry() method to insert a value if nothing is found." -msgstr "" - -#: src/std-types/hashmap.md -msgid "\"{page_counts:#?}\"" +msgid "// Use the .entry() method to insert a value if nothing is found.\n" msgstr "" #: src/std-types/hashmap.md @@ -6477,21 +8409,8 @@ msgstr "" #: src/std-types/hashmap.md msgid "" -"Alternatively HashMap can be built from any `Iterator` which yields key-" -"value tuples." -msgstr "" - -#: src/std-types/hashmap.md -msgid "" -"We are showing `HashMap`, and avoid using `&str` as key to make " -"examples easier. Using references in collections can, of course, be done, " -"but it can lead into complications with the borrow checker." -msgstr "" - -#: src/std-types/hashmap.md -msgid "" -"Try removing `to_string()` from the example above and see if it still " -"compiles. Where do you think we might run into issues?" +"Alternatively HashMap can be built from any `Iterator` that yields key-value " +"tuples." msgstr "" #: src/std-types/hashmap.md @@ -6506,14 +8425,14 @@ msgstr "" msgid "" "In this exercise you will take a very simple data structure and make it " "generic. It uses a [`std::collections::HashMap`](https://doc.rust-lang.org/" -"stable/std/collections/struct.HashMap.html) to keep track of which values " +"stable/std/collections/struct.HashMap.html) to keep track of what values " "have been seen and how many times each one has appeared." msgstr "" #: src/std-types/exercise.md msgid "" -"The initial version of `Counter` is hard coded to only work for `u32` " -"values. Make the struct and its methods generic over the type of value being " +"The initial version of `Counter` is hardcoded to only work for `u32` values. " +"Make the struct and its methods generic over the type of value being " "tracked, that way `Counter` can track any type of value." msgstr "" @@ -6524,21 +8443,21 @@ msgid "" "number of hash lookups required to implement the `count` method." msgstr "" -#: src/std-types/exercise.md +#: src/std-types/exercise.md src/std-types/solution.md msgid "" -"/// Counter counts the number of times each value of type T has been seen." +"/// Counter counts the number of times each value of type T has been seen.\n" msgstr "" -#: src/std-types/exercise.md -msgid "/// Create a new Counter." +#: src/std-types/exercise.md src/std-types/solution.md +msgid "/// Create a new Counter.\n" msgstr "" -#: src/std-types/exercise.md -msgid "/// Count an occurrence of the given value." +#: src/std-types/exercise.md src/std-types/solution.md +msgid "/// Count an occurrence of the given value.\n" msgstr "" -#: src/std-types/exercise.md -msgid "/// Return the number of times the given value has been seen." +#: src/std-types/exercise.md src/std-types/solution.md +msgid "/// Return the number of times the given value has been seen.\n" msgstr "" #: src/std-types/exercise.md src/std-types/solution.md @@ -6557,62 +8476,17 @@ msgstr "" msgid "\"got {} apples\"" msgstr "" -#: src/std-types/solution.md -msgid "" -"/// Counter counts the number of times each value of type T has been seen.\n" -msgstr "" - -#: src/std-types/solution.md -msgid "/// Create a new Counter.\n" -msgstr "" - -#: src/std-types/solution.md -msgid "/// Count an occurrence of the given value.\n" -msgstr "" - -#: src/std-types/solution.md -msgid "/// Return the number of times the given value has been seen.\n" +#: src/std-traits.md +msgid "Read and Write" msgstr "" #: src/std-traits.md -msgid "[Comparisons](./std-traits/comparisons.md) (10 minutes)" -msgstr "" - -#: src/std-traits.md -msgid "[Operators](./std-traits/operators.md) (10 minutes)" -msgstr "" - -#: src/std-traits.md -msgid "[From and Into](./std-traits/from-and-into.md) (10 minutes)" -msgstr "" - -#: src/std-traits.md -msgid "[Casting](./std-traits/casting.md) (5 minutes)" -msgstr "" - -#: src/std-traits.md -msgid "[Read and Write](./std-traits/read-and-write.md) (10 minutes)" -msgstr "" - -#: src/std-traits.md -msgid "[Default, struct update syntax](./std-traits/default.md) (5 minutes)" -msgstr "" - -#: src/std-traits.md -msgid "[Closures](./std-traits/closures.md) (20 minutes)" -msgstr "" - -#: src/std-traits.md -msgid "[Exercise: ROT13](./std-traits/exercise.md) (30 minutes)" -msgstr "" - -#: src/std-traits.md -msgid "This segment should take about 1 hour and 40 minutes" +msgid "Default, struct update syntax" msgstr "" #: src/std-traits.md msgid "" -"As with the standard-library types, spend time reviewing the documentation " +"As with the standard library types, spend time reviewing the documentation " "for each trait." msgstr "" @@ -6669,6 +8543,14 @@ msgid "" "them." msgstr "" +#: src/std-traits/comparisons.md +msgid "" +"When comparing references in Rust, it will compare the value of the things " +"pointed to, it will NOT compare the references themselves. That means that " +"references to two different things can compare as equal if the values " +"pointed to are the same:" +msgstr "" + #: src/std-traits/operators.md msgid "" "Operator overloading is implemented via traits in [`std::ops`](https://doc." @@ -6676,7 +8558,7 @@ msgid "" msgstr "" #: src/std-traits/operators.md -msgid "\"{:?} + {:?} = {:?}\"" +msgid "\"{p1:?} + {p2:?} = {:?}\"" msgstr "" #: src/std-traits/operators.md src/memory-management/drop.md @@ -6714,11 +8596,20 @@ msgid "" "i32)> for Point` would add a tuple to a `Point`." msgstr "" +#: src/std-traits/operators.md +msgid "" +"The `Not` trait (`!` operator) is notable because it does not convert the " +"argument to `bool` like the same operator in C-family languages; instead, " +"for integer types it flips each bit of the number, which, arithmetically, is " +"equivalent to subtracting the argument from `-1`: `!5 == -6`." +msgstr "" + #: src/std-traits/from-and-into.md msgid "" "Types implement [`From`](https://doc.rust-lang.org/std/convert/trait.From." "html) and [`Into`](https://doc.rust-lang.org/std/convert/trait.Into.html) to " -"facilitate type conversions:" +"facilitate type conversions. Unlike `as`, these traits correspond to " +"lossless, infallible conversions." msgstr "" #: src/std-traits/from-and-into.md @@ -6833,12 +8724,8 @@ msgstr "" msgid "\"\\n\"" msgstr "" -#: src/std-traits/read-and-write.md src/slices-and-lifetimes/str.md -msgid "\"World\"" -msgstr "" - #: src/std-traits/read-and-write.md -msgid "\"Logged: {:?}\"" +msgid "\"Logged: {buffer:?}\"" msgstr "" #: src/std-traits/default.md @@ -6847,31 +8734,18 @@ msgstr "" #: src/std-traits/default.md msgid "" -"[`Default`](https://doc.rust-lang.org/std/default/trait.Default.html) trait " -"produces a default value for a type." +"The [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html) " +"trait produces a default value for a type." msgstr "" #: src/std-traits/default.md msgid "\"John Smith\"" msgstr "" -#: src/std-traits/default.md -msgid "\"{default_struct:#?}\"" -msgstr "" - #: src/std-traits/default.md msgid "\"Y is set!\"" msgstr "" -#: src/std-traits/default.md -msgid "\"{almost_default_struct:#?}\"" -msgstr "" - -#: src/std-traits/default.md src/slices-and-lifetimes/exercise.md -#: src/slices-and-lifetimes/solution.md -msgid "\"{:#?}\"" -msgstr "" - #: src/std-traits/default.md msgid "" "It can be implemented directly or it can be derived via `#[derive(Default)]`." @@ -6889,8 +8763,8 @@ msgstr "" #: src/std-traits/default.md msgid "" -"Standard Rust types often implement `Default` with reasonable values (e.g. " -"`0`, `\"\"`, etc)." +"Standard Rust types commonly implement `Default` with reasonable values (e." +"g. `0`, `\"\"`, etc)." msgstr "" #: src/std-traits/default.md @@ -6910,94 +8784,6 @@ msgid "" "with-struct-update-syntax)." msgstr "" -#: src/std-traits/closures.md -msgid "" -"Closures or lambda expressions have types which cannot be named. However, " -"they implement special [`Fn`](https://doc.rust-lang.org/std/ops/trait.Fn." -"html), [`FnMut`](https://doc.rust-lang.org/std/ops/trait.FnMut.html), and " -"[`FnOnce`](https://doc.rust-lang.org/std/ops/trait.FnOnce.html) traits:" -msgstr "" - -#: src/std-traits/closures.md -#, fuzzy -msgid "\"Calling function on {input}\"" -msgstr "āĻ…āύāĻŋāϰāĻžāĻĒāĻĻ āĻĢāĻžāĻ‚āĻļāύ āĻĄāĻžāĻ•āĻž" - -#: src/std-traits/closures.md -msgid "\"add_3: {}\"" -msgstr "" - -#: src/std-traits/closures.md -msgid "\"accumulate: {}\"" -msgstr "" - -#: src/std-traits/closures.md -msgid "\"multiply_sum: {}\"" -msgstr "" - -#: src/std-traits/closures.md -msgid "" -"An `Fn` (e.g. `add_3`) neither consumes nor mutates captured values, or " -"perhaps captures nothing at all. It can be called multiple times " -"concurrently." -msgstr "" - -#: src/std-traits/closures.md -msgid "" -"An `FnMut` (e.g. `accumulate`) might mutate captured values. You can call it " -"multiple times, but not concurrently." -msgstr "" - -#: src/std-traits/closures.md -msgid "" -"If you have an `FnOnce` (e.g. `multiply_sum`), you may only call it once. It " -"might consume captured values." -msgstr "" - -#: src/std-traits/closures.md -msgid "" -"`FnMut` is a subtype of `FnOnce`. `Fn` is a subtype of `FnMut` and `FnOnce`. " -"I.e. you can use an `FnMut` wherever an `FnOnce` is called for, and you can " -"use an `Fn` wherever an `FnMut` or `FnOnce` is called for." -msgstr "" - -#: src/std-traits/closures.md -msgid "" -"When you define a function that takes a closure, you should take `FnOnce` if " -"you can (i.e. you call it once), or `FnMut` else, and last `Fn`. This allows " -"the most flexibility for the caller." -msgstr "" - -#: src/std-traits/closures.md -msgid "" -"In contrast, when you have a closure, the most flexible you can have is `Fn` " -"(it can be passed everywhere), then `FnMut`, and lastly `FnOnce`." -msgstr "" - -#: src/std-traits/closures.md -msgid "" -"The compiler also infers `Copy` (e.g. for `add_3`) and `Clone` (e.g. " -"`multiply_sum`), depending on what the closure captures." -msgstr "" - -#: src/std-traits/closures.md -msgid "" -"By default, closures will capture by reference if they can. The `move` " -"keyword makes them capture by value." -msgstr "" - -#: src/std-traits/closures.md src/smart-pointers/trait-objects.md -msgid "\"{} {}\"" -msgstr "" - -#: src/std-traits/closures.md -msgid "\"Hi\"" -msgstr "" - -#: src/std-traits/closures.md -msgid "\"Greg\"" -msgstr "" - #: src/std-traits/exercise.md msgid "" "In this example, you will implement the classic [\"ROT13\" cipher](https://" @@ -7007,7 +8793,7 @@ msgid "" msgstr "" #: src/std-traits/exercise.md -msgid "// Implement the `Read` trait for `RotDecoder`." +msgid "// Implement the `Read` trait for `RotDecoder`.\n" msgstr "" #: src/std-traits/exercise.md src/std-traits/solution.md @@ -7024,78 +8810,51 @@ msgid "" "by 13 characters?" msgstr "" -#: src/std-traits/solution.md -msgid "'A'" -msgstr "" - #: src/welcome-day-3.md msgid "Welcome to Day 3" msgstr "" #: src/welcome-day-3.md -msgid "Today, we will cover:" +msgid "We have now seen all the core language features:" msgstr "" #: src/welcome-day-3.md msgid "" -"Memory management, lifetimes, and the borrow checker: how Rust ensures " -"memory safety." +"**Foundations:** Basic types, control flow, functions, and data structures." msgstr "" #: src/welcome-day-3.md -msgid "Smart pointers: standard library pointer types." +msgid "**Pattern Matching:** Destructuring data effectively." msgstr "" #: src/welcome-day-3.md -msgid "[Welcome](./welcome-day-3.md) (3 minutes)" +msgid "**Polymorphism:** Methods, Traits, and Generics." msgstr "" #: src/welcome-day-3.md -msgid "[Memory Management](./memory-management.md) (1 hour)" +msgid "" +"**Standard Library:** Using essential types like `Option`, `Result`, `Vec`, " +"and `String`." msgstr "" #: src/welcome-day-3.md -msgid "[Smart Pointers](./smart-pointers.md) (55 minutes)" +msgid "**Closures:** Anonymous functions that can capture their environment." msgstr "" #: src/welcome-day-3.md msgid "" +"You can write any type and associate behavior with it. We are now shifting " +"gears to apply these concepts to memory management and system design." +msgstr "" + +#: src/welcome-day-3.md src/welcome-day-4-afternoon.md +msgid "" "Including 10 minute breaks, this session should take about 2 hours and 20 " -"minutes" +"minutes. It contains:" msgstr "" #: src/memory-management.md -msgid "[Review of Program Memory](./memory-management/review.md) (5 minutes)" -msgstr "" - -#: src/memory-management.md -msgid "" -"[Approaches to Memory Management](./memory-management/approaches.md) (10 " -"minutes)" -msgstr "" - -#: src/memory-management.md -msgid "[Ownership](./memory-management/ownership.md) (5 minutes)" -msgstr "" - -#: src/memory-management.md -msgid "[Move Semantics](./memory-management/move.md) (5 minutes)" -msgstr "" - -#: src/memory-management.md -msgid "[Clone](./memory-management/clone.md) (2 minutes)" -msgstr "" - -#: src/memory-management.md -msgid "[Copy Types](./memory-management/copy-types.md) (5 minutes)" -msgstr "" - -#: src/memory-management.md -msgid "[Drop](./memory-management/drop.md) (10 minutes)" -msgstr "" - -#: src/memory-management.md -msgid "[Exercise: Builder Type](./memory-management/exercise.md) (20 minutes)" +msgid "Drop" msgstr "" #: src/memory-management/review.md @@ -7131,7 +8890,7 @@ msgid "Values have dynamic sizes determined at runtime." msgstr "" #: src/memory-management/review.md -msgid "Slightly slower than the stack: some book-keeping needed." +msgid "Slightly slower than the stack: some bookkeeping needed." msgstr "" #: src/memory-management/review.md @@ -7172,20 +8931,14 @@ msgstr "" msgid "\"world\"" msgstr "" -#: src/memory-management/review.md -msgid "// DON'T DO THIS AT HOME! For educational purposes only." -msgstr "" - #: src/memory-management/review.md msgid "" -"// String provides no guarantees about its layout, so this could lead to" +"// DON'T DO THIS AT HOME! For educational purposes only.\n" +" // String provides no guarantees about its layout, so this could lead " +"to\n" +" // undefined behavior.\n" msgstr "" -#: src/memory-management/review.md -#, fuzzy -msgid "// undefined behavior." -msgstr "āϰāĻžāύāϟāĻžāχāĻŽā§‡ āϕ⧋āύ āĻ…āύāĻŋāĻ°ā§āϧāĻžāϰāĻŋāϤ āφāϚāϰāĻŖ āύ⧇āχ:" - #: src/memory-management/review.md msgid "\"capacity = {capacity}, ptr = {ptr:#x}, len = {len}\"" msgstr "" @@ -7224,8 +8977,7 @@ msgid "" msgstr "" #: src/memory-management/approaches.md -msgid "" -"Typically implemented with reference counting, garbage collection, or RAII." +msgid "Typically implemented with reference counting or garbage collection." msgstr "" #: src/memory-management/approaches.md @@ -7259,7 +9011,7 @@ msgstr "" msgid "" "C++ has tools like smart pointers (`unique_ptr`, `shared_ptr`) that take " "advantage of language guarantees about calling destructors to ensure memory " -"is freed when a function returns. It is still quite easy to mis-use these " +"is freed when a function returns. It is still quite easy to misuse these " "tools and create similar bugs to C." msgstr "" @@ -7275,10 +9027,10 @@ msgstr "" msgid "" "Rust's ownership and borrowing model can, in many cases, get the performance " "of C, with alloc and free operations precisely where they are required -- " -"zero cost. It also provides tools similar to C++'s smart pointers. When " +"zero-cost. It also provides tools similar to C++'s smart pointers. When " "required, other options such as reference counting are available, and there " -"are even third-party crates available to support runtime garbage collection " -"(not covered in this class)." +"are even crates available to support runtime garbage collection (not covered " +"in this class)." msgstr "" #: src/memory-management/ownership.md @@ -7301,7 +9053,7 @@ msgstr "" #: src/memory-management/ownership.md msgid "" -"Students familiar with garbage-collection implementations will know that a " +"Students familiar with garbage collection implementations will know that a " "garbage collector starts with a set of \"roots\" to find all reachable " "memory. Rust's \"single owner\" principle is a similar idea." msgstr "" @@ -7310,17 +9062,12 @@ msgstr "" msgid "An assignment will transfer _ownership_ between variables:" msgstr "" -#: src/memory-management/move.md -#, fuzzy +#: src/memory-management/move.md src/concurrency/async-control-flow/select.md msgid "\"Hello!\"" -msgstr "Hello World!" - -#: src/memory-management/move.md src/slices-and-lifetimes/str.md -msgid "\"s2: {s2}\"" msgstr "" #: src/memory-management/move.md -msgid "// println!(\"s1: {s1}\");" +msgid "// dbg!(s1);\n" msgstr "" #: src/memory-management/move.md @@ -7347,20 +9094,20 @@ msgstr "" msgid "" "```bob\n" " Stack Heap\n" -".- - - - - - - - - - - - - -. .- - - - - - - - - - - - - -.\n" -": : : :\n" -": s1 \"(inaccessible)\" : : :\n" -": +-----------+-------+ : : +----+----+----+----+ :\n" -": | ptr | o---+---+--+--+-->| R | u | s | t | :\n" -": | len | 4 | : | : +----+----+----+----+ :\n" -": | capacity | 4 | : | : :\n" -": +-----------+-------+ : | : :\n" -": : | `- - - - - - - - - - - - - -'\n" +".- - - - - - - - - - - - - -. .- - - - - - - - - - - - - - - - - - -.\n" +": : : :\n" +": s1 \"(inaccessible)\" : : :\n" +": +-----------+-------+ : : +----+----+----+----+----+----+ :\n" +": | ptr | o---+---+--+--+-->| H | e | l | l | o | ! | :\n" +": | len | 6 | : | : +----+----+----+----+----+----+ :\n" +": | capacity | 6 | : | : :\n" +": +-----------+-------+ : | : :\n" +": : | `- - - - - - - - - - - - - - - - - - -'\n" ": s2 : |\n" ": +-----------+-------+ : |\n" ": | ptr | o---+---+--'\n" -": | len | 4 | :\n" -": | capacity | 4 | :\n" +": | len | 6 | :\n" +": | capacity | 6 | :\n" ": +-----------+-------+ :\n" ": :\n" "`- - - - - - - - - - - - - -'\n" @@ -7373,17 +9120,20 @@ msgid "" "parameter. This transfers ownership:" msgstr "" -#: src/memory-management/move.md +#: src/memory-management/move.md src/memory-management/clone.md msgid "\"Hello {name}\"" msgstr "" -#: src/memory-management/move.md src/android/interoperability/java.md -#, fuzzy +#: src/memory-management/move.md src/memory-management/clone.md +#: src/android/aidl/types/parcelables.md src/android/interoperability/java.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/debug.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-example.md msgid "\"Alice\"" -msgstr "Slices" +msgstr "" #: src/memory-management/move.md -msgid "// say_hello(name);" +msgid "// say_hello(name);\n" msgstr "" #: src/memory-management/move.md @@ -7443,9 +9193,8 @@ msgid "" msgstr "" #: src/memory-management/move.md -#, fuzzy msgid "Defensive Copies in Modern C++" -msgstr "āφāϧ⧁āύāĻŋāĻ• C++ āĻ āĻĄāĻŦāϞ āĻŽā§āĻ•ā§āϤ" +msgstr "" #: src/memory-management/move.md msgid "Modern C++ solves this differently:" @@ -7456,7 +9205,7 @@ msgid "\"Cpp\"" msgstr "" #: src/memory-management/move.md -msgid "// Duplicate the data in s1." +msgid "// Duplicate the data in s1.\n" msgstr "" #: src/memory-management/move.md @@ -7495,11 +9244,7 @@ msgstr "" #: src/memory-management/move.md msgid "" "Unlike Rust, `=` in C++ can run arbitrary code as determined by the type " -"which is being copied or moved." -msgstr "" - -#: src/memory-management/clone.md -msgid "Clone" +"that is being copied or moved." msgstr "" #: src/memory-management/clone.md @@ -7511,8 +9256,7 @@ msgstr "" #: src/memory-management/clone.md msgid "" "The idea of `Clone` is to make it easy to spot where heap allocations are " -"occurring. Look for `.clone()` and a few others like `Vec::new` or `Box::" -"new`." +"occurring. Look for `.clone()` and a few others like `vec!` or `Box::new`." msgstr "" #: src/memory-management/clone.md @@ -7521,6 +9265,18 @@ msgid "" "and return later to try to optimize those clones away." msgstr "" +#: src/memory-management/clone.md +msgid "" +"`clone` generally performs a deep copy of the value, meaning that if you e." +"g. clone an array, all of the elements of the array are cloned as well." +msgstr "" + +#: src/memory-management/clone.md +msgid "" +"The behavior for `clone` is user-defined, so it can perform custom cloning " +"logic if needed." +msgstr "" + #: src/memory-management/copy-types.md msgid "" "While move semantics are the default, certain types are copied by default:" @@ -7587,6 +9343,14 @@ msgstr "" msgid "Show that it works if you clone `p1` instead." msgstr "" +#: src/memory-management/copy-types.md +msgid "" +"Shared references are `Copy`/`Clone`, mutable references are not. This is " +"because Rust requires that mutable references be exclusive, so while it's " +"valid to make a copy of a shared reference, creating a copy of a mutable " +"reference would violate Rust's borrowing rules." +msgstr "" + #: src/memory-management/drop.md msgid "The `Drop` Trait" msgstr "" @@ -7601,12 +9365,12 @@ msgstr "" msgid "\"Dropping {}\"" msgstr "" -#: src/memory-management/drop.md src/exercises/concurrency/link-checker.md -#: src/exercises/concurrency/solutions-morning.md +#: src/memory-management/drop.md src/concurrency/sync-exercises/link-checker.md +#: src/concurrency/sync-exercises/solutions.md msgid "\"a\"" msgstr "" -#: src/memory-management/drop.md src/testing/googletest.md +#: src/memory-management/drop.md src/android/testing/googletest.md msgid "\"b\"" msgstr "" @@ -7619,11 +9383,11 @@ msgid "\"d\"" msgstr "" #: src/memory-management/drop.md -msgid "\"Exiting block B\"" +msgid "\"Exiting innermost block\"" msgstr "" #: src/memory-management/drop.md -msgid "\"Exiting block A\"" +msgid "\"Exiting next block\"" msgstr "" #: src/memory-management/drop.md @@ -7659,7 +9423,7 @@ msgstr "" #: src/memory-management/drop.md msgid "" -"This can be useful for objects that do some work on `drop`: releasing locks, " +"This is useful for objects that do some work on `drop`: releasing locks, " "closing files, etc." msgstr "" @@ -7747,10 +9511,6 @@ msgstr "" msgid "\"0.13\"" msgstr "" -#: src/memory-management/exercise.md src/memory-management/solution.md -msgid "\"base64: {base64:?}\"" -msgstr "" - #: src/memory-management/exercise.md src/memory-management/solution.md msgid "\"log\"" msgstr "" @@ -7759,10 +9519,6 @@ msgstr "" msgid "\"0.4\"" msgstr "" -#: src/memory-management/exercise.md src/memory-management/solution.md -msgid "\"log: {log:?}\"" -msgstr "" - #: src/memory-management/exercise.md src/memory-management/solution.md msgid "\"serde\"" msgstr "" @@ -7775,36 +9531,16 @@ msgstr "" msgid "\"4.0\"" msgstr "" -#: src/memory-management/exercise.md src/memory-management/solution.md -msgid "\"serde: {serde:?}\"" -msgstr "" - #: src/memory-management/solution.md msgid "\"0.1\"" msgstr "" #: src/smart-pointers.md -msgid "[Box" +msgid "Box" msgstr "" #: src/smart-pointers.md -msgid "](./smart-pointers/box.md) (10 minutes)" -msgstr "" - -#: src/smart-pointers.md -msgid "[Rc](./smart-pointers/rc.md) (5 minutes)" -msgstr "" - -#: src/smart-pointers.md -msgid "[Trait Objects](./smart-pointers/trait-objects.md) (10 minutes)" -msgstr "" - -#: src/smart-pointers.md -msgid "[Exercise: Binary Tree](./smart-pointers/exercise.md) (30 minutes)" -msgstr "" - -#: src/smart-pointers.md src/error-handling.md -msgid "This segment should take about 55 minutes" +msgid "Rc" msgstr "" #: src/smart-pointers/box.md @@ -7826,15 +9562,16 @@ msgstr "" #: src/smart-pointers/box.md msgid "" -"Recursive data types or data types with dynamic sizes need to use a `Box`:" +"Recursive data types or data types with dynamic sizes cannot be stored " +"inline without a pointer indirection. `Box` accomplishes that indirection:" msgstr "" #: src/smart-pointers/box.md -msgid "/// A non-empty list: first element and the rest of the list." +msgid "/// A non-empty list: first element and the rest of the list.\n" msgstr "" #: src/smart-pointers/box.md -msgid "/// An empty list." +msgid "/// An empty list.\n" msgstr "" #: src/smart-pointers/box.md @@ -7875,8 +9612,8 @@ msgstr "" #: src/smart-pointers/box.md msgid "" -"have a type whose size that can't be known at compile time, but the Rust " -"compiler wants to know an exact size." +"have a type whose size can't be known at compile time, but the Rust compiler " +"wants to know an exact size." msgstr "" #: src/smart-pointers/box.md @@ -7903,34 +9640,15 @@ msgstr "" msgid "" "Remove the `Box` in the List definition and show the compiler error. We get " "the message \"recursive without indirection\", because for data recursion, " -"we have to use indirection, a Box or reference of some kind, instead of " +"we have to use indirection, a `Box` or reference of some kind, instead of " "storing the value directly." msgstr "" -#: src/smart-pointers/box.md -msgid "Niche Optimization" -msgstr "Niche āĻ…āĻĒāϟāĻŋāĻŽāĻžāχāĻœā§‡āĻļāύ" - #: src/smart-pointers/box.md msgid "" -"A `Box` cannot be empty, so the pointer is always valid and non-`null`. This " -"allows the compiler to optimize the memory layout:" -msgstr "" - -#: src/smart-pointers/box.md -msgid "" -"```bob\n" -" Stack Heap\n" -".- - - - - - - - - - - - - - . .- - - - - - - - - - - - - -.\n" -": : : :\n" -": list : : :\n" -": +---------+----+----+ : : +---------+----+----+ :\n" -": | Element | 1 | o--+----+-----+--->| Element | 2 | // | :\n" -": +---------+----+----+ : : +---------+----+----+ :\n" -": : : :\n" -": : : :\n" -"'- - - - - - - - - - - - - - ' '- - - - - - - - - - - - - -'\n" -"```" +"Though `Box` looks like `std::unique_ptr` in C++, it cannot be empty/null. " +"This makes `Box` one of the types that allow the compiler to optimize " +"storage of some enums (the \"niche optimization\")." msgstr "" #: src/smart-pointers/rc.md @@ -7941,16 +9659,14 @@ msgid "" msgstr "" #: src/smart-pointers/rc.md -msgid "\"a: {a}\"" -msgstr "" - -#: src/smart-pointers/rc.md -msgid "\"b: {b}\"" +msgid "" +"Each `Rc` points to the same shared data structure, containing strong and " +"weak pointers and the value:" msgstr "" #: src/smart-pointers/rc.md msgid "" -"See [`Arc`](../concurrency/shared_state/arc.md) and [`Mutex`](https://doc." +"See [`Arc`](../concurrency/shared-state/arc.md) and [`Mutex`](https://doc." "rust-lang.org/std/sync/struct.Mutex.html) if you are in a multi-threaded " "context." msgstr "" @@ -7996,16 +9712,9 @@ msgstr "" #: src/smart-pointers/trait-objects.md msgid "" -"Trait objects allow for values of different types, for instance in a " -"collection:" -msgstr "" - -#: src/smart-pointers/trait-objects.md -msgid "\"Miau!\"" -msgstr "" - -#: src/smart-pointers/trait-objects.md -msgid "\"Hello, who are you? {}\"" +"We previously saw how trait objects can be used with references, e.g `&dyn " +"Pet`. However, we can also use trait objects with smart pointers like `Box` " +"to create an owned trait object: `Box`." msgstr "" #: src/smart-pointers/trait-objects.md @@ -8016,60 +9725,59 @@ msgstr "" msgid "" "```bob\n" " Stack Heap\n" -".- - - - - - - - - - - - - -. .- - - - - - - - - - - - - - - - - - - - - " -"- -.\n" -": : : :\n" -": pets : : +----+----+----+----" -"+ :\n" -": +-----------+-------+ : : +-----+-----+ .->| F | i | d | o " -"| :\n" -": | ptr | o---+---+-----+-->| o o | o o | | +----+----+----+----" -"+ :\n" -": | len | 2 | : : +-|-|-+-|-|-+ " -"`---------. :\n" -": | capacity | 2 | : : | | | | data " -"| :\n" -": +-----------+-------+ : : | | | | +-------+--|-------" -"+ :\n" -": : : | | | '-->| name | o, 4, 4 " -"| :\n" -": : : | | | | age | 5 " -"| :\n" -"`- - - - - - - - - - - - - -' : | | | +-------+----------" -"+ :\n" -" : | | " +".- - - - - - - - - - - - - - - -. .- - - - - - - - - - - - - - - - - - - " +"- - - -.\n" +": : : :\n" +": \"pets: Vec>\" : : \"data: Cat\" +----+----" +"+----+----+ :\n" +": +-----------+-------+ : : +-------+-------+ | F | i | d " +"| o | :\n" +": | ptr | o---+-------+--. : | lives | 9 | +----+----+----" +"+----+ :\n" +": | len | 2 | : | : +-------+-------+ " +"^ :\n" +": | capacity | 2 | : | : ^ " +"| :\n" +": +-----------+-------+ : | : | " +"'-------. :\n" +": : | : | data:" +"\"Dog\"| :\n" +": : | : | +-------" +"+--|-------+ :\n" +"`- - - - - - - - - - - - - - - -' | : +---|-+-----+ | name | o, " +"4, 4 | :\n" +" `--+-->| o o | o o-|----->| age " +"| 5 | :\n" +" : +-|---+-|---+ +-------" +"+----------+ :\n" +" : | " "| :\n" -" : | | | " -"vtable :\n" -" : | | | +----------------------" -"+ :\n" -" : | | '---->| \"::talk\" " -"| :\n" -" : | | +----------------------" -"+ :\n" -" : | " -"| :\n" -" : | | " -"data :\n" -" : | | +-------+-------" -"+ :\n" -" : | '-->| lives | 9 " -"| :\n" -" : | +-------+-------" -"+ :\n" -" : " -"| :\n" -" : | " -"vtable :\n" -" : | +----------------------" -"+ :\n" -" : '---->| \"::talk\" " -"| :\n" -" : +----------------------" -"+ :\n" -" : :\n" -" '- - - - - - - - - - - - - - - - - - - - - " -"- -'\n" +" `- - -| - - |- - - - - - - - - - - - - " +"- - - -'\n" +" | |\n" +" | | " +"\"Program text\"\n" +" .- - -| - - |- - - - - - - - - - - - - " +"- - - -.\n" +" : | | " +"vtable :\n" +" : | | " +"+----------------------+ :\n" +" : | `----->| \"::" +"talk\" | :\n" +" : | " +"+----------------------+ :\n" +" : | " +"vtable :\n" +" : | " +"+----------------------+ :\n" +" : '----------->| \"::" +"talk\" | :\n" +" : " +"+----------------------+ :\n" +" : :\n" +" '- - - - - - - - - - - - - - - - - - - " +"- - - -'\n" "```" msgstr "" @@ -8109,24 +9817,39 @@ msgstr "" msgid "Compare these outputs in the above example:" msgstr "" +#: src/smart-pointers/trait-objects.md +msgid "\"{} {}\"" +msgstr "" + +#: src/smart-pointers/trait-objects.md src/modules/exercise.md +#: src/modules/solution.md src/android/build-rules/library.md +#: src/android/interoperability/cpp/rust-bridge.md +#: src/concurrency/async-pitfalls/cancellation.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-example.md +#: src/idiomatic/polymorphism/refresher/conditional-methods.md +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-vs-generics.md +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/safe.md +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/encapsulated-unsafe.md +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/documented-safety-preconditions.md +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/crying-wolf.md +msgid "\"{}\"" +msgstr "" + #: src/smart-pointers/exercise.md msgid "" "A binary tree is a tree-type data structure where every node has two " "children (left and right). We will create a tree where each node stores a " "value. For a given node N, all nodes in a N's left subtree contain smaller " -"values, and all nodes in N's right subtree will contain larger values." +"values, and all nodes in N's right subtree will contain larger values. A " +"given value should only be stored in the tree once, i.e. no duplicate nodes." msgstr "" #: src/smart-pointers/exercise.md msgid "Implement the following types, so that the given tests pass." msgstr "" -#: src/smart-pointers/exercise.md -msgid "" -"Extra Credit: implement an iterator over a binary tree that returns the " -"values in order." -msgstr "" - #: src/smart-pointers/exercise.md src/smart-pointers/solution.md msgid "/// A node in the binary tree.\n" msgstr "" @@ -8143,40 +9866,23 @@ msgid "" msgstr "" #: src/smart-pointers/exercise.md -msgid "// Implement `new`, `insert`, `len`, and `has`." +msgid "" +"// Implement `new` for `Node`.\n" +"// Implement `new`, `insert`, `len`, and `has` for `Subtree`.\n" msgstr "" #: src/smart-pointers/exercise.md src/smart-pointers/solution.md msgid "// not a unique item\n" msgstr "" -#: src/smart-pointers/solution.md src/testing/googletest.md -msgid "\"bar\"" -msgstr "" - -#: src/welcome-day-3-afternoon.md -msgid "[Borrowing](./borrowing.md) (50 minutes)" -msgstr "" - #: src/welcome-day-3-afternoon.md msgid "" -"[Slices and Lifetimes](./slices-and-lifetimes.md) (1 hour and 10 minutes)" +"Including 10 minute breaks, this session should take about 2 hours and 30 " +"minutes. It contains:" msgstr "" -#: src/borrowing.md -msgid "[Borrowing a Value](./borrowing/shared.md) (10 minutes)" -msgstr "" - -#: src/borrowing.md -msgid "[Borrow Checking](./borrowing/borrowck.md) (10 minutes)" -msgstr "" - -#: src/borrowing.md -msgid "[Interior Mutability](./borrowing/interior-mutability.md) (10 minutes)" -msgstr "" - -#: src/borrowing.md -msgid "[Exercise: Health Statistics](./borrowing/exercise.md) (20 minutes)" +#: src/borrowing.md src/unsafe-rust.md +msgid "This segment should take about 1 hour and 15 minutes. It contains:" msgstr "" #: src/borrowing/shared.md @@ -8200,36 +9906,45 @@ msgid "" msgstr "" #: src/borrowing/shared.md -msgid "Notes on stack returns:" +msgid "Notes on stack returns and inlining:" msgstr "" #: src/borrowing/shared.md msgid "" "Demonstrate that the return from `add` is cheap because the compiler can " -"eliminate the copy operation. Change the above code to print stack addresses " -"and run it on the [Playground](https://play.rust-lang.org/?" -"version=stable&mode=release&edition=2021&gist=0cb13be1c05d7e3446686ad9947c4671) " +"eliminate the copy operation, by inlining the call to add into main. Change " +"the above code to print stack addresses and run it on the [Playground]" +"(https://play.rust-lang.org/?" +"version=stable&mode=release&edition=2024&gist=0cb13be1c05d7e3446686ad9947c4671) " "or look at the assembly in [Godbolt](https://rust.godbolt.org/). In the " "\"DEBUG\" optimization level, the addresses should change, while they stay " "the same when changing to the \"RELEASE\" setting:" msgstr "" #: src/borrowing/shared.md -msgid "The Rust compiler can do return value optimization (RVO)." +msgid "" +"The Rust compiler can do automatic inlining, that can be disabled on a " +"function level with `#[inline(never)]`." msgstr "" #: src/borrowing/shared.md msgid "" -"In C++, copy elision has to be defined in the language specification because " -"constructors can have side effects. In Rust, this is not an issue at all. If " -"RVO did not happen, Rust will always perform a simple and efficient `memcpy` " -"copy." +"Once disabled, the printed address will change on all optimization levels. " +"Looking at Godbolt or Playground, one can see that in this case, the return " +"of the value depends on the ABI, e.g. on amd64 the two i32 that is making up " +"the point will be returned in 2 registers (eax and edx)." msgstr "" #: src/borrowing/borrowck.md msgid "" "Rust's _borrow checker_ puts constraints on the ways you can borrow values. " -"For a given value, at any time:" +"We've already seen that a reference cannot _outlive_ the value it borrows:" +msgstr "" + +#: src/borrowing/borrowck.md +msgid "" +"There's also a second main rule that the borrow checker enforces: The " +"_aliasing_ rule. For a given value, at any time:" msgstr "" #: src/borrowing/borrowck.md @@ -8242,8 +9957,9 @@ msgstr "" #: src/borrowing/borrowck.md msgid "" -"Note that the requirement is that conflicting references not _exist_ at the " -"same point. It does not matter where the reference is dereferenced." +"The \"outlives\" rule was demonstrated previously when we first looked at " +"references. We review it here to show students that the borrow checking is " +"following a few different rules to validate borrowing." msgstr "" #: src/borrowing/borrowck.md @@ -8254,8 +9970,24 @@ msgstr "" #: src/borrowing/borrowck.md msgid "" -"Move the `println!` statement for `b` before the scope that introduces `c` " -"to make the code compile." +"Note that the requirement is that conflicting references not _exist_ at the " +"same point. It does not matter where the reference is dereferenced. Try " +"commenting out `*c = 20` and show that the compiler error still occurs even " +"if we never use `c`." +msgstr "" + +#: src/borrowing/borrowck.md +msgid "" +"Note that the intermediate reference `c` isn't necessary to trigger a borrow " +"conflict. Replace `c` with a direct mutation of `a` and demonstrate that " +"this produces a similar error. This is because direct mutation of a value " +"effectively creates a temporary mutable reference." +msgstr "" + +#: src/borrowing/borrowck.md +msgid "" +"Move the `dbg!` statement for `b` before the scope that introduces `c` to " +"make the code compile." msgstr "" #: src/borrowing/borrowck.md @@ -8267,18 +9999,54 @@ msgstr "" #: src/borrowing/borrowck.md msgid "" -"The exclusive reference constraint is quite strong. Rust uses it to ensure " -"that data races do not occur. Rust also _relies_ on this constraint to " -"optimize code. For example, a value behind a shared reference can be safely " -"cached in a register for the lifetime of that reference." +"Technically, multiple mutable references to a piece of data can exist at the " +"same time via re-borrowing. This is what allows you to pass a mutable " +"reference into a function without invalidating the original reference. [This " +"playground example](https://play.rust-lang.org/?" +"version=stable&mode=debug&edition=2024&gist=8f5896878611566845fe3b0f4dc5af68) " +"demonstrates that behavior." msgstr "" #: src/borrowing/borrowck.md msgid "" -"The borrow checker is designed to accommodate many common patterns, such as " -"taking exclusive references to different fields in a struct at the same " -"time. But, there are some situations where it doesn't quite \"get it\" and " -"this often results in \"fighting with the borrow checker.\"" +"Rust uses the exclusive reference constraint to ensure that data races do " +"not occur in multi-threaded code, since only one thread can have mutable " +"access to a piece of data at a time." +msgstr "" + +#: src/borrowing/borrowck.md +msgid "" +"Rust also uses this constraint to optimize code. For example, a value behind " +"a shared reference can be safely cached in a register for the lifetime of " +"that reference." +msgstr "" + +#: src/borrowing/borrowck.md +msgid "" +"Fields of a struct can be borrowed independently of each other, but calling " +"a method on a struct will borrow the whole struct, potentially invalidating " +"references to individual fields. See [this playground snippet](https://play." +"rust-lang.org/?" +"version=stable&mode=debug&edition=2024&gist=f293a31f2d4d0d31770486247c2e8437) " +"for an example of this." +msgstr "" + +#: src/borrowing/examples.md +msgid "" +"As a concrete example of how these borrowing rules prevent memory errors, " +"consider the case of modifying a collection while there are references to " +"its elements:" +msgstr "" + +#: src/borrowing/examples.md +msgid "Similarly, consider the case of iterator invalidation:" +msgstr "" + +#: src/borrowing/examples.md +msgid "" +"In both of these cases, modifying the collection by pushing new elements " +"into it can potentially invalidate existing references to the collection's " +"elements if the collection has to reallocate." msgstr "" #: src/borrowing/interior-mutability.md @@ -8295,37 +10063,64 @@ msgid "" "all while still ensuring safety, typically by performing a runtime check." msgstr "" -#: src/borrowing/interior-mutability.md -msgid "`RefCell`" -msgstr "" - -#: src/borrowing/interior-mutability.md -msgid "\"graph: {root:#?}\"" -msgstr "" - -#: src/borrowing/interior-mutability.md -msgid "\"graph sum: {}\"" -msgstr "" - -#: src/borrowing/interior-mutability.md -msgid "`Cell`" -msgstr "" - -#: src/borrowing/interior-mutability.md -msgid "" -"`Cell` wraps a value and allows getting or setting the value, even with a " -"shared reference to the `Cell`. However, it does not allow any references to " -"the value. Since there are no references, borrowing rules cannot be broken." -msgstr "" - #: src/borrowing/interior-mutability.md msgid "" "The main thing to take away from this slide is that Rust provides _safe_ " "ways to modify data behind a shared reference. There are a variety of ways " -"to ensure that safety, and `RefCell` and `Cell` are two of them." +"to ensure that safety, and the next sub-slides present a few of them." msgstr "" -#: src/borrowing/interior-mutability.md +#: src/borrowing/interior-mutability/cell.md +msgid "" +"`Cell` wraps a value and allows getting or setting the value using only a " +"shared reference to the `Cell`. However, it does not allow any references to " +"the inner value. Since there are no references, borrowing rules cannot be " +"broken." +msgstr "" + +#: src/borrowing/interior-mutability/cell.md +#: src/borrowing/interior-mutability/refcell.md +msgid "// Note that `cell` is NOT declared as mutable.\n" +msgstr "" + +#: src/borrowing/interior-mutability/cell.md +msgid "" +"`Cell` is a simple means to ensure safety: it has a `set` method that takes " +"`&self`. This needs no runtime check, but requires moving values, which can " +"have its own cost." +msgstr "" + +#: src/borrowing/interior-mutability/refcell.md +msgid "" +"`RefCell` allows accessing and mutating a wrapped value by providing " +"alternative types `Ref` and `RefMut` that emulate `&T`/`&mut T` without " +"actually being Rust references." +msgstr "" + +#: src/borrowing/interior-mutability/refcell.md +msgid "" +"These types perform dynamic checks using a counter in the `RefCell` to " +"prevent existence of a `RefMut` alongside another `Ref`/`RefMut`." +msgstr "" + +#: src/borrowing/interior-mutability/refcell.md +msgid "" +"By implementing `Deref` (and `DerefMut` for `RefMut`), these types allow " +"calling methods on the inner value without allowing references to escape." +msgstr "" + +#: src/borrowing/interior-mutability/refcell.md +msgid "" +"// This triggers an error at runtime.\n" +" // let other = cell.borrow();\n" +" // println!(\"{}\", other);\n" +msgstr "" + +#: src/borrowing/interior-mutability/refcell.md +msgid "\"{cell:?}\"" +msgstr "" + +#: src/borrowing/interior-mutability/refcell.md msgid "" "`RefCell` enforces Rust's usual borrowing rules (either multiple shared " "references or a single exclusive reference) with a runtime check. In this " @@ -8333,306 +10128,351 @@ msgid "" "succeed." msgstr "" -#: src/borrowing/interior-mutability.md +#: src/borrowing/interior-mutability/refcell.md msgid "" -"`Rc` only allows shared (read-only) access to its contents, since its " -"purpose is to allow (and count) many references. But we want to modify the " -"value, so we need interior mutability." +"The extra block in the example is to end the borrow created by the call to " +"`borrow_mut` before we print the cell. Trying to print a borrowed `RefCell` " +"just shows the message `\"{borrowed}\"`." msgstr "" -#: src/borrowing/interior-mutability.md +#: src/borrowing/interior-mutability/refcell.md msgid "" -"`Cell` is a simpler means to ensure safety: it has a `set` method that takes " -"`&self`. This needs no runtime check, but requires moving values, which can " -"have its own cost." -msgstr "" - -#: src/borrowing/interior-mutability.md -msgid "" -"Demonstrate that reference loops can be created by adding `root` to `subtree." -"children`." -msgstr "" - -#: src/borrowing/interior-mutability.md -msgid "" -"To demonstrate a runtime panic, add a `fn inc(&mut self)` that increments " -"`self.value` and calls the same method on its children. This will panic in " -"the presence of the reference loop, with `thread 'main' panicked at 'already " -"borrowed: BorrowMutError'`." +"There are also `OnceCell` and `OnceLock`, which allow initialization on " +"first use. Making these useful requires some more knowledge than students " +"have at this time." msgstr "" #: src/borrowing/exercise.md msgid "" -"You're working on implementing a health-monitoring system. As part of that, " -"you need to keep track of users' health statistics." +"In this exercise, you will manage a wizard's inventory using what you have " +"learned about borrowing and ownership." msgstr "" #: src/borrowing/exercise.md msgid "" -"You'll start with a stubbed function in an `impl` block as well as a `User` " -"struct definition. Your goal is to implement the stubbed out method on the " -"`User` `struct` defined in the `impl` block." +"The wizard has a collection of spells. You need to implement functions to " +"add spells to the inventory and to cast spells from them." msgstr "" #: src/borrowing/exercise.md msgid "" -"Copy the code below to and fill in the missing " -"method:" +"Spells have a limited number of uses. When a spell has no uses left, it must " +"be removed from the wizard's inventory." msgstr "" #: src/borrowing/exercise.md msgid "" -"\"Update a user's statistics based on measurements from a visit to the " -"doctor\"" +"// TODO: Implement `add_spell` to take ownership of a spell and add it to\n" +" // the wizard's inventory.\n" +msgstr "" + +#: src/borrowing/exercise.md +msgid "" +"// TODO: Implement `cast_spell` to borrow a spell from the inventory and\n" +" // cast it. The wizard's mana should decrease by the spell's cost and " +"the\n" +" // number of uses for the spell should decrease by 1.\n" +" //\n" +" // If the wizard doesn't have enough mana, the spell should fail.\n" +" // If the spell has no uses left, it is removed from the inventory.\n" msgstr "" #: src/borrowing/exercise.md src/borrowing/solution.md -#: src/android/build-rules/library.md -#: src/android/aidl/example-service/client.md -msgid "\"Bob\"" +msgid "\"Fireball\"" msgstr "" #: src/borrowing/exercise.md src/borrowing/solution.md -msgid "\"I'm {} and my age is {}\"" +msgid "\"Ice Blast\"" msgstr "" -#: src/slices-and-lifetimes.md -msgid "[Slices: &\\[T\\]](./slices-and-lifetimes/slices.md) (10 minutes)" +#: src/borrowing/exercise.md src/borrowing/solution.md +msgid "// Casts successfully\n" msgstr "" -#: src/slices-and-lifetimes.md -msgid "[String References](./slices-and-lifetimes/str.md) (10 minutes)" +#: src/borrowing/exercise.md src/borrowing/solution.md +msgid "// Casts successfully, then removed\n" msgstr "" -#: src/slices-and-lifetimes.md +#: src/borrowing/exercise.md src/borrowing/solution.md +msgid "// Fails (not found)\n" +msgstr "" + +#: src/borrowing/exercise.md msgid "" -"[Lifetime Annotations](./slices-and-lifetimes/lifetime-annotations.md) (10 " -"minutes)" +"The goal of this exercise is to practice the core concepts of ownership and " +"borrowing, specifically the rule that you cannot mutate a collection while " +"holding a reference to one of its elements." msgstr "" -#: src/slices-and-lifetimes.md +#: src/borrowing/exercise.md msgid "" -"[Lifetime Elision](./slices-and-lifetimes/lifetime-elision.md) (5 minutes)" +"`add_spell` should take ownership of a `Spell` and move it into the " +"`Wizard`'s inventory." msgstr "" -#: src/slices-and-lifetimes.md +#: src/borrowing/exercise.md +msgid "`cast_spell` is the core of the exercise. It needs to:" +msgstr "" + +#: src/borrowing/exercise.md +msgid "Find the spell (by index or by reference)." +msgstr "" + +#: src/borrowing/exercise.md +msgid "Check mana and decrement it." +msgstr "" + +#: src/borrowing/exercise.md +msgid "Decrement the spell's `uses`." +msgstr "" + +#: src/borrowing/exercise.md +msgid "Remove the spell if `uses == 0`." +msgstr "" + +#: src/borrowing/exercise.md msgid "" -"[Struct Lifetimes](./slices-and-lifetimes/struct-lifetimes.md) (5 minutes)" +"**Borrow Checker Conflict:** If students try to hold a reference to the " +"spell (e.g., `let spell = &mut self.spells[i]`) and then call `self.spells." +"remove(i)` while that reference is still \"alive\" in the same scope, the " +"borrow checker will complain. This is a great opportunity to show how to " +"structure code to satisfy the borrow checker (e.g., by using indices or by " +"ensuring the borrow ends before the mutation)." msgstr "" -#: src/slices-and-lifetimes.md +#: src/borrowing/solution.md +msgid "Solution: Wizard's Inventory" +msgstr "" + +#: src/borrowing/solution.md +msgid "\"Spell {} not found!\"" +msgstr "" + +#: src/borrowing/solution.md +msgid "\"Casting {}! Mana left: {}. Uses left: {}\"" +msgstr "" + +#: src/borrowing/solution.md +msgid "\"Not enough mana to cast {}!\"" +msgstr "" + +#: src/lifetimes.md +msgid "This segment should take about 1 hour and 5 minutes. It contains:" +msgstr "" + +#: src/lifetimes/simple-borrows.md +msgid "Borrowing with Functions" +msgstr "" + +#: src/lifetimes/simple-borrows.md msgid "" -"[Exercise: Protobuf Parsing](./slices-and-lifetimes/exercise.md) (30 minutes)" +"As part of borrow checking, the compiler needs to reason about how borrows " +"flow into and out of functions. In the simplest case borrows last for the " +"duration of the function call:" msgstr "" -#: src/slices-and-lifetimes.md -msgid "This segment should take about 1 hour and 10 minutes" +#: src/lifetimes/simple-borrows.md +msgid "// Borrow `val` for the function call.\n" msgstr "" -#: src/slices-and-lifetimes/slices.md -msgid "Slices" -msgstr "Slices" - -#: src/slices-and-lifetimes/slices.md -msgid "A slice gives you a view into a larger collection:" +#: src/lifetimes/simple-borrows.md +msgid "// Borrow has ended and we're free to mutate.\n" msgstr "" -#: src/slices-and-lifetimes/slices.md -msgid "Slices borrow data from the sliced type." -msgstr "" - -#: src/slices-and-lifetimes/slices.md -msgid "Question: What happens if you modify `a[3]` right before printing `s`?" -msgstr "" - -#: src/slices-and-lifetimes/slices.md +#: src/lifetimes/simple-borrows.md msgid "" -"We create a slice by borrowing `a` and specifying the starting and ending " -"indexes in brackets." +"In this example we borrow `val` for the call to `borrows`. This would limit " +"our ability to mutate `val`, but once the function call returns the borrow " +"has ended and we're free to mutate again." msgstr "" -#: src/slices-and-lifetimes/slices.md +#: src/lifetimes/returning-borrows.md msgid "" -"If the slice starts at index 0, Rust’s range syntax allows us to drop the " -"starting index, meaning that `&a[0..a.len()]` and `&a[..a.len()]` are " -"identical." +"But we can also have our function return a reference! This means that a " +"borrow flows back out of a function:" msgstr "" -#: src/slices-and-lifetimes/slices.md +#: src/lifetimes/returning-borrows.md +msgid "// x = 5; // đŸ› ī¸âŒ `x` is still borrowed!\n" +msgstr "" + +#: src/lifetimes/returning-borrows.md msgid "" -"The same is true for the last index, so `&a[2..a.len()]` and `&a[2..]` are " -"identical." +"Rust functions can return references, meaning that a borrow can flow back " +"out of a function." msgstr "" -#: src/slices-and-lifetimes/slices.md +#: src/lifetimes/returning-borrows.md msgid "" -"To easily create a slice of the full array, we can therefore use `&a[..]`." +"If a function returns a reference (or another kind of borrow), it was likely " +"derived from one of its arguments. This means that the return value of the " +"function will extend the borrow for one or more argument borrows." msgstr "" -#: src/slices-and-lifetimes/slices.md +#: src/lifetimes/returning-borrows.md msgid "" -"`s` is a reference to a slice of `i32`s. Notice that the type of `s` " -"(`&[i32]`) no longer mentions the array length. This allows us to perform " -"computation on slices of different sizes." +"This case is still fairly simple, in that only one borrow is passed into the " +"function, so the returned borrow has to be the same one." msgstr "" -#: src/slices-and-lifetimes/slices.md +#: src/lifetimes/multiple-borrows.md msgid "" -"Slices always borrow from another object. In this example, `a` has to remain " -"'alive' (in scope) for at least as long as our slice." +"But what about when there are multiple borrows passed into a function and " +"one being returned?" msgstr "" -#: src/slices-and-lifetimes/slices.md +#: src/lifetimes/multiple-borrows.md +msgid "\"Return either `a` or `b`\"" +msgstr "" + +#: src/lifetimes/multiple-borrows.md msgid "" -"The question about modifying `a[3]` can spark an interesting discussion, but " -"the answer is that for memory safety reasons you cannot do it through `a` at " -"this point in the execution, but you can read the data from both `a` and `s` " -"safely. It works before you created the slice, and again after the " -"`println`, when the slice is no longer used." +"// Which one is still borrowed?\n" +" // Should either mutation be allowed?\n" msgstr "" -#: src/slices-and-lifetimes/str.md +#: src/lifetimes/multiple-borrows.md msgid "" -"We can now understand the two string types in Rust: `&str` is almost like " -"`&[char]`, but with its data stored in a variable-length encoding (UTF-8)." +"This code does not compile right now because it is missing lifetime " +"annotations. Before we get it to compile, use this opportunity to have " +"students to think about which of our argument borrows should be extended by " +"the return value." msgstr "" -#: src/slices-and-lifetimes/str.md -msgid "\"s1: {s1}\"" -msgstr "" - -#: src/slices-and-lifetimes/str.md -#, fuzzy -msgid "\"Hello \"" -msgstr "Hello World!" - -#: src/slices-and-lifetimes/str.md -msgid "\"s3: {s3}\"" -msgstr "" - -#: src/slices-and-lifetimes/str.md -msgid "Rust terminology:" -msgstr "" - -#: src/slices-and-lifetimes/str.md -msgid "`&str` an immutable reference to a string slice." -msgstr "" - -#: src/slices-and-lifetimes/str.md -msgid "`String` a mutable string buffer." -msgstr "" - -#: src/slices-and-lifetimes/str.md +#: src/lifetimes/multiple-borrows.md msgid "" -"`&str` introduces a string slice, which is an immutable reference to UTF-8 " -"encoded string data stored in a block of memory. String literals " -"(`”Hello”`), are stored in the program’s binary." +"We pass two borrows into `multiple` and one is going to come back out, which " +"means we will need to extend the borrow of one of the argument lifetimes. " +"Which one should be extended? Do we need to see the body of `multiple` to " +"figure this out?" msgstr "" -#: src/slices-and-lifetimes/str.md +#: src/lifetimes/multiple-borrows.md msgid "" -"Rust’s `String` type is a wrapper around a vector of bytes. As with a " -"`Vec`, it is owned." +"When borrow checking, the compiler doesn't look at the body of `multiple` to " +"reason about the borrows flowing out, instead it looks only at the signature " +"of the function for borrow analysis." msgstr "" -#: src/slices-and-lifetimes/str.md +#: src/lifetimes/multiple-borrows.md msgid "" -"As with many other types `String::from()` creates a string from a string " -"literal; `String::new()` creates a new empty string, to which string data " -"can be added using the `push()` and `push_str()` methods." +"In this case there is not enough information to determine if `a` or `b` will " +"be borrowed by the returned reference. Show students the compiler errors and " +"introduce the lifetime syntax:" msgstr "" -#: src/slices-and-lifetimes/str.md +#: src/lifetimes/borrow-both.md msgid "" -"The `format!()` macro is a convenient way to generate an owned string from " -"dynamic values. It accepts the same format specification as `println!()`." +"In this case, we have a function where either `a` or `b` may be returned. In " +"this case we use the lifetime annotations to tell the compiler that both " +"borrows may flow into the return value." msgstr "" -#: src/slices-and-lifetimes/str.md +#: src/lifetimes/borrow-both.md msgid "" -"You can borrow `&str` slices from `String` via `&` and optionally range " -"selection. If you select a byte range that is not aligned to character " -"boundaries, the expression will panic. The `chars` iterator iterates over " -"characters and is preferred over trying to get character boundaries right." +"// Which one is still borrowed?\n" +" // Should either mutation be allowed?\n" +" // a += 7;\n" +" // b += 7;\n" msgstr "" -#: src/slices-and-lifetimes/str.md +#: src/lifetimes/borrow-both.md msgid "" -"For C++ programmers: think of `&str` as `std::string_view` from C++, but the " -"one that always points to a valid string in memory. Rust `String` is a rough " -"equivalent of `std::string` from C++ (main difference: it can only contain " -"UTF-8 encoded bytes and will never use a small-string optimization)." +"The `pick` function will return either `a` or `b` depending on the value of " +"`c`, which means we can't know at compile time which one will be returned." msgstr "" -#: src/slices-and-lifetimes/str.md -#, fuzzy -msgid "Byte strings literals allow you to create a `&[u8]` value directly:" -msgstr "Byte strings allow you to create a `&[u8]` value directly:" - -#: src/slices-and-lifetimes/lifetime-annotations.md +#: src/lifetimes/borrow-both.md msgid "" -"A reference has a _lifetime_, which must not \"outlive\" the value it refers " -"to. This is verified by the borrow checker." +"To express this to the compiler, we use the same lifetime for both `a` and " +"`b`, along with the return type. This means that the returned reference will " +"borrow BOTH `a` and `b`!" msgstr "" -#: src/slices-and-lifetimes/lifetime-annotations.md +#: src/lifetimes/borrow-both.md msgid "" -"The lifetime can be implicit - this is what we have seen so far. Lifetimes " -"can also be explicit: `&'a Point`, `&'document str`. Lifetimes start with " -"`'` and `'a` is a typical default name. Read `&'a Point` as \"a borrowed " -"`Point` which is valid for at least the lifetime `a`\"." +"Uncomment both of the commented lines and show that `r` is borrowing both " +"`a` and `b`, even though at runtime it will only point to one of them." msgstr "" -#: src/slices-and-lifetimes/lifetime-annotations.md +#: src/lifetimes/borrow-both.md msgid "" -"Lifetimes are always inferred by the compiler: you cannot assign a lifetime " -"yourself. Explicit lifetime annotations create constraints where there is " -"ambiguity; the compiler verifies that there is a valid solution." +"Change the first argument to `pick` to show that the result is the same " +"regardless of if `a` or `b` is returned." msgstr "" -#: src/slices-and-lifetimes/lifetime-annotations.md +#: src/lifetimes/borrow-one.md msgid "" -"Lifetimes become more complicated when considering passing values to and " -"returning values from functions." +"In this example `find_nearest` takes in multiple borrows but returns only " +"one of them. The lifetime annotations explicitly tie the returned borrow to " +"the corresponding argument borrow." msgstr "" -#: src/slices-and-lifetimes/lifetime-annotations.md -msgid "// What is the lifetime of p3?" -msgstr "" - -#: src/slices-and-lifetimes/lifetime-annotations.md -msgid "\"p3: {p3:?}\"" -msgstr "" - -#: src/slices-and-lifetimes/lifetime-annotations.md +#: src/lifetimes/borrow-one.md msgid "" -"In this example, the the compiler does not know what lifetime to infer for " -"`p3`. Looking inside the function body shows that it can only safely assume " -"that `p3`'s lifetime is the shorter of `p1` and `p2`. But just like types, " -"Rust requires explicit annotations of lifetimes on function arguments and " -"return values." +"/// Searches `points` for the point closest to `query`.\n" +"/// Assumes there's at least one point in `points`.\n" msgstr "" -#: src/slices-and-lifetimes/lifetime-annotations.md -msgid "Add `'a` appropriately to `left_most`:" +#: src/lifetimes/borrow-one.md +msgid "// query // What happens if we do this instead?\n" msgstr "" -#: src/slices-and-lifetimes/lifetime-annotations.md +#: src/lifetimes/borrow-one.md +msgid "// `query` isn't borrowed at this point.\n" +msgstr "" + +#: src/lifetimes/borrow-one.md msgid "" -"This says, \"given p1 and p2 which both outlive `'a`, the return value lives " -"for at least `'a`." +"It may be helpful to collapse the definition of `find_nearest` to put more " +"focus on the signature of the function. The actual logic in the function is " +"somewhat complex and isn't important for the purpose of borrow analysis." msgstr "" -#: src/slices-and-lifetimes/lifetime-annotations.md +#: src/lifetimes/borrow-one.md msgid "" -"In common cases, lifetimes can be elided, as described on the next slide." +"When we call `find_nearest` the returned reference doesn't borrow `query`, " +"and so we are free to drop it while `nearest` is still active." msgstr "" -#: src/slices-and-lifetimes/lifetime-elision.md -msgid "Lifetimes in Function Calls" -msgstr "āĻĢāĻžāĻ‚āĻļāύ āĻ•āϞ āĻ āĻœā§€āĻŦāύāĻ•āĻžāϞ" +#: src/lifetimes/borrow-one.md +msgid "" +"But what happens if we return the wrong borrow? Change the last line of " +"`find_nearest` to return `query` instead. Show the compiler error to the " +"students." +msgstr "" -#: src/slices-and-lifetimes/lifetime-elision.md +#: src/lifetimes/borrow-one.md +msgid "" +"The first thing we have to do is add a lifetime annotation to `query`. Show " +"students that we can add a second lifetime `'b` to `find_nearest`." +msgstr "" + +#: src/lifetimes/borrow-one.md +msgid "" +"Show the new error to the students. The borrow checker verifies that the " +"logic in the function body actually returns a reference with the correct " +"lifetime, enforcing that the function adheres to the contract set by the " +"function's signature." +msgstr "" + +#: src/lifetimes/borrow-one.md +msgid "" +"The \"help\" message in the error notes that we can add a lifetime bound " +"`'b: 'a` to say that `'b` will live at least as long as `'a`, which would " +"then allow us to return `query`. This is an example of lifetime subtyping, " +"which allows us to return a longer lifetime where a shorter one is expected." +msgstr "" + +#: src/lifetimes/borrow-one.md +msgid "" +"We can do something similar by returning a `'static` lifetime, e.g., a " +"reference to a `static` variable. The `'static` lifetime is guaranteed to be " +"longer than any other lifetime, so it's always safe to return in place of a " +"shorter lifetime." +msgstr "" + +#: src/lifetimes/lifetime-elision.md msgid "" "Lifetimes for function arguments and return values must be fully specified, " "but Rust allows lifetimes to be elided in most cases with [a few simple " @@ -8640,106 +10480,74 @@ msgid "" "inference -- it is just a syntactic shorthand." msgstr "" -#: src/slices-and-lifetimes/lifetime-elision.md +#: src/lifetimes/lifetime-elision.md msgid "Each argument which does not have a lifetime annotation is given one." msgstr "" -#: src/slices-and-lifetimes/lifetime-elision.md +#: src/lifetimes/lifetime-elision.md msgid "" "If there is only one argument lifetime, it is given to all un-annotated " "return values." msgstr "" -#: src/slices-and-lifetimes/lifetime-elision.md +#: src/lifetimes/lifetime-elision.md msgid "" "If there are multiple argument lifetimes, but the first one is for `self`, " "that lifetime is given to all un-annotated return values." msgstr "" -#: src/slices-and-lifetimes/lifetime-elision.md -msgid "In this example, `cab_distance` is trivially elided." -msgstr "" - -#: src/slices-and-lifetimes/lifetime-elision.md +#: src/lifetimes/lifetime-elision.md msgid "" -"The `nearest` function provides another example of a function with multiple " -"references in its arguments that requires explicit annotation." +"Walk through applying the lifetime elision rules to each of the example " +"functions. `only_args` is completed by the first rule, `identity` is " +"completed by the second, and `Foo::get` is completed by the third." msgstr "" -#: src/slices-and-lifetimes/lifetime-elision.md -msgid "Try adjusting the signature to \"lie\" about the lifetimes returned:" -msgstr "" - -#: src/slices-and-lifetimes/lifetime-elision.md +#: src/lifetimes/lifetime-elision.md msgid "" -"This won't compile, demonstrating that the annotations are checked for " -"validity by the compiler. Note that this is not the case for raw pointers " -"(unsafe), and this is a common source of errors with unsafe Rust." +"If all lifetimes have not been filled in by applying the three elision rules " +"then you will get a compiler error telling you to add annotations manually." msgstr "" -#: src/slices-and-lifetimes/lifetime-elision.md -msgid "" -"Students may ask when to use lifetimes. Rust borrows _always_ have " -"lifetimes. Most of the time, elision and type inference mean these don't " -"need to be written out. In more complicated cases, lifetime annotations can " -"help resolve ambiguity. Often, especially when prototyping, it's easier to " -"just work with owned data by cloning values where necessary." -msgstr "" - -#: src/slices-and-lifetimes/struct-lifetimes.md -msgid "Lifetimes in Data Structures" -msgstr "āĻĄā§‡āϟāĻž āĻ¸ā§āĻŸā§āϰāĻžāĻ•āϚāĻžāϰ āĻ āĻœā§€āĻŦāύāĻ•āĻžāϞ" - -#: src/slices-and-lifetimes/struct-lifetimes.md +#: src/lifetimes/struct-lifetimes.md msgid "" "If a data type stores borrowed data, it must be annotated with a lifetime:" msgstr "" -#: src/slices-and-lifetimes/struct-lifetimes.md -msgid "\"Bye {text}!\"" -msgstr "" - -#: src/slices-and-lifetimes/struct-lifetimes.md +#: src/lifetimes/struct-lifetimes.md msgid "\"The quick brown fox jumps over the lazy dog.\"" msgstr "" -#: src/slices-and-lifetimes/struct-lifetimes.md -msgid "// erase(text);" +#: src/lifetimes/struct-lifetimes.md +msgid "// drop(doc);\n" msgstr "" -#: src/slices-and-lifetimes/struct-lifetimes.md -msgid "\"{fox:?}\"" -msgstr "" - -#: src/slices-and-lifetimes/struct-lifetimes.md -msgid "\"{dog:?}\"" -msgstr "" - -#: src/slices-and-lifetimes/struct-lifetimes.md +#: src/lifetimes/struct-lifetimes.md msgid "" "In the above example, the annotation on `Highlight` enforces that the data " "underlying the contained `&str` lives at least as long as any instance of " -"`Highlight` that uses that data." +"`Highlight` that uses that data. A struct cannot live longer than the data " +"it references." msgstr "" -#: src/slices-and-lifetimes/struct-lifetimes.md +#: src/lifetimes/struct-lifetimes.md msgid "" -"If `text` is consumed before the end of the lifetime of `fox` (or `dog`), " -"the borrow checker throws an error." +"If `doc` is dropped before the end of the lifetime of `noun` or `verb`, the " +"borrow checker throws an error." msgstr "" -#: src/slices-and-lifetimes/struct-lifetimes.md +#: src/lifetimes/struct-lifetimes.md msgid "" "Types with borrowed data force users to hold on to the original data. This " "can be useful for creating lightweight views, but it generally makes them " "somewhat harder to use." msgstr "" -#: src/slices-and-lifetimes/struct-lifetimes.md +#: src/lifetimes/struct-lifetimes.md msgid "When possible, make data structures own their data directly." msgstr "" -#: src/slices-and-lifetimes/struct-lifetimes.md +#: src/lifetimes/struct-lifetimes.md msgid "" "Some structs with multiple references inside can have more than one lifetime " "annotation. This can be necessary if there is a need to describe lifetime " @@ -8747,7 +10555,7 @@ msgid "" "of the struct itself. Those are very advanced use cases." msgstr "" -#: src/slices-and-lifetimes/exercise.md +#: src/lifetimes/exercise.md msgid "" "In this exercise, you will build a parser for the [protobuf binary encoding]" "(https://protobuf.dev/programming-guides/encoding/). Don't worry, it's " @@ -8755,7 +10563,7 @@ msgid "" "slices of data. The underlying data itself is never copied." msgstr "" -#: src/slices-and-lifetimes/exercise.md +#: src/lifetimes/exercise.md msgid "" "Fully parsing a protobuf message requires knowing the types of the fields, " "indexed by their field numbers. That is typically provided in a `proto` " @@ -8763,128 +10571,183 @@ msgid "" "statements in functions that get called for each field." msgstr "" -#: src/slices-and-lifetimes/exercise.md +#: src/lifetimes/exercise.md msgid "We'll use the following proto:" msgstr "" -#: src/slices-and-lifetimes/exercise.md +#: src/lifetimes/exercise.md +msgid "Messages" +msgstr "" + +#: src/lifetimes/exercise.md msgid "" "A proto message is encoded as a series of fields, one after the next. Each " "is implemented as a \"tag\" followed by the value. The tag contains a field " "number (e.g., `2` for the `id` field of a `Person` message) and a wire type " -"defining how the payload should be determined from the byte stream." +"defining how the payload should be determined from the byte stream. These " +"are combined into a single integer, as decoded in `unpack_tag` below." msgstr "" -#: src/slices-and-lifetimes/exercise.md +#: src/lifetimes/exercise.md +msgid "Varint" +msgstr "" + +#: src/lifetimes/exercise.md msgid "" "Integers, including the tag, are represented with a variable-length encoding " -"called VARINT. Luckily, `parse_varint` is defined for you below. The given " -"code also defines callbacks to handle `Person` and `PhoneNumber` fields, and " -"to parse a message into a series of calls to those callbacks." +"called VARINT. Luckily, `parse_varint` is defined for you below." msgstr "" -#: src/slices-and-lifetimes/exercise.md +#: src/lifetimes/exercise.md +msgid "Wire Types" +msgstr "" + +#: src/lifetimes/exercise.md +msgid "" +"Proto defines several wire types, only two of which are used in this " +"exercise." +msgstr "" + +#: src/lifetimes/exercise.md +msgid "" +"The `Varint` wire type contains a single varint, and is used to encode proto " +"values of type `int32` such as `Person.id`." +msgstr "" + +#: src/lifetimes/exercise.md +msgid "" +"The `Len` wire type contains a length expressed as a varint, followed by a " +"payload of that number of bytes. This is used to encode proto values of type " +"`string` such as `Person.name`. It is also used to encode proto values " +"containing sub-messages such as `Person.phones`, where the payload contains " +"an encoding of the sub-message." +msgstr "" + +#: src/lifetimes/exercise.md +msgid "" +"The given code also defines callbacks to handle `Person` and `PhoneNumber` " +"fields, and to parse a message into a series of calls to those callbacks." +msgstr "" + +#: src/lifetimes/exercise.md msgid "" "What remains for you is to implement the `parse_field` function and the " "`ProtoMessage` trait for `Person` and `PhoneNumber`." msgstr "" -#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md -msgid "\"Invalid varint\"" -msgstr "" - -#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md -msgid "\"Invalid wire-type\"" -msgstr "" - -#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md -msgid "\"Unexpected EOF\"" -msgstr "" - -#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md -msgid "\"Invalid length\"" -msgstr "" - -#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md -msgid "\"Unexpected wire-type)\"" -msgstr "" - -#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md -msgid "\"Invalid string (not UTF-8)\"" -msgstr "" - -#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md +#: src/lifetimes/exercise.md src/lifetimes/solution.md msgid "/// A wire type as seen on the wire.\n" msgstr "" -#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md +#: src/lifetimes/exercise.md src/lifetimes/solution.md msgid "/// The Varint WireType indicates the value is a single VARINT.\n" msgstr "" -#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md +#: src/lifetimes/exercise.md src/lifetimes/solution.md msgid "" -"//I64, -- not needed for this exercise\n" +"// The I64 WireType indicates that the value is precisely 8 bytes in\n" +" // little-endian order containing a 64-bit signed integer or double " +"type.\n" +" //I64, -- not needed for this exercise\n" " /// The Len WireType indicates that the value is a length represented as " "a\n" " /// VARINT followed by exactly that number of bytes.\n" msgstr "" -#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md +#: src/lifetimes/exercise.md src/lifetimes/solution.md msgid "" -"/// The I32 WireType indicates that the value is precisely 4 bytes in\n" -" /// little-endian order containing a 32-bit signed integer.\n" +"// The I32 WireType indicates that the value is precisely 4 bytes in\n" +" // little-endian order containing a 32-bit signed integer or float " +"type.\n" +" //I32, -- not needed for this exercise\n" msgstr "" -#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md +#: src/lifetimes/exercise.md src/lifetimes/solution.md msgid "/// A field's value, typed based on the wire type.\n" msgstr "" -#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md +#: src/lifetimes/exercise.md src/lifetimes/solution.md msgid "//I64(i64), -- not needed for this exercise\n" msgstr "" -#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md +#: src/lifetimes/exercise.md src/lifetimes/solution.md +msgid "//I32(i32), -- not needed for this exercise\n" +msgstr "" + +#: src/lifetimes/exercise.md src/lifetimes/solution.md msgid "/// A field, containing the field number and its value.\n" msgstr "" -#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md +#: src/lifetimes/exercise.md src/lifetimes/solution.md msgid "//1 => WireType::I64, -- not needed for this exercise\n" msgstr "" -#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md +#: src/lifetimes/exercise.md src/lifetimes/solution.md +msgid "//5 => WireType::I32, -- not needed for this exercise\n" +msgstr "" + +#: src/lifetimes/exercise.md src/lifetimes/solution.md +msgid "\"Invalid wire type: {value}\"" +msgstr "" + +#: src/lifetimes/exercise.md src/lifetimes/solution.md +msgid "\"Expected string to be a `Len` field\"" +msgstr "" + +#: src/lifetimes/exercise.md src/lifetimes/solution.md +msgid "\"Invalid string\"" +msgstr "" + +#: src/lifetimes/exercise.md src/lifetimes/solution.md +msgid "\"Expected bytes to be a `Len` field\"" +msgstr "" + +#: src/lifetimes/exercise.md src/lifetimes/solution.md +msgid "\"Expected `u64` to be a `Varint` field\"" +msgstr "" + +#: src/lifetimes/exercise.md src/lifetimes/solution.md msgid "" "/// Parse a VARINT, returning the parsed value and the remaining bytes.\n" msgstr "" -#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md +#: src/lifetimes/exercise.md src/lifetimes/solution.md +msgid "\"Not enough bytes for varint\"" +msgstr "" + +#: src/lifetimes/exercise.md src/lifetimes/solution.md msgid "" "// This is the last byte of the VARINT, so convert it to\n" " // a u64 and return it.\n" msgstr "" -#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md +#: src/lifetimes/exercise.md src/lifetimes/solution.md msgid "// More than 7 bytes is invalid.\n" msgstr "" -#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md +#: src/lifetimes/exercise.md src/lifetimes/solution.md +msgid "\"Too many bytes for varint\"" +msgstr "" + +#: src/lifetimes/exercise.md src/lifetimes/solution.md msgid "/// Convert a tag into a field number and a WireType.\n" msgstr "" -#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md +#: src/lifetimes/exercise.md src/lifetimes/solution.md msgid "/// Parse a field, returning the remaining bytes\n" msgstr "" -#: src/slices-and-lifetimes/exercise.md +#: src/lifetimes/exercise.md msgid "" "\"Based on the wire type, build a Field, consuming as many bytes as " "necessary.\"" msgstr "" -#: src/slices-and-lifetimes/exercise.md +#: src/lifetimes/exercise.md msgid "\"Return the field, and any un-consumed bytes.\"" msgstr "" -#: src/slices-and-lifetimes/exercise.md src/slices-and-lifetimes/solution.md +#: src/lifetimes/exercise.md src/lifetimes/solution.md msgid "" "/// Parse a message in the given data, calling `T::add_field` for each field " "in\n" @@ -8893,114 +10756,346 @@ msgid "" "/// The entire input is consumed.\n" msgstr "" -#: src/slices-and-lifetimes/exercise.md -msgid "// TODO: Implement ProtoMessage for Person and PhoneNumber." +#: src/lifetimes/exercise.md +msgid "// TODO: Implement ProtoMessage for Person and PhoneNumber.\n" msgstr "" -#: src/slices-and-lifetimes/solution.md -msgid "// Unwrap error because `value` is definitely 4 bytes long.\n" +#: src/lifetimes/exercise.md src/lifetimes/solution.md src/modules/exercise.md +#: src/modules/solution.md src/testing/unit-tests.md src/testing/solution.md +msgid "\"\"" msgstr "" -#: src/slices-and-lifetimes/solution.md +#: src/lifetimes/exercise.md src/lifetimes/solution.md +msgid "\"beautiful name\"" +msgstr "" + +#: src/lifetimes/exercise.md src/lifetimes/solution.md +msgid "\"Evan\"" +msgstr "" + +#: src/lifetimes/exercise.md src/lifetimes/solution.md +msgid "\"+1234-777-9090\"" +msgstr "" + +#: src/lifetimes/exercise.md src/lifetimes/solution.md +msgid "\"home\"" +msgstr "" + +#: src/lifetimes/exercise.md src/lifetimes/solution.md +msgid "// Put that all together into a single parse.\n" +msgstr "" + +#: src/lifetimes/exercise.md src/lifetimes/solution.md +msgid "\"maxwell\"" +msgstr "" + +#: src/lifetimes/exercise.md src/lifetimes/solution.md +msgid "\"+1202-555-1212\"" +msgstr "" + +#: src/lifetimes/exercise.md src/lifetimes/solution.md +msgid "\"+1800-867-5308\"" +msgstr "" + +#: src/lifetimes/exercise.md src/lifetimes/solution.md +msgid "\"mobile\"" +msgstr "" + +#: src/lifetimes/exercise.md +msgid "" +"In this exercise there are various cases where protobuf parsing might fail, " +"e.g. if you try to parse an `i32` when there are fewer than 4 bytes left in " +"the data buffer. In normal Rust code we'd handle this with the `Result` " +"enum, but for simplicity in this exercise we panic if any errors are " +"encountered. On day 4 we'll cover error handling in Rust in more detail." +msgstr "" + +#: src/lifetimes/solution.md +msgid "// cast for simplicity\n" +msgstr "" + +#: src/lifetimes/solution.md msgid "// skip everything else\n" msgstr "" -#: src/slices-and-lifetimes/solution.md -msgid "b\"hello\"" -msgstr "" - #: src/welcome-day-4.md -#, fuzzy msgid "Welcome to Day 4" -msgstr "āĻĒā§āϰāĻĨāĻŽ āĻĻāĻŋāύ⧇ āφāĻĒāύāĻžāϕ⧇ āĻ¸ā§āĻŦāĻžāĻ—āϤāĻŽ" - -#: src/welcome-day-4.md -msgid "" -"Today we will cover topics relating to building large-scale software in Rust:" msgstr "" #: src/welcome-day-4.md -msgid "Iterators: a deep dive on the `Iterator` trait." -msgstr "" - -#: src/welcome-day-4.md -msgid "Modules and visibility." -msgstr "" - -#: src/welcome-day-4.md -#, fuzzy -msgid "Testing." -msgstr "āĻŸā§‡āĻ¸ā§āϟāĻŋāĻ‚" - -#: src/welcome-day-4.md -msgid "Error handling: panics, `Result`, and the try operator `?`." +msgid "We have mastered the core language and its unique safety model:" msgstr "" #: src/welcome-day-4.md msgid "" -"Unsafe Rust: the escape hatch when you can't express yourself in safe Rust." +"**Foundations & Abstraction:** Traits, generics, and the standard library." msgstr "" #: src/welcome-day-4.md -msgid "[Welcome](./welcome-day-4.md) (3 minutes)" +msgid "**Ownership:** Move semantics and the `Drop` trait." msgstr "" #: src/welcome-day-4.md -msgid "[Iterators](./iterators.md) (45 minutes)" +msgid "**Memory Management:** Borrowing rules (`&` vs `&mut`) and lifetimes." msgstr "" #: src/welcome-day-4.md -msgid "[Modules](./modules.md) (40 minutes)" -msgstr "" - -#: src/welcome-day-4.md -msgid "[Testing](./testing.md) (1 hour)" -msgstr "" - -#: src/iterators.md -msgid "[Iterator](./iterators/iterator.md) (5 minutes)" -msgstr "" - -#: src/iterators.md -msgid "[IntoIterator](./iterators/intoiterator.md) (5 minutes)" -msgstr "" - -#: src/iterators.md -msgid "[FromIterator](./iterators/fromiterator.md) (5 minutes)" -msgstr "" - -#: src/iterators.md msgid "" -"[Exercise: Iterator Method Chaining](./iterators/exercise.md) (30 minutes)" +"**Smart Pointers:** `Box`, `Rc`, and `RefCell` for complex data structures." +msgstr "" + +#: src/welcome-day-4.md +msgid "" +"You now understand how Rust guarantees memory safety at compile time! Today " +"we focus on applying this knowledge to build robust, large-scale " +"applications." +msgstr "" + +#: src/iterators.md +msgid "Iterator Trait" +msgstr "" + +#: src/iterators.md +msgid "Iterator Helper Methods" +msgstr "" + +#: src/iterators.md +msgid "collect" +msgstr "" + +#: src/iterators.md +msgid "IntoIterator" +msgstr "" + +#: src/iterators/motivation.md +msgid "Motivating Iterators" +msgstr "" + +#: src/iterators/motivation.md +msgid "" +"If you want to iterate over the contents of an array, you'll need to define:" +msgstr "" + +#: src/iterators/motivation.md +msgid "" +"Some state to keep track of where you are in the iteration process, e.g. an " +"index." +msgstr "" + +#: src/iterators/motivation.md +msgid "A condition to determine when iteration is done." +msgstr "" + +#: src/iterators/motivation.md +msgid "Logic for updating the state of iteration each loop." +msgstr "" + +#: src/iterators/motivation.md +msgid "Logic for fetching each element using that iteration state." +msgstr "" + +#: src/iterators/motivation.md +msgid "In a C-style for loop you declare these things directly:" +msgstr "" + +#: src/iterators/motivation.md +msgid "" +"In Rust we bundle this state and logic together into an object known as an " +"\"iterator\"." +msgstr "" + +#: src/iterators/motivation.md +msgid "" +"This slide provides context for what Rust iterators do under the hood. We " +"use the (hopefully) familiar construct of a C-style `for` loop to show how " +"iteration requires some state and some logic, that way on the next slide we " +"can show how an iterator bundles these together." +msgstr "" + +#: src/iterators/motivation.md +msgid "" +"Rust doesn't have a C-style `for` loop, but we can express the same thing " +"with `while`:" +msgstr "" + +#: src/iterators/motivation.md +msgid "" +"There's another way to express array iteration using `for` in C and C++: You " +"can use a pointer to the front and a pointer to the end of the array and " +"then compare those pointers to determine when the loop should end." +msgstr "" + +#: src/iterators/motivation.md +msgid "" +"If students ask, you can point out that this is how Rust's slice and array " +"iterators work under the hood (though implemented as a Rust iterator)." msgstr "" #: src/iterators/iterator.md msgid "" "The [`Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html) " -"trait supports iterating over values in a collection. It requires a `next` " -"method and provides lots of methods. Many standard library types implement " -"`Iterator`, and you can implement it yourself, too:" +"trait defines how an object can be used to produce a sequence of values. For " +"example, if we wanted to create an iterator that can produce the elements of " +"a slice it might look something like this:" msgstr "" #: src/iterators/iterator.md -msgid "\"fib({i}): {n}\"" +msgid "" +"The `SliceIter` example implements the same logic as the C-style `for` loop " +"demonstrated on the last slide." msgstr "" #: src/iterators/iterator.md msgid "" +"Point out to the students that iterators are lazy: Creating the iterator " +"just initializes the struct but does not otherwise do any work. No work " +"happens until the `next` method is called." +msgstr "" + +#: src/iterators/iterator.md +msgid "" +"Iterators don't need to be finite! It's entirely valid to have an iterator " +"that will produce values forever. For example, a half open range like `0..` " +"will keep going until integer overflow occurs." +msgstr "" + +#: src/iterators/iterator.md +msgid "" +"The \"real\" version of `SliceIter` is the [`slice::Iter`](https://doc.rust-" +"lang.org/stable/std/slice/struct.Iter.html) type in the standard library, " +"however the real version uses pointers under the hood instead of an index in " +"order to eliminate bounds checks." +msgstr "" + +#: src/iterators/iterator.md +msgid "" +"The `SliceIter` example is a good example of a struct that contains a " +"reference and therefore uses lifetime annotations." +msgstr "" + +#: src/iterators/iterator.md +msgid "" +"You can also demonstrate adding a generic parameter to `SliceIter` to allow " +"it to work with any kind of slice (not just `&[i32]`)." +msgstr "" + +#: src/iterators/helpers.md +msgid "" +"In addition to the `next` method that defines how an iterator behaves, the " +"`Iterator` trait provides 70+ helper methods that can be used to build " +"customized iterators." +msgstr "" + +#: src/iterators/helpers.md +msgid "// Create a range from 1 to 10\n" +msgstr "" + +#: src/iterators/helpers.md +msgid "// Keep only even numbers\n" +msgstr "" + +#: src/iterators/helpers.md +msgid "// Square each number\n" +msgstr "" + +#: src/iterators/helpers.md +msgid "// Sum up all the squared numbers\n" +msgstr "" + +#: src/iterators/helpers.md +msgid "\"The sum of squares of even numbers from 1 to 10 is: {}\"" +msgstr "" + +#: src/iterators/helpers.md +msgid "" "The `Iterator` trait implements many common functional programming " "operations over collections (e.g. `map`, `filter`, `reduce`, etc). This is " -"the trait where you can find all the documentation about them. In Rust these " -"functions should produce the code as efficient as equivalent imperative " -"implementations." +"the trait where you can find all the documentation about them." msgstr "" -#: src/iterators/iterator.md +#: src/iterators/helpers.md msgid "" -"`IntoIterator` is the trait that makes for loops work. It is implemented by " -"collection types such as `Vec` and references to them such as `&Vec` " -"and `&[T]`. Ranges also implement it. This is why you can iterate over a " -"vector with `for i in some_vec { .. }` but `some_vec.next()` doesn't exist." +"Many of these helper methods take the original iterator and produce a new " +"iterator with different behavior. These are know as \"iterator adapter " +"methods\"." +msgstr "" + +#: src/iterators/helpers.md +msgid "" +"Some methods, like `sum` and `count`, consume the iterator and pull all of " +"the elements out of it." +msgstr "" + +#: src/iterators/helpers.md +msgid "" +"These methods are designed to be chained together so that it's easy to build " +"a custom iterator that does exactly what you need." +msgstr "" + +#: src/iterators/helpers.md +msgid "" +"Rust's iterators are extremely efficient and highly optimizable. Even " +"complex iterators made by combining many adapter methods will still result " +"in code as efficient as equivalent imperative implementations." +msgstr "" + +#: src/iterators/collect.md +msgid "" +"The [`collect`](https://doc.rust-lang.org/std/iter/trait.Iterator." +"html#method.collect) method lets you build a collection from an [`Iterator`]" +"(https://doc.rust-lang.org/std/iter/trait.Iterator.html)." +msgstr "" + +#: src/iterators/collect.md +msgid "\"prime_squares: {prime_squares:?}\"" +msgstr "" + +#: src/iterators/collect.md +msgid "" +"Any iterator can be collected in to a `Vec`, `VecDeque`, or `HashSet`. " +"Iterators that produce key-value pairs (i.e. a two-element tuple) can also " +"be collected into `HashMap` and `BTreeMap`." +msgstr "" + +#: src/iterators/collect.md +msgid "" +"Show the students the definition for `collect` in the standard library docs. " +"There are two ways to specify the generic type `B` for this method:" +msgstr "" + +#: src/iterators/collect.md +msgid "" +"With the \"turbofish\": `some_iterator.collect::()`, as " +"shown. The `_` shorthand used here lets Rust infer the type of the `Vec` " +"elements." +msgstr "" + +#: src/iterators/collect.md +msgid "" +"With type inference: `let prime_squares: Vec<_> = some_iterator.collect()`. " +"Rewrite the example to use this form." +msgstr "" + +#: src/iterators/collect.md +msgid "" +"If students are curious about how this works, you can bring up the " +"[`FromIterator`](https://doc.rust-lang.org/std/iter/trait.FromIterator.html) " +"trait, which defines how each type of collection gets built from an iterator." +msgstr "" + +#: src/iterators/collect.md +msgid "" +"In addition to the basic implementations of `FromIterator` for `Vec`, " +"`HashMap`, etc., there are also more specialized implementations which let " +"you do cool things like convert an `Iterator>` into a " +"`Result, E>`." +msgstr "" + +#: src/iterators/collect.md +msgid "" +"The reason type annotations are often needed with `collect` is because it's " +"generic over its return type. This makes it harder for the compiler to infer " +"the correct type in many cases." msgstr "" #: src/iterators/intoiterator.md @@ -9015,6 +11110,14 @@ msgstr "" msgid "\"point = {x}, {y}\"" msgstr "" +#: src/iterators/intoiterator.md +msgid "" +"`IntoIterator` is the trait that makes for loops work. It is implemented by " +"collection types such as `Vec` and references to them such as `&Vec` " +"and `&[T]`. Ranges also implement it. This is why you can iterate over a " +"vector with `for i in some_vec { .. }` but `some_vec.next()` doesn't exist." +msgstr "" + #: src/iterators/intoiterator.md msgid "" "Click through to the docs for `IntoIterator`. Every implementation of " @@ -9047,8 +11150,10 @@ msgstr "" #: src/iterators/intoiterator.md msgid "" -"Fix this issue by implementing `IntoIterator` for `&Grid` and storing a " -"reference to the `Grid` in `GridIter`." +"Fix this issue by implementing `IntoIterator` for `&Grid` and creating a " +"`GridRefIter` that iterates by reference. A version with both `GridIter` and " +"`GridRefIter` is available [in this playground](https://play.rust-lang.org/?" +"version=stable&mode=debug&edition=2024&gist=947e371c7295af758504f01f149023a1)." msgstr "" #: src/iterators/intoiterator.md @@ -9059,52 +11164,6 @@ msgid "" "over references to elements of `some_vector`." msgstr "" -#: src/iterators/fromiterator.md -msgid "FromIterator" -msgstr "FromIterator" - -#: src/iterators/fromiterator.md -msgid "" -"[`FromIterator`](https://doc.rust-lang.org/std/iter/trait.FromIterator.html) " -"lets you build a collection from an [`Iterator`](https://doc.rust-lang.org/" -"std/iter/trait.Iterator.html)." -msgstr "" -"[`FromIterator`](https://doc.rust-lang.org/std/iter/trait.FromIterator.html) " -"āφāĻĒāύāĻžāϕ⧇ [`Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html) " -"āĻĨ⧇āϕ⧇ āĻāĻ•āϟāĻŋ āϏāĻ‚āĻ—ā§āϰāĻš āϤ⧈āϰāĻŋ āĻ•āϰāϤ⧇ āĻĻ⧇āϝāĻŧ|" - -#: src/iterators/fromiterator.md -msgid "\"prime_squares: {prime_squares:?}\"" -msgstr "\"prime_squares: {prime_squares:?}\"" - -#: src/iterators/fromiterator.md -msgid "`Iterator` implements" -msgstr "" - -#: src/iterators/fromiterator.md -msgid "There are two ways to specify `B` for this method:" -msgstr "" - -#: src/iterators/fromiterator.md -msgid "" -"With the \"turbofish\": `some_iterator.collect::()`, as " -"shown. The `_` shorthand used here lets Rust infer the type of the `Vec` " -"elements." -msgstr "" - -#: src/iterators/fromiterator.md -msgid "" -"With type inference: `let prime_squares: Vec<_> = some_iterator.collect()`. " -"Rewrite the example to use this form." -msgstr "" - -#: src/iterators/fromiterator.md -msgid "" -"There are basic implementations of `FromIterator` for `Vec`, `HashMap`, etc. " -"There are also more specialized implementations which let you do cool things " -"like convert an `Iterator>` into a `Result, E>`." -msgstr "" - #: src/iterators/exercise.md msgid "" "In this exercise, you will need to find and use some of the provided methods " @@ -9128,25 +11187,8 @@ msgid "" "/// Element `n` of the result is `values[(n+offset)%len] - values[n]`.\n" msgstr "" -#: src/modules.md -msgid "[Modules](./modules/modules.md) (3 minutes)" -msgstr "" - -#: src/modules.md -msgid "[Filesystem Hierarchy](./modules/filesystem.md) (5 minutes)" -msgstr "" - -#: src/modules.md -msgid "[Visibility](./modules/visibility.md) (5 minutes)" -msgstr "" - -#: src/modules.md -msgid "[use, super, self](./modules/paths.md) (10 minutes)" -msgstr "" - -#: src/modules.md -msgid "" -"[Exercise: Modules for a GUI Library](./modules/exercise.md) (15 minutes)" +#: src/modules.md src/modules/paths.md +msgid "use, super, self" msgstr "" #: src/modules/modules.md @@ -9188,7 +11230,7 @@ msgstr "" #: src/modules/filesystem.md msgid "" -"This tells rust that the `garden` module content is found at `src/garden." +"This tells Rust that the `garden` module content is found at `src/garden." "rs`. Similarly, a `garden::vegetables` module can be found at `src/garden/" "vegetables.rs`." msgstr "" @@ -9215,24 +11257,20 @@ msgstr "" #: src/modules/filesystem.md msgid "" "//! This module implements the garden, including a highly performant " -"germination" +"germination\n" +"//! implementation.\n" msgstr "" #: src/modules/filesystem.md -#, fuzzy -msgid "//! implementation." -msgstr "āĻŦāĻžāĻ¸ā§āϤāĻŦāĻžāϝāĻŧāύ" - -#: src/modules/filesystem.md -msgid "// Re-export types from this module." +msgid "// Re-export types from this module.\n" msgstr "" #: src/modules/filesystem.md -msgid "/// Sow the given seed packets." +msgid "/// Sow the given seed packets.\n" msgstr "" #: src/modules/filesystem.md -msgid "/// Harvest the produce in the garden that is ready." +msgid "/// Harvest the produce in the garden that is ready.\n" msgstr "" #: src/modules/filesystem.md @@ -9253,7 +11291,7 @@ msgstr "" #: src/modules/filesystem.md msgid "" -"The place rust will look for modules can be changed with a compiler " +"The place Rust will look for modules can be changed with a compiler " "directive:" msgstr "" @@ -9331,8 +11369,80 @@ msgid "" "its descendants)." msgstr "" -#: src/modules/paths.md -msgid "use, super, self" +#: src/modules/encapsulation.md +msgid "Visibility and Encapsulation" +msgstr "" + +#: src/modules/encapsulation.md +msgid "" +"Like with items in a module, struct fields are also private by default. " +"Private fields are likewise visible within the rest of the module (including " +"child modules). This allows us to encapsulate implementation details of " +"struct, controlling what data and functionality is visible externally." +msgstr "" + +#: src/modules/encapsulation.md +msgid "\"Is {} big? {}\"" +msgstr "" + +#: src/modules/encapsulation.md +msgid "\"foo.val = {}\"" +msgstr "" + +#: src/modules/encapsulation.md +msgid "// let foo = Foo { val: 42, is_big: true };\n" +msgstr "" + +#: src/modules/encapsulation.md +msgid "// println!(\"Is {} big? {}\", foo.val, foo.is_big);\n" +msgstr "" + +#: src/modules/encapsulation.md +msgid "" +"This slide demonstrates how privacy in structs is module-based. Students " +"coming from object-oriented languages may be used to types being the " +"encapsulation boundary, so this demonstrates how Rust behaves differently " +"while showing how we can still achieve encapsulation." +msgstr "" + +#: src/modules/encapsulation.md +msgid "" +"Note how the `is_big` field is fully controlled by `Foo`, allowing `Foo` to " +"control how it's initialized and enforce any invariants it needs to (e.g. " +"that `is_big` is only `true` if `val > 100`)." +msgstr "" + +#: src/modules/encapsulation.md +msgid "" +"Point out how helper functions can be defined in the same module (including " +"child modules) in order to get access to the type's private fields/methods." +msgstr "" + +#: src/modules/encapsulation.md +msgid "" +"The first commented out line demonstrates that you cannot initialize a " +"struct with private fields. The second one demonstrates that you also can't " +"directly access private fields." +msgstr "" + +#: src/modules/encapsulation.md +msgid "" +"Enums do not support privacy: Variants and data within those variants is " +"always public." +msgstr "" + +#: src/modules/encapsulation.md +msgid "" +"If students want more information about privacy (or lack thereof) in enums, " +"you can bring up `#[doc_hidden]` and `#[non_exhaustive]` and show how " +"they're used to limit what can be done with an enum." +msgstr "" + +#: src/modules/encapsulation.md +msgid "" +"Module privacy still applies when there are `impl` blocks in other modules " +"[(example in the playground)](https://play.rust-lang.org/?" +"version=stable&mode=debug&edition=2024&gist=3e61f43c88de12bcdf69c1d6df9ab3da)." msgstr "" #: src/modules/paths.md @@ -9343,7 +11453,7 @@ msgstr "" #: src/modules/paths.md msgid "Paths" -msgstr "Paths" +msgstr "" #: src/modules/paths.md msgid "Paths are resolved as follows:" @@ -9415,9 +11525,8 @@ msgid "" msgstr "" #: src/modules/exercise.md -#, fuzzy msgid "Cargo Setup" -msgstr "āϏ⧇āϟāφāĻĒ" +msgstr "" #: src/modules/exercise.md msgid "" @@ -9439,15 +11548,15 @@ msgstr "" msgid "Here's the single-module implementation of the GUI library:" msgstr "" -#: src/modules/exercise.md +#: src/modules/exercise.md src/modules/solution.md msgid "/// Natural width of `self`.\n" msgstr "" -#: src/modules/exercise.md +#: src/modules/exercise.md src/modules/solution.md msgid "/// Draw the widget into a buffer.\n" msgstr "" -#: src/modules/exercise.md +#: src/modules/exercise.md src/modules/solution.md msgid "/// Draw the widget on standard output.\n" msgstr "" @@ -9470,11 +11579,6 @@ msgstr "" msgid "\"+-{:-. Then use\n" +" // the ?-operator here instead of .unwrap().\n" msgstr "" #: src/modules/solution.md -msgid "// ANCHOR_END: Window-width" -msgstr "" - -#: src/modules/solution.md -msgid "// Add 4 paddings for borders" -msgstr "" - -#: src/modules/solution.md -msgid "// ANCHOR: Window-draw_into" -msgstr "" - -#: src/modules/solution.md -msgid "// ANCHOR_END: Window-draw_into" -msgstr "" - -#: src/modules/solution.md -msgid "// TODO: after learning about error handling, you can change" -msgstr "" - -#: src/modules/solution.md -msgid "// draw_into to return Result<(), std::fmt::Error>. Then use" -msgstr "" - -#: src/modules/solution.md -msgid "// the ?-operator here instead of .unwrap()." -msgstr "" - -#: src/modules/solution.md -msgid "// ---- src/main.rs ----" -msgstr "" - -#: src/testing.md -msgid "[Test Modules](./testing/unit-tests.md) (5 minutes)" -msgstr "" - -#: src/testing.md -msgid "[Other Types of Tests](./testing/other.md) (5 minutes)" -msgstr "" - -#: src/testing.md -msgid "[Useful Crates](./testing/useful-crates.md) (3 minutes)" -msgstr "" - -#: src/testing.md -msgid "[GoogleTest](./testing/googletest.md) (5 minutes)" -msgstr "" - -#: src/testing.md -msgid "[Mocking](./testing/mocking.md) (5 minutes)" -msgstr "" - -#: src/testing.md -msgid "[Compiler Lints and Clippy](./testing/lints.md) (3 minutes)" -msgstr "" - -#: src/testing.md -msgid "[Exercise: Luhn Algorithm](./testing/exercise.md) (30 minutes)" -msgstr "" - -#: src/testing/unit-tests.md -msgid "Unit Tests" -msgstr "āχāωāύāĻŋāϟ āĻŸā§‡āĻ¸ā§āϟ" - -#: src/testing/unit-tests.md -msgid "Rust and Cargo come with a simple unit test framework:" -msgstr "" - -#: src/testing/unit-tests.md -msgid "Unit tests are supported throughout your code." -msgstr "" - -#: src/testing/unit-tests.md -msgid "Integration tests are supported via the `tests/` directory." +msgid "// ---- src/main.rs ----\n" msgstr "" #: src/testing/unit-tests.md msgid "" -"Tests are marked with `#[test]`. Unit tests are often put in a nested " -"`tests` module, using `#[cfg(test)]` to conditionally compile them only when " -"building tests." +"Rust and Cargo come with a simple unit test framework. Tests are marked with " +"`#[test]`. Unit tests are often put in a nested `tests` module, using " +"`#[cfg(test)]` to conditionally compile them only when building tests." msgstr "" #: src/testing/unit-tests.md -#, fuzzy msgid "\"Hello World\"" -msgstr "Hello World!" +msgstr "" #: src/testing/unit-tests.md msgid "This lets you unit test private helpers." @@ -9670,13 +11706,9 @@ msgstr "" msgid "The `#[cfg(test)]` attribute is only active when you run `cargo test`." msgstr "" -#: src/testing/unit-tests.md -msgid "Run the tests in the playground in order to show their results." -msgstr "" - #: src/testing/other.md msgid "Integration Tests" -msgstr "āχāĻ¨ā§āϟāĻŋāĻ—ā§āϰ⧇āĻļāύ āĻŸā§‡āĻ¸ā§āϟ" +msgstr "" #: src/testing/other.md msgid "If you want to test your library as a client, use an integration test." @@ -9687,7 +11719,7 @@ msgid "Create a `.rs` file under `tests/`:" msgstr "" #: src/testing/other.md -msgid "// tests/my_library.rs" +msgid "// tests/my_library.rs\n" msgstr "" #: src/testing/other.md @@ -9696,30 +11728,21 @@ msgstr "" #: src/testing/other.md msgid "Documentation Tests" -msgstr "āĻĄāϕ⧁āĻŽā§‡āĻ¨ā§āĻŸā§‡āĻļāύ āĻŸā§‡āĻ¸ā§āϟ" +msgstr "" #: src/testing/other.md msgid "Rust has built-in support for documentation tests:" msgstr "" #: src/testing/other.md -msgid "/// Shortens a string to the given length." -msgstr "" - -#: src/testing/other.md -msgid "/// ```" -msgstr "" - -#: src/testing/other.md -msgid "/// # use playground::shorten_string;" -msgstr "" - -#: src/testing/other.md -msgid "/// assert_eq!(shorten_string(\"Hello World\", 5), \"Hello\");" -msgstr "" - -#: src/testing/other.md -msgid "/// assert_eq!(shorten_string(\"Hello World\", 20), \"Hello World\");" +msgid "" +"/// Shortens a string to the given length.\n" +"///\n" +"/// ```\n" +"/// # use playground::shorten_string;\n" +"/// assert_eq!(shorten_string(\"Hello World\", 5), \"Hello\");\n" +"/// assert_eq!(shorten_string(\"Hello World\", 20), \"Hello World\");\n" +"/// ```\n" msgstr "" #: src/testing/other.md @@ -9739,163 +11762,7 @@ msgstr "" #: src/testing/other.md msgid "" "Test the above code on the [Rust Playground](https://play.rust-lang.org/?" -"version=stable&mode=debug&edition=2021&gist=3ce2ad13ea1302f6572cb15cd96becf0)." -msgstr "" - -#: src/testing/useful-crates.md -msgid "Rust comes with only basic support for writing tests." -msgstr "" - -#: src/testing/useful-crates.md -msgid "Here are some additional crates which we recommend for writing tests:" -msgstr "" - -#: src/testing/useful-crates.md -msgid "" -"[googletest](https://docs.rs/googletest): Comprehensive test assertion " -"library in the tradition of GoogleTest for C++." -msgstr "" - -#: src/testing/useful-crates.md -msgid "[proptest](https://docs.rs/proptest): Property-based testing for Rust." -msgstr "" - -#: src/testing/useful-crates.md -msgid "" -"[rstest](https://docs.rs/rstest): Support for fixtures and parameterised " -"tests." -msgstr "" - -#: src/testing/googletest.md -msgid "" -"The [GoogleTest](https://docs.rs/googletest/) crate allows for flexible test " -"assertions using _matchers_:" -msgstr "" - -#: src/testing/googletest.md -msgid "\"baz\"" -msgstr "" - -#: src/testing/googletest.md -msgid "\"xyz\"" -msgstr "" - -#: src/testing/googletest.md -msgid "" -"If we change the last element to `\"!\"`, the test fails with a structured " -"error message pin-pointing the error:" -msgstr "" - -#: src/testing/googletest.md -msgid "" -"GoogleTest is not part of the Rust Playground, so you need to run this " -"example in a local environment. Use `cargo add googletest` to quickly add it " -"to an existing Cargo project." -msgstr "" - -#: src/testing/googletest.md -msgid "" -"The `use googletest::prelude::*;` line imports a number of [commonly used " -"macros and types](https://docs.rs/googletest/latest/googletest/prelude/index." -"html)." -msgstr "" - -#: src/testing/googletest.md -msgid "This just scratches the surface, there are many builtin matchers." -msgstr "" - -#: src/testing/googletest.md -msgid "" -"A particularly nice feature is that mismatches in multi-line strings are " -"shown as a diff:" -msgstr "" - -#: src/testing/googletest.md -msgid "" -"\"Memory safety found,\\n\\\n" -" Rust's strong typing guides the way,\\n\\\n" -" Secure code you'll write.\"" -msgstr "" - -#: src/testing/googletest.md -msgid "" -"\"Memory safety found,\\n\\\n" -" Rust's silly humor guides the way,\\n\\\n" -" Secure code you'll write.\"" -msgstr "" - -#: src/testing/googletest.md -msgid "shows a color-coded diff (colors not shown here):" -msgstr "" - -#: src/testing/googletest.md -msgid "" -"The crate is a Rust port of [GoogleTest for C++](https://google.github.io/" -"googletest/)." -msgstr "" - -#: src/testing/googletest.md -msgid "GoogleTest is available for use in AOSP." -msgstr "" - -#: src/testing/mocking.md -msgid "" -"For mocking, [Mockall](https://docs.rs/mockall/) is a widely used library. " -"You need to refactor your code to use traits, which you can then quickly " -"mock:" -msgstr "" - -#: src/testing/mocking.md -msgid "" -"The advice here is for Android (AOSP) where Mockall is the recommended " -"mocking library. There are other [mocking libraries available on crates.io]" -"(https://crates.io/keywords/mock), in particular in the area of mocking HTTP " -"services. The other mocking libraries work in a similar fashion as Mockall, " -"meaning that they make it easy to get a mock implementation of a given trait." -msgstr "" - -#: src/testing/mocking.md -msgid "" -"Note that mocking is somewhat _controversial_: mocks allow you to completely " -"isolate a test from its dependencies. The immediate result is faster and " -"more stable test execution. On the other hand, the mocks can be configured " -"wrongly and return output different from what the real dependencies would do." -msgstr "" - -#: src/testing/mocking.md -msgid "" -"If at all possible, it is recommended that you use the real dependencies. As " -"an example, many databases allow you to configure an in-memory backend. This " -"means that you get the correct behavior in your tests, plus they are fast " -"and will automatically clean up after themselves." -msgstr "" - -#: src/testing/mocking.md -msgid "" -"Similarly, many web frameworks allow you to start an in-process server which " -"binds to a random port on `localhost`. Always prefer this over mocking away " -"the framework since it helps you test your code in the real environment." -msgstr "" - -#: src/testing/mocking.md -msgid "" -"Mockall is not part of the Rust Playground, so you need to run this example " -"in a local environment. Use `cargo add mockall` to quickly add Mockall to an " -"existing Cargo project." -msgstr "" - -#: src/testing/mocking.md -msgid "" -"Mockall has a lot more functionality. In particular, you can set up " -"expectations which depend on the arguments passed. Here we use this to mock " -"a cat which becomes hungry 3 hours after the last time it was fed:" -msgstr "" - -#: src/testing/mocking.md -msgid "" -"You can use `.times(n)` to limit the number of times a mock method can be " -"called to `n` --- the mock will automatically panic when dropped if this " -"isn't satisfied." +"version=stable&mode=debug&edition=2024&gist=3ce2ad13ea1302f6572cb15cd96becf0)." msgstr "" #: src/testing/lints.md @@ -9911,16 +11778,10 @@ msgstr "" #: src/testing/lints.md msgid "" -"Run the code sample and examine the error message. There are also lints " -"visible here, but those will not be shown once the code compiles. Switch to " -"the Playground site to show those lints." -msgstr "" - -#: src/testing/lints.md -msgid "" -"After resolving the lints, run `clippy` on the playground site to show " -"clippy warnings. Clippy has extensive documentation of its lints, and adds " -"new lints (including default-deny lints) all the time." +"There are compiler lints visible here, but not clippy lints. Run `clippy` on " +"the playground site to show clippy warnings. Clippy has extensive " +"documentation of its lints, and adds new lints (including default-deny " +"lints) all the time." msgstr "" #: src/testing/lints.md @@ -9929,10 +11790,6 @@ msgid "" "or via your editor." msgstr "" -#: src/testing/exercise.md -msgid "Luhn Algorithm" -msgstr "āϞ⧁āύ āĻ…ā§āϝāĻžāϞāĻ—āϰāĻŋāĻĻāĻŽ" - #: src/testing/exercise.md msgid "" "The [Luhn algorithm](https://en.wikipedia.org/wiki/Luhn_algorithm) is used " @@ -9941,7 +11798,9 @@ msgid "" msgstr "" #: src/testing/exercise.md -msgid "Ignore all spaces. Reject number with fewer than two digits." +msgid "" +"Ignore all spaces. Reject numbers with fewer than two digits. Reject letters " +"and other non-digit characters." msgstr "" #: src/testing/exercise.md @@ -9966,8 +11825,8 @@ msgstr "" #: src/testing/exercise.md msgid "" -"The provided code provides a buggy implementation of the luhn algorithm, " -"along with two basic unit tests that confirm that most the algorithm is " +"The provided code provides a buggy implementation of the Luhn algorithm, " +"along with two basic unit tests that confirm that most of the algorithm is " "implemented correctly." msgstr "" @@ -10003,27 +11862,15 @@ msgid "\"8273 1232 7352 0569\"" msgstr "" #: src/testing/solution.md -msgid "// This is the buggy version that appears in the problem.\n" +msgid "// New: accept whitespace.\n" msgstr "" #: src/testing/solution.md -msgid "// This is the solution and passes all of the tests below.\n" +msgid "// New: reject all other characters.\n" msgstr "" #: src/testing/solution.md -msgid "\"1234 5678 1234 5670\"" -msgstr "" - -#: src/testing/solution.md -msgid "\"Is {cc_number} a valid credit card number? {}\"" -msgstr "" - -#: src/testing/solution.md -msgid "\"yes\"" -msgstr "" - -#: src/testing/solution.md -msgid "\"no\"" +msgid "// New: check that we have at least two digits\n" msgstr "" #: src/testing/solution.md @@ -10031,6 +11878,7 @@ msgid "\"foo 0 0\"" msgstr "" #: src/testing/solution.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/struct.md msgid "\" \"" msgstr "" @@ -10050,50 +11898,24 @@ msgstr "" msgid "\" 0 0 \"" msgstr "" -#: src/welcome-day-4-afternoon.md -msgid "[Error Handling](./error-handling.md) (55 minutes)" -msgstr "" - -#: src/welcome-day-4-afternoon.md -msgid "[Unsafe Rust](./unsafe-rust.md) (1 hour and 5 minutes)" +#: src/error-handling.md +msgid "Error Trait" msgstr "" #: src/error-handling.md -msgid "[Panics](./error-handling/panics.md) (3 minutes)" +msgid "thiserror" msgstr "" #: src/error-handling.md -msgid "[Try Operator](./error-handling/try.md) (5 minutes)" +msgid "anyhow" msgstr "" -#: src/error-handling.md -msgid "[Try Conversions](./error-handling/try-conversions.md) (5 minutes)" -msgstr "" - -#: src/error-handling.md -msgid "[Error Trait](./error-handling/error.md) (5 minutes)" -msgstr "" - -#: src/error-handling.md -msgid "" -"[thiserror and anyhow](./error-handling/thiserror-and-anyhow.md) (5 minutes)" -msgstr "" - -#: src/error-handling.md -msgid "" -"[Exercise: Rewriting with Result](./error-handling/exercise.md) (30 minutes)" +#: src/error-handling.md src/error-handling/exercise.md +msgid "Exercise: Rewriting with Result" msgstr "" #: src/error-handling/panics.md -msgid "Rust handles fatal errors with a \"panic\"." -msgstr "" - -#: src/error-handling/panics.md -msgid "Rust will trigger a panic if a fatal error happens at runtime:" -msgstr "" - -#: src/error-handling/panics.md -msgid "\"v[100]: {}\"" +msgid "In case of a fatal runtime error, Rust triggers a \"panic\":" msgstr "" #: src/error-handling/panics.md @@ -10105,11 +11927,11 @@ msgid "Panics are symptoms of bugs in the program." msgstr "" #: src/error-handling/panics.md -msgid "Runtime failures like failed bounds checks can panic" +msgid "Runtime failures like failed bounds checks can panic." msgstr "" #: src/error-handling/panics.md -msgid "Assertions (such as `assert!`) panic on failure" +msgid "Assertions (such as `assert!`) panic on failure." msgstr "" #: src/error-handling/panics.md @@ -10137,10 +11959,6 @@ msgstr "" msgid "\"No problem here!\"" msgstr "" -#: src/error-handling/panics.md -msgid "\"{result:?}\"" -msgstr "" - #: src/error-handling/panics.md msgid "\"oh no!\"" msgstr "" @@ -10161,6 +11979,79 @@ msgstr "" msgid "This does not work if `panic = 'abort'` is set in your `Cargo.toml`." msgstr "" +#: src/error-handling/result.md +msgid "" +"Our primary mechanism for error handling in Rust is the [`Result`](https://" +"doc.rust-lang.org/stable/std/result/enum.Result.html) enum, which we briefly " +"saw when discussing standard library types." +msgstr "" + +#: src/error-handling/result.md +msgid "" +"`Result` has two variants: `Ok` which contains the success value, and `Err` " +"which contains an error value of some kind." +msgstr "" + +#: src/error-handling/result.md +msgid "" +"Whether or not a function can produce an error is encoded in the function's " +"type signature by having the function return a `Result` value." +msgstr "" + +#: src/error-handling/result.md +msgid "" +"Like with `Option`, there is no way to forget to handle an error: You cannot " +"access either the success value or the error value without first pattern " +"matching on the `Result` to check which variant you have. Methods like " +"`unwrap` make it easier to write quick-and-dirty code that doesn't do robust " +"error handling, but means that you can always see in your source code where " +"proper error handling is being skipped." +msgstr "" + +#: src/error-handling/result.md +msgid "" +"It may be helpful to compare error handling in Rust to error handling " +"conventions that students may be familiar with from other programming " +"languages." +msgstr "" + +#: src/error-handling/result.md +msgid "Many languages use exceptions, e.g. C++, Java, Python." +msgstr "" + +#: src/error-handling/result.md +msgid "" +"In most languages with exceptions, whether or not a function can throw an " +"exception is not visible as part of its type signature. This generally means " +"that you can't tell when calling a function if it may throw an exception or " +"not." +msgstr "" + +#: src/error-handling/result.md +msgid "" +"Exceptions generally unwind the call stack, propagating upward until a `try` " +"block is reached. An error originating deep in the call stack may impact an " +"unrelated function further up." +msgstr "" + +#: src/error-handling/result.md +msgid "Error Numbers" +msgstr "" + +#: src/error-handling/result.md +msgid "" +"Some languages have functions return an error number (or some other error " +"value) separately from the successful return value of the function. Examples " +"include C and Go." +msgstr "" + +#: src/error-handling/result.md +msgid "" +"Depending on the language it may be possible to forget to check the error " +"value, in which case you may be accessing an uninitialized or otherwise " +"invalid success value." +msgstr "" + #: src/error-handling/try.md msgid "" "Runtime errors like connection-refused or file-not-found are handled with " @@ -10178,11 +12069,11 @@ msgid "We can use this to simplify our error handling code:" msgstr "" #: src/error-handling/try.md -msgid "//fs::write(\"config.dat\", \"alice\").unwrap();" +msgid "//fs::write(\"config.dat\", \"alice\").unwrap();\n" msgstr "" #: src/error-handling/try.md src/error-handling/try-conversions.md -#: src/error-handling/thiserror-and-anyhow.md +#: src/error-handling/thiserror.md src/error-handling/anyhow.md msgid "\"config.dat\"" msgstr "" @@ -10230,7 +12121,7 @@ msgid "" msgstr "" #: src/error-handling/try-conversions.md -msgid "\"IO error: {e}\"" +msgid "\"I/O error: {e}\"" msgstr "" #: src/error-handling/try-conversions.md @@ -10238,8 +12129,7 @@ msgid "\"Found no username in {path}\"" msgstr "" #: src/error-handling/try-conversions.md -#: src/error-handling/thiserror-and-anyhow.md -msgid "//fs::write(\"config.dat\", \"\").unwrap();" +msgid "//std::fs::write(\"config.dat\", \"\").unwrap();\n" msgstr "" #: src/error-handling/try-conversions.md @@ -10273,7 +12163,7 @@ msgstr "" #: src/error-handling/error.md msgid "Dynamic Error Types" -msgstr "āĻĄāĻžāϝāĻŧāύāĻžāĻŽāĻŋāĻ• āĻ¤ā§āϰ⧁āϟāĻŋāϰ āϧāϰāύ" +msgstr "" #: src/error-handling/error.md msgid "" @@ -10295,7 +12185,7 @@ msgstr "" msgid "\"Count: {count}\"" msgstr "" -#: src/error-handling/error.md +#: src/error-handling/error.md src/error-handling/thiserror.md msgid "\"Error: {err}\"" msgstr "" @@ -10317,236 +12207,172 @@ msgstr "" #: src/error-handling/error.md msgid "" "Make sure to implement the `std::error::Error` trait when defining a custom " -"error type so it can be boxed. But if you need to support the `no_std` " -"attribute, keep in mind that the `std::error::Error` trait is currently " -"compatible with `no_std` in [nightly](https://github.com/rust-lang/rust/" -"issues/103765) only." +"error type so it can be boxed." msgstr "" -#: src/error-handling/thiserror-and-anyhow.md +#: src/error-handling/thiserror.md msgid "" -"The [`thiserror`](https://docs.rs/thiserror/) and [`anyhow`](https://docs.rs/" -"anyhow/) crates are widely used to simplify error handling." +"The [`thiserror`](https://docs.rs/thiserror/) crate provides macros to help " +"avoid boilerplate when defining error types. It provides derive macros that " +"assist in implementing `From`, `Display`, and the `Error` trait." msgstr "" -#: src/error-handling/thiserror-and-anyhow.md -msgid "" -"`thiserror` is often used in libraries to create custom error types that " -"implement `From`." +#: src/error-handling/thiserror.md +msgid "\"I/O error: {0}\"" msgstr "" -#: src/error-handling/thiserror-and-anyhow.md -msgid "" -"`anyhow` is often used by applications to help with error handling in " -"functions, including adding contextual information to your errors." -msgstr "" - -#: src/error-handling/thiserror-and-anyhow.md +#: src/error-handling/thiserror.md src/error-handling/anyhow.md msgid "\"Found no username in {0}\"" msgstr "" -#: src/error-handling/thiserror-and-anyhow.md -msgid "\"Failed to open {path}\"" +#: src/error-handling/thiserror.md src/error-handling/anyhow.md +msgid "//fs::write(\"config.dat\", \"\").unwrap();\n" msgstr "" -#: src/error-handling/thiserror-and-anyhow.md -msgid "\"Failed to read\"" -msgstr "" - -#: src/error-handling/thiserror-and-anyhow.md +#: src/error-handling/thiserror.md src/error-handling/anyhow.md msgid "\"Username: {username}\"" msgstr "" -#: src/error-handling/thiserror-and-anyhow.md -msgid "\"Error: {err:?}\"" -msgstr "" - -#: src/error-handling/thiserror-and-anyhow.md -msgid "`thiserror`" -msgstr "" - -#: src/error-handling/thiserror-and-anyhow.md +#: src/error-handling/thiserror.md msgid "" "The `Error` derive macro is provided by `thiserror`, and has lots of useful " "attributes to help define error types in a compact way." msgstr "" -#: src/error-handling/thiserror-and-anyhow.md -msgid "The `std::error::Error` trait is derived automatically." -msgstr "" - -#: src/error-handling/thiserror-and-anyhow.md +#: src/error-handling/thiserror.md msgid "The message from `#[error]` is used to derive the `Display` trait." msgstr "" -#: src/error-handling/thiserror-and-anyhow.md -msgid "`anyhow`" +#: src/error-handling/thiserror.md +msgid "" +"Note that the (`thiserror::`)`Error` derive macro, while it has the effect " +"of implementing the (`std::error::`)`Error` trait, is not the same this; " +"traits and macros do not share a namespace." msgstr "" -#: src/error-handling/thiserror-and-anyhow.md +#: src/error-handling/anyhow.md +msgid "" +"The [`anyhow`](https://docs.rs/anyhow/) crate provides a rich error type " +"with support for carrying additional contextual information, which can be " +"used to provide a semantic trace of what the program was doing leading up to " +"the error." +msgstr "" + +#: src/error-handling/anyhow.md +msgid "" +"This can be combined with the convenience macros from [`thiserror`](https://" +"docs.rs/thiserror/) to avoid writing out trait impls explicitly for custom " +"error types." +msgstr "" + +#: src/error-handling/anyhow.md +msgid "\"Failed to open {path}\"" +msgstr "" + +#: src/error-handling/anyhow.md +msgid "\"Failed to read\"" +msgstr "" + +#: src/error-handling/anyhow.md +msgid "\"Error: {err:?}\"" +msgstr "" + +#: src/error-handling/anyhow.md msgid "" "`anyhow::Error` is essentially a wrapper around `Box`. As such " "it's again generally not a good choice for the public API of a library, but " "is widely used in applications." msgstr "" -#: src/error-handling/thiserror-and-anyhow.md +#: src/error-handling/anyhow.md msgid "`anyhow::Result` is a type alias for `Result`." msgstr "" -#: src/error-handling/thiserror-and-anyhow.md +#: src/error-handling/anyhow.md msgid "" -"Actual error type inside of it can be extracted for examination if necessary." +"Functionality provided by `anyhow::Error` may be familiar to Go developers, " +"as it provides similar behavior to the Go `error` type and `Result` is much like a Go `(T, error)` (with the convention that " +"only one element of the pair is meaningful)." msgstr "" -#: src/error-handling/thiserror-and-anyhow.md -msgid "" -"Functionality provided by `anyhow::Result` may be familiar to Go " -"developers, as it provides similar usage patterns and ergonomics to `(T, " -"error)` from Go." -msgstr "" - -#: src/error-handling/thiserror-and-anyhow.md +#: src/error-handling/anyhow.md msgid "" "`anyhow::Context` is a trait implemented for the standard `Result` and " "`Option` types. `use anyhow::Context` is necessary to enable `.context()` " "and `.with_context()` on those types." msgstr "" -#: src/error-handling/exercise.md -msgid "Exercise: Rewriting with Result" +#: src/error-handling/anyhow.md +msgid "" +"`anyhow::Error` has support for downcasting, much like `std::any::Any`; the " +"specific error type stored inside can be extracted for examination if " +"desired with [`Error::downcast`](https://docs.rs/anyhow/latest/anyhow/struct." +"Error.html#method.downcast)." msgstr "" #: src/error-handling/exercise.md msgid "" -"The following implements a very simple parser for an expression language. " -"However, it handles errors by panicking. Rewrite it to instead use idiomatic " -"error handling and propagate errors to a return from `main`. Feel free to " -"use `thiserror` and `anyhow`." +"In this exercise we're revisiting the expression evaluator exercise that we " +"did in day 2. Our initial solution ignores a possible error case: Dividing " +"by zero! Rewrite `eval` to instead use idiomatic error handling to handle " +"this error case and return an error when it occurs. We provide a simple " +"`DivideByZeroError` type to use as the error type for `eval`." msgstr "" #: src/error-handling/exercise.md msgid "" -"HINT: start by fixing error handling in the `parse` function. Once that is " -"working correctly, update `Tokenizer` to implement " -"`Iterator>` and handle that in the parser." -msgstr "" - -#: src/error-handling/exercise.md src/error-handling/solution.md -msgid "/// An arithmetic operator.\n" -msgstr "" - -#: src/error-handling/exercise.md src/error-handling/solution.md -msgid "/// A token in the expression language.\n" -msgstr "" - -#: src/error-handling/exercise.md src/error-handling/solution.md -msgid "/// An expression in the expression language.\n" -msgstr "" - -#: src/error-handling/exercise.md src/error-handling/solution.md -msgid "/// A reference to a variable.\n" -msgstr "" - -#: src/error-handling/exercise.md src/error-handling/solution.md -msgid "/// A literal number.\n" -msgstr "" - -#: src/error-handling/exercise.md src/error-handling/solution.md -msgid "/// A binary operation.\n" -msgstr "" - -#: src/error-handling/exercise.md src/error-handling/solution.md -msgid "'z'" -msgstr "" - -#: src/error-handling/exercise.md src/error-handling/solution.md -msgid "'_'" -msgstr "" - -#: src/error-handling/exercise.md src/error-handling/solution.md -msgid "'+'" -msgstr "" - -#: src/error-handling/exercise.md src/error-handling/solution.md -msgid "'-'" +"// The original implementation of the expression evaluator. Update this to\n" +"// return a `Result` and produce an error when dividing by 0.\n" msgstr "" #: src/error-handling/exercise.md -msgid "\"Unexpected character {c}\"" -msgstr "" - -#: src/error-handling/exercise.md src/error-handling/solution.md -msgid "\"Unexpected end of input\"" +msgid "\"Cannot divide by zero!\"" msgstr "" #: src/error-handling/exercise.md -msgid "\"Invalid 32-bit integer'\"" -msgstr "" - -#: src/error-handling/exercise.md -msgid "\"Unexpected token {tok:?}\"" -msgstr "" - -#: src/error-handling/exercise.md src/error-handling/solution.md -msgid "// Look ahead to parse a binary operation if present.\n" -msgstr "" - -#: src/error-handling/exercise.md src/error-handling/solution.md -msgid "\"10+foo+20-30\"" -msgstr "" - -#: src/error-handling/exercise.md src/error-handling/solution.md -msgid "\"{expr:?}\"" -msgstr "" - -#: src/error-handling/solution.md -msgid "\"Unexpected character '{0}' in input\"" -msgstr "" - -#: src/error-handling/solution.md -msgid "\"Tokenizer error: {0}\"" -msgstr "" - -#: src/error-handling/solution.md -msgid "\"Unexpected token {0:?}\"" -msgstr "" - -#: src/error-handling/solution.md -msgid "\"Invalid number\"" -msgstr "" - -#: src/unsafe-rust.md -msgid "[Unsafe](./unsafe-rust/unsafe.md) (5 minutes)" -msgstr "" - -#: src/unsafe-rust.md msgid "" -"[Dereferencing Raw Pointers](./unsafe-rust/dereferencing.md) (10 minutes)" +"The starting code here isn't exactly the same as the previous exercise's " +"solution: We've added in an explicit panic to show students where the error " +"case is. Point this out if students get confused." msgstr "" -#: src/unsafe-rust.md -msgid "[Mutable Static Variables](./unsafe-rust/mutable-static.md) (5 minutes)" +#: src/error-handling/solution.md +msgid "" +"**`Result` Return Type:** The function signature changes to return " +"`Result`. This explicit type signature forces the " +"caller to handle the possibility of failure." msgstr "" -#: src/unsafe-rust.md -msgid "[Unions](./unsafe-rust/unions.md) (5 minutes)" +#: src/error-handling/solution.md +msgid "" +"**The `?` Operator:** We use `?` on the recursive calls: `eval(*left)?`. " +"This cleanly propagates errors. If `eval` returns `Err`, the function " +"immediately returns that `Err`. If it returns `Ok(v)`, `v` is assigned to " +"`left` (or `right`)." msgstr "" -#: src/unsafe-rust.md -msgid "[Unsafe Functions](./unsafe-rust/unsafe-functions.md) (5 minutes)" +#: src/error-handling/solution.md +msgid "**`Ok` Wrapping:** Successful results must be wrapped in `Ok(...)`." msgstr "" -#: src/unsafe-rust.md -msgid "[Unsafe Traits](./unsafe-rust/unsafe-traits.md) (5 minutes)" +#: src/error-handling/solution.md +msgid "" +"**Handling Division by Zero:** We explicitly check for `right == 0` and " +"return `Err(DivideByZeroError)`. This replaces the panic in the original " +"code." msgstr "" -#: src/unsafe-rust.md -msgid "[Exercise: FFI Wrapper](./unsafe-rust/exercise.md) (30 minutes)" +#: src/error-handling/solution.md +msgid "" +"Mention that `DivideByZeroError` is a unit struct (no fields), which is " +"sufficient here since there's no extra context to provide about the error." msgstr "" -#: src/unsafe-rust.md -msgid "This segment should take about 1 hour and 5 minutes" +#: src/error-handling/solution.md +msgid "" +"Discuss how `?` makes error handling almost as concise as exceptions, but " +"with explicit control flow." msgstr "" #: src/unsafe-rust/unsafe.md @@ -10571,8 +12397,8 @@ msgstr "" #: src/unsafe-rust/unsafe.md msgid "" -"Unsafe code is usually small and isolated, and its correctness should be " -"carefully documented. It is usually wrapped in a safe abstraction layer." +"Unsafe code should be small and isolated, and its correctness should be " +"carefully documented. It should be wrapped in a safe abstraction layer." msgstr "" #: src/unsafe-rust/unsafe.md @@ -10619,48 +12445,34 @@ msgid "Creating pointers is safe, but dereferencing them requires `unsafe`:" msgstr "" #: src/unsafe-rust/dereferencing.md -msgid "\"careful!\"" +msgid "" +"// SAFETY: p1 and p2 were created by taking raw pointers to a local, so " +"they\n" +" // are guaranteed to be non-null, aligned, and point into a single " +"(stack-)\n" +" // allocated object.\n" +" //\n" +" // The object underlying the raw pointers lives for the entire function, " +"so\n" +" // it is not deallocated while the raw pointers still exist. It is not\n" +" // accessed through references while the raw pointers exist, nor is it\n" +" // accessed from other threads concurrently.\n" msgstr "" #: src/unsafe-rust/dereferencing.md -msgid "// Safe because r1 and r2 were obtained from references and so are" +msgid "// Mutation may soundly be observed through a raw pointer, like in C.\n" msgstr "" #: src/unsafe-rust/dereferencing.md msgid "" -"// guaranteed to be non-null and properly aligned, the objects underlying" -msgstr "" - -#: src/unsafe-rust/dereferencing.md -msgid "// the references from which they were obtained are live throughout the" -msgstr "" - -#: src/unsafe-rust/dereferencing.md -msgid "// whole unsafe block, and they are not accessed either through the" -msgstr "" - -#: src/unsafe-rust/dereferencing.md -msgid "// references or concurrently through any other pointers." -msgstr "" - -#: src/unsafe-rust/dereferencing.md -msgid "\"r1 is: {}\"" -msgstr "" - -#: src/unsafe-rust/dereferencing.md -msgid "\"uhoh\"" -msgstr "" - -#: src/unsafe-rust/dereferencing.md -msgid "\"r2 is: {}\"" -msgstr "" - -#: src/unsafe-rust/dereferencing.md -msgid "// NOT SAFE. DO NOT DO THIS." -msgstr "" - -#: src/unsafe-rust/dereferencing.md -msgid "/*" +"// UNSOUND. DO NOT DO THIS.\n" +" /*\n" +" let r: &i32 = unsafe { &*p1 };\n" +" dbg!(r);\n" +" x = 50;\n" +" dbg!(r); // Object underlying the reference has been mutated. This is " +"UB.\n" +" */" msgstr "" #: src/unsafe-rust/dereferencing.md @@ -10706,9 +12518,12 @@ msgstr "" #: src/unsafe-rust/dereferencing.md msgid "" -"The \"NOT SAFE\" section gives an example of a common kind of UB bug: `*r1` " -"has the `'static` lifetime, so `r3` has type `&'static String`, and thus " -"outlives `s`. Creating a reference from a pointer requires _great care_." +"The \"UNSOUND\" section gives an example of a common kind of UB bug: naïvely " +"taking a reference to the dereference of a raw pointer sidesteps the " +"compiler's knowledge of what object the reference is actually pointing to. " +"As such, the borrow checker does not freeze `x` and so we are able to modify " +"it despite the existence of a reference to it. Creating a reference from a " +"pointer requires _great care_." msgstr "" #: src/unsafe-rust/mutable-static.md @@ -10716,9 +12531,8 @@ msgid "It is safe to read an immutable static variable:" msgstr "" #: src/unsafe-rust/mutable-static.md -#, fuzzy msgid "\"Hello, world!\"" -msgstr "Hello World!" +msgstr "" #: src/unsafe-rust/mutable-static.md msgid "\"HELLO_WORLD: {HELLO_WORLD}\"" @@ -10726,27 +12540,47 @@ msgstr "" #: src/unsafe-rust/mutable-static.md msgid "" -"However, since data races can occur, it is unsafe to read and write mutable " -"static variables:" -msgstr "" - -#: src/unsafe-rust/mutable-static.md -msgid "\"COUNTER: {COUNTER}\"" +"However, mutable static variables are unsafe to read and write because " +"multiple threads could do so concurrently without synchronization, " +"constituting a data race." msgstr "" #: src/unsafe-rust/mutable-static.md msgid "" -"The program here is safe because it is single-threaded. However, the Rust " -"compiler is conservative and will assume the worst. Try removing the " -"`unsafe` and see how the compiler explains that it is undefined behavior to " -"mutate a static from multiple threads." +"Using mutable statics soundly requires reasoning about concurrency without " +"the compiler's help:" msgstr "" #: src/unsafe-rust/mutable-static.md msgid "" -"Using a mutable static is generally a bad idea, but there are some cases " -"where it might make sense in low-level `no_std` code, such as implementing a " -"heap allocator or working with some C APIs." +"// SAFETY: There are no other threads which could be accessing `COUNTER`.\n" +msgstr "" + +#: src/unsafe-rust/mutable-static.md +msgid "" +"The program here is sound because it is single-threaded. However, the Rust " +"compiler reasons about functions individually so can't assume that. Try " +"removing the `unsafe` and see how the compiler explains that it is undefined " +"behavior to access a mutable static from multiple threads." +msgstr "" + +#: src/unsafe-rust/mutable-static.md +msgid "" +"The 2024 Rust edition goes further and makes accessing a mutable static by " +"reference an error by default." +msgstr "" + +#: src/unsafe-rust/mutable-static.md +msgid "" +"Using a mutable static is rarely a good idea, you should use interior " +"mutability instead." +msgstr "" + +#: src/unsafe-rust/mutable-static.md +msgid "" +"There are some cases where it might be necessary in low-level `no_std` code, " +"such as implementing a heap allocator or working with some C APIs. In this " +"case you should use pointers rather than references." msgstr "" #: src/unsafe-rust/unions.md @@ -10762,14 +12596,13 @@ msgid "\"bool: {}\"" msgstr "" #: src/unsafe-rust/unions.md -#, fuzzy -msgid "// Undefined behavior!" -msgstr "āϰāĻžāύāϟāĻžāχāĻŽā§‡ āϕ⧋āύ āĻ…āύāĻŋāĻ°ā§āϧāĻžāϰāĻŋāϤ āφāϚāϰāĻŖ āύ⧇āχ:" +msgid "// Undefined behavior!\n" +msgstr "" #: src/unsafe-rust/unions.md msgid "" -"Unions are very rarely needed in Rust as you can usually use an enum. They " -"are occasionally needed for interacting with C library APIs." +"Unions are rarely needed in Rust as enums provide a superior alternative. " +"They are occasionally needed for interacting with C library APIs." msgstr "" #: src/unsafe-rust/unions.md @@ -10780,135 +12613,214 @@ msgid "" "crates/zerocopy) crate." msgstr "" -#: src/unsafe-rust/unsafe-functions.md -msgid "Calling Unsafe Functions" -msgstr "āĻ…āύāĻŋāϰāĻžāĻĒāĻĻ āĻĢāĻžāĻ‚āĻļāύ āĻĄāĻžāĻ•āĻž" - #: src/unsafe-rust/unsafe-functions.md msgid "" "A function or method can be marked `unsafe` if it has extra preconditions " -"you must uphold to avoid undefined behaviour:" -msgstr "" - -#: src/unsafe-rust/unsafe-functions.md src/unsafe-rust/exercise.md -#: src/unsafe-rust/solution.md src/android/interoperability/with-c.md -#: src/android/interoperability/with-c/rust.md -#: src/android/interoperability/cpp/cpp-bridge.md -#: src/exercises/chromium/build-rules.md src/bare-metal/aps/inline-assembly.md -#: src/bare-metal/aps/better-uart/using.md src/bare-metal/aps/logging/using.md -#: src/exercises/bare-metal/solutions-afternoon.md -msgid "\"C\"" +"you must uphold to avoid undefined behaviour." msgstr "" #: src/unsafe-rust/unsafe-functions.md -msgid "\"đŸ—ģ∈🌏\"" +msgid "Unsafe functions may come from two places:" msgstr "" #: src/unsafe-rust/unsafe-functions.md -msgid "" -"// Safe because the indices are in the correct order, within the bounds of" +msgid "Rust functions declared unsafe." msgstr "" #: src/unsafe-rust/unsafe-functions.md -msgid "// the string slice, and lie on UTF-8 sequence boundaries." +msgid "Unsafe foreign functions in `extern \"C\"` blocks." msgstr "" #: src/unsafe-rust/unsafe-functions.md -msgid "\"emoji: {}\"" +msgid "We will look at the two kinds of unsafe functions next." msgstr "" -#: src/unsafe-rust/unsafe-functions.md -msgid "\"char count: {}\"" -msgstr "" - -#: src/unsafe-rust/unsafe-functions.md -#, fuzzy -msgid "// Undefined behavior if abs misbehaves." -msgstr "āϰāĻžāύāϟāĻžāχāĻŽā§‡ āϕ⧋āύ āĻ…āύāĻŋāĻ°ā§āϧāĻžāϰāĻŋāϤ āφāϚāϰāĻŖ āύ⧇āχ:" - -#: src/unsafe-rust/unsafe-functions.md -msgid "\"Absolute value of -3 according to C: {}\"" -msgstr "" - -#: src/unsafe-rust/unsafe-functions.md -msgid "// Not upholding the UTF-8 encoding requirement breaks memory safety!" -msgstr "" - -#: src/unsafe-rust/unsafe-functions.md -msgid "// println!(\"emoji: {}\", unsafe { emojis.get_unchecked(0..3) });" -msgstr "" - -#: src/unsafe-rust/unsafe-functions.md -msgid "// println!(\"char count: {}\", count_chars(unsafe {" -msgstr "" - -#: src/unsafe-rust/unsafe-functions.md -msgid "// emojis.get_unchecked(0..3) }));" -msgstr "" - -#: src/unsafe-rust/unsafe-functions.md -msgid "Writing Unsafe Functions" -msgstr "āĻ…āύāĻŋāϰāĻžāĻĒāĻĻ āĻĢāĻžāĻ‚āĻļāύ āϞ⧇āĻ–āĻž" - -#: src/unsafe-rust/unsafe-functions.md +#: src/unsafe-rust/unsafe-functions/rust.md msgid "" "You can mark your own functions as `unsafe` if they require particular " -"conditions to avoid undefined behaviour." +"preconditions to avoid undefined behaviour." msgstr "" -#: src/unsafe-rust/unsafe-functions.md -msgid "/// Swaps the values pointed to by the given pointers." +#: src/unsafe-rust/unsafe-functions/rust.md +msgid "" +"/// Swaps the values pointed to by the given pointers.\n" +"///\n" +"/// # Safety\n" +"///\n" +"/// The pointers must be valid, properly aligned, and not otherwise accessed " +"for\n" +"/// the duration of the function call.\n" msgstr "" -#: src/unsafe-rust/unsafe-functions.md src/unsafe-rust/unsafe-traits.md -msgid "/// # Safety" +#: src/unsafe-rust/unsafe-functions/rust.md +msgid "" +"// SAFETY: Our caller promised that the pointers are valid, properly " +"aligned\n" +" // and have no other access.\n" msgstr "" -#: src/unsafe-rust/unsafe-functions.md -msgid "/// The pointers must be valid and properly aligned." +#: src/unsafe-rust/unsafe-functions/rust.md +msgid "" +"// SAFETY: The pointers must be valid, aligned and unique because they came\n" +" // from references.\n" msgstr "" -#: src/unsafe-rust/unsafe-functions.md -msgid "// Safe because ..." -msgstr "" - -#: src/unsafe-rust/unsafe-functions.md +#: src/unsafe-rust/unsafe-functions/rust.md msgid "\"a = {}, b = {}\"" msgstr "" -#: src/unsafe-rust/unsafe-functions.md +#: src/unsafe-rust/unsafe-functions/rust.md msgid "" -"`get_unchecked`, like most `_unchecked` functions, is unsafe, because it can " -"create UB if the range is incorrect. `abs` is incorrect for a different " -"reason: it is an external function (FFI). Calling external functions is " -"usually only a problem when those functions do things with pointers which " -"might violate Rust's memory model, but in general any C function might have " -"undefined behaviour under any arbitrary circumstances." +"We wouldn't actually use pointers for a `swap` function --- it can be done " +"safely with references." msgstr "" -#: src/unsafe-rust/unsafe-functions.md +#: src/unsafe-rust/unsafe-functions/rust.md +msgid "" +"Note that Rust 2021 and earlier allow unsafe code within an unsafe function " +"without an `unsafe` block. This changed in the 2024 edition. We can prohibit " +"it in older editions with `#[deny(unsafe_op_in_unsafe_fn)]`. Try adding it " +"and see what happens." +msgstr "" + +#: src/unsafe-rust/unsafe-functions/extern-c.md +msgid "" +"You can declare foreign functions for access from Rust with `unsafe extern`. " +"This is unsafe because the compiler has no way to reason about their " +"behavior. Functions declared in an `extern` block must be marked as `safe` " +"or `unsafe`, depending on whether they have preconditions for safe use:" +msgstr "" + +#: src/unsafe-rust/unsafe-functions/extern-c.md src/unsafe-rust/exercise.md +#: src/unsafe-rust/solution.md src/android/interoperability/with-c.md +#: src/android/interoperability/with-c/rust-library.md +#: src/android/interoperability/cpp/cpp-bridge.md +#: src/exercises/chromium/build-rules.md src/bare-metal/aps/inline-assembly.md +#: src/bare-metal/aps/uart/using.md src/bare-metal/aps/safemmio/using.md +#: src/bare-metal/aps/logging/using.md +#: src/unsafe-deep-dive/ffi/language-differences/semantics.md +#: src/unsafe-deep-dive/ffi/abs.md +#: src/unsafe-deep-dive/ffi/c-library-example.md +#: src/unsafe-deep-dive/ffi/cpp-library-example.md +msgid "\"C\"" +msgstr "" + +#: src/unsafe-rust/unsafe-functions/extern-c.md +msgid "" +"// `abs` doesn't deal with pointers and doesn't have any safety " +"requirements.\n" +msgstr "" + +#: src/unsafe-rust/unsafe-functions/extern-c.md +msgid "" +"/// # Safety\n" +" ///\n" +" /// `s` must be a pointer to a NUL-terminated C string which is valid " +"and\n" +" /// not modified for the duration of this function call.\n" +msgstr "" + +#: src/unsafe-rust/unsafe-functions/extern-c.md +msgid "\"Absolute value of -3 according to C: {}\"" +msgstr "" + +#: src/unsafe-rust/unsafe-functions/extern-c.md +msgid "" +"// SAFETY: We pass a pointer to a C string literal which is valid for\n" +" // the duration of the program.\n" +msgstr "" + +#: src/unsafe-rust/unsafe-functions/extern-c.md +msgid "\"String length: {}\"" +msgstr "" + +#: src/unsafe-rust/unsafe-functions/extern-c.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/clone.md +msgid "\"String\"" +msgstr "" + +#: src/unsafe-rust/unsafe-functions/extern-c.md +msgid "" +"Rust used to consider all extern functions unsafe, but this changed in Rust " +"1.82 with `unsafe extern` blocks." +msgstr "" + +#: src/unsafe-rust/unsafe-functions/extern-c.md +msgid "" +"`abs` must be explicitly marked as `safe` because it is an external function " +"(FFI). Calling external functions is only a problem when those functions do " +"things with pointers which might violate Rust's memory model, but in general " +"any C function might have undefined behaviour under any arbitrary " +"circumstances." +msgstr "" + +#: src/unsafe-rust/unsafe-functions/extern-c.md msgid "" "The `\"C\"` in this example is the ABI; [other ABIs are available too]" "(https://doc.rust-lang.org/reference/items/external-blocks.html)." msgstr "" -#: src/unsafe-rust/unsafe-functions.md +#: src/unsafe-rust/unsafe-functions/extern-c.md msgid "" -"We wouldn't actually use pointers for a `swap` function - it can be done " -"safely with references." +"Note that there is no verification that the Rust function signature matches " +"that of the function definition -- that's up to you!" msgstr "" -#: src/unsafe-rust/unsafe-functions.md +#: src/unsafe-rust/unsafe-functions/calling.md +msgid "Failing to uphold the safety requirements breaks memory safety!" +msgstr "" + +#: src/unsafe-rust/unsafe-functions/calling.md +msgid "// 8 bytes\n" +msgstr "" + +#: src/unsafe-rust/unsafe-functions/calling.md +msgid "\"{pk:?}\"" +msgstr "" + +#: src/unsafe-rust/unsafe-functions/calling.md msgid "" -"Note that unsafe code is allowed within an unsafe function without an " -"`unsafe` block. We can prohibit this with `#[deny(unsafe_op_in_unsafe_fn)]`. " -"Try adding it and see what happens. This will likely change in a future Rust " -"edition." +"Always include a safety comment for each `unsafe` block. It must explain why " +"the code is actually safe. This example is missing a safety comment and is " +"unsound." +msgstr "" + +#: src/unsafe-rust/unsafe-functions/calling.md +msgid "" +"The second argument to `slice::from_raw_parts` is the number of _elements_, " +"not bytes! This example demonstrates unexpected behavior by reading past the " +"end of one array and into another." +msgstr "" + +#: src/unsafe-rust/unsafe-functions/calling.md +msgid "" +"This is undefined behavior because we're reading past the end of the array " +"that the pointer was derived from." +msgstr "" + +#: src/unsafe-rust/unsafe-functions/calling.md +msgid "" +"`log_public_key` should be unsafe, because `pk_ptr` must meet certain " +"prerequisites to avoid undefined behaviour. A safe function which can cause " +"undefined behaviour is said to be `unsound`. What should its safety " +"documentation say?" +msgstr "" + +#: src/unsafe-rust/unsafe-functions/calling.md +msgid "" +"The standard library contains a number of low-level unsafe functions. Prefer " +"the safe alternatives when possible!" +msgstr "" + +#: src/unsafe-rust/unsafe-functions/calling.md +msgid "" +"If you use an unsafe function as an optimization, make sure to add a " +"benchmark to demonstrate the gain." msgstr "" #: src/unsafe-rust/unsafe-traits.md msgid "Implementing Unsafe Traits" -msgstr "āĻ…āύāĻŋāϰāĻžāĻĒāĻĻ Traits āĻŦāĻžāĻ¸ā§āϤāĻŦāĻžāϝāĻŧāύ" +msgstr "" #: src/unsafe-rust/unsafe-traits.md msgid "" @@ -10919,19 +12831,18 @@ msgstr "" #: src/unsafe-rust/unsafe-traits.md msgid "" "For example, the `zerocopy` crate has an unsafe trait that looks [something " -"like this](https://docs.rs/zerocopy/latest/zerocopy/trait.AsBytes.html):" +"like this](https://docs.rs/zerocopy/latest/zerocopy/trait.IntoBytes.html):" msgstr "" #: src/unsafe-rust/unsafe-traits.md -msgid "/// ..." +msgid "" +"/// ...\n" +"/// # Safety\n" +"/// The type must have a defined representation and no padding.\n" msgstr "" #: src/unsafe-rust/unsafe-traits.md -msgid "/// The type must have a defined representation and no padding." -msgstr "" - -#: src/unsafe-rust/unsafe-traits.md -msgid "// Safe because u32 has a defined representation and no padding." +msgid "// SAFETY: `u32` has a defined representation and no padding.\n" msgstr "" #: src/unsafe-rust/unsafe-traits.md @@ -10942,7 +12853,7 @@ msgstr "" #: src/unsafe-rust/unsafe-traits.md msgid "" -"The actual safety section for `AsBytes` is rather longer and more " +"The actual safety section for `IntoBytes` is rather longer and more " "complicated." msgstr "" @@ -10952,7 +12863,7 @@ msgstr "" #: src/unsafe-rust/exercise.md msgid "Safe FFI Wrapper" -msgstr "āύāĻŋāϰāĻžāĻĒāĻĻ FFI āĻŽā§‹āĻĄāĻŧāĻ•" +msgstr "" #: src/unsafe-rust/exercise.md msgid "" @@ -11045,13 +12956,13 @@ msgid "" msgstr "" #: src/unsafe-rust/exercise.md -msgid "`CString` to `*const i8`: you need a pointer to call C functions," +msgid "`CString` to `*const c_char`: you need a pointer to call C functions," msgstr "" #: src/unsafe-rust/exercise.md msgid "" -"`*const i8` to `&CStr`: you need something which can find the trailing `\\0` " -"character," +"`*const c_char` to `&CStr`: you need something which can find the trailing " +"`\\0` character," msgstr "" #: src/unsafe-rust/exercise.md @@ -11084,6 +12995,10 @@ msgid "" "functions and methods:" msgstr "" +#: src/unsafe-rust/exercise.md +msgid "// TODO: remove this when you're done with your implementation.\n" +msgstr "" + #: src/unsafe-rust/exercise.md src/unsafe-rust/solution.md msgid "\"macos\"" msgstr "" @@ -11122,22 +13037,22 @@ msgstr "" msgid "\"readdir$INODE64\"" msgstr "" -#: src/unsafe-rust/exercise.md +#: src/unsafe-rust/exercise.md src/unsafe-rust/solution.md msgid "" "// Call opendir and return a Ok value if that worked,\n" -" // otherwise return Err with a message." +" // otherwise return Err with a message.\n" msgstr "" #: src/unsafe-rust/exercise.md -msgid "// Keep calling readdir until we get a NULL pointer back." +msgid "// Keep calling readdir until we get a NULL pointer back.\n" msgstr "" #: src/unsafe-rust/exercise.md -msgid "// Call closedir as needed." +msgid "// Call closedir as needed.\n" msgstr "" #: src/unsafe-rust/exercise.md src/unsafe-rust/solution.md -#: src/android/interoperability/with-c/rust.md +#: src/android/interoperability/with-c/rust-library.md msgid "\".\"" msgstr "" @@ -11145,10 +13060,11 @@ msgstr "" msgid "\"files: {:#?}\"" msgstr "" -#: src/unsafe-rust/solution.md +#: src/unsafe-rust/exercise.md msgid "" -"// Call opendir and return a Ok value if that worked,\n" -" // otherwise return Err with a message.\n" +"FFI binding code is typically generated by tools like [bindgen](https://" +"github.com/rust-lang/rust-bindgen), rather than being written manually as we " +"are doing here. However, bindgen can't run in an online playground." msgstr "" #: src/unsafe-rust/solution.md @@ -11160,7 +13076,7 @@ msgid "// SAFETY: path.as_ptr() cannot be NULL.\n" msgstr "" #: src/unsafe-rust/solution.md -msgid "\"Could not open {:?}\"" +msgid "\"Could not open {path:?}\"" msgstr "" #: src/unsafe-rust/solution.md @@ -11180,11 +13096,9 @@ msgid "" msgstr "" #: src/unsafe-rust/solution.md -msgid "// Call closedir as needed.\n" -msgstr "" - -#: src/unsafe-rust/solution.md -msgid "// SAFETY: self.dir is not NULL.\n" +msgid "" +"// Call closedir as needed.\n" +" // SAFETY: self.dir is never NULL.\n" msgstr "" #: src/unsafe-rust/solution.md @@ -11204,6 +13118,7 @@ msgid "\"..\"" msgstr "" #: src/unsafe-rust/solution.md +#: src/idiomatic/leveraging-the-type-system/raii/drop_option.md msgid "\"foo.txt\"" msgstr "" @@ -11227,6 +13142,62 @@ msgstr "" msgid "\"//! Crab\\n\"" msgstr "" +#: src/unsafe-rust/solution.md +msgid "" +"**Safety Comments:** Each `unsafe` block is preceded by a `// SAFETY:` " +"comment explaining why the operation is safe. This is standard practice in " +"Rust to aid auditing." +msgstr "" + +#: src/unsafe-rust/solution.md +msgid "" +"**String conversions:** The code demonstrates the conversions required for " +"FFI:" +msgstr "" + +#: src/unsafe-rust/solution.md +msgid "`&str` -> `CString`: To create a null-terminated string for C." +msgstr "" + +#: src/unsafe-rust/solution.md +msgid "`CString` -> `*const c_char`: To pass the pointer to C." +msgstr "" + +#: src/unsafe-rust/solution.md +msgid "`*const c_char` -> `&CStr`: To wrap the returned C string." +msgstr "" + +#: src/unsafe-rust/solution.md +msgid "" +"`&CStr` -> `&[u8]` -> `&OsStr` -> `OsString`: To convert the bytes back to a " +"Rust OS string." +msgstr "" + +#: src/unsafe-rust/solution.md +msgid "" +"**RAII (`Drop`):** We implement `Drop` to call `closedir` automatically when " +"the iterator goes out of scope. This ensures we don't leak file descriptors." +msgstr "" + +#: src/unsafe-rust/solution.md +msgid "" +"**Iterator Interface:** We wrap the C API in a Rust `Iterator`, providing a " +"safe and idiomatic interface (`next` returns `Option`) to the " +"underlying unsafe C functions." +msgstr "" + +#: src/unsafe-rust/solution.md +msgid "" +"Explain that `CString` owns the data (like `String`), while `CStr` is a " +"borrowed reference (like `&str`)." +msgstr "" + +#: src/unsafe-rust/solution.md +msgid "" +"The `OsStrExt` trait is needed on Unix systems to convert bytes directly to " +"`OsStr`." +msgstr "" + #: src/android.md msgid "Welcome to Rust in Android" msgstr "" @@ -11238,14 +13209,6 @@ msgid "" "existing code as needed)." msgstr "" -#: src/android.md -msgid "" -"We will attempt to call Rust from one of your own projects today. So try to " -"find a little corner of your code base where we can move some lines of code " -"to Rust. The fewer dependencies and \"exotic\" types the better. Something " -"that parses some raw bytes would be ideal." -msgstr "" - #: src/android.md msgid "" "The speaker may mention any of the following given the increased use of Rust " @@ -11255,25 +13218,25 @@ msgstr "" #: src/android.md msgid "" "Service example: [DNS over HTTP](https://security.googleblog.com/2022/07/dns-" -"over-http3-in-android.html)" +"over-http3-in-android.html)." msgstr "" #: src/android.md msgid "" "Libraries: [Rutabaga Virtual Graphics Interface](https://crosvm.dev/book/" -"appendix/rutabaga_gfx.html)" +"appendix/rutabaga_gfx.html)." msgstr "" #: src/android.md msgid "" "Kernel Drivers: [Binder](https://lore.kernel.org/rust-for-linux/20231101-" -"rust-binder-v1-0-08ba9197f637@google.com/)" +"rust-binder-v1-0-08ba9197f637@google.com/)." msgstr "" #: src/android.md msgid "" "Firmware: [pKVM firmware](https://security.googleblog.com/2023/10/bare-metal-" -"rust-in-android.html)" +"rust-in-android.html)." msgstr "" #: src/android/setup.md @@ -11288,6 +13251,14 @@ msgid "" "setup/start) for details." msgstr "" +#: src/android/setup.md +msgid "" +"The code on the following pages can be found in the [`src/android/` " +"directory](https://github.com/google/comprehensive-rust/tree/main/src/" +"android) of the course material. Please `git clone` the repository to follow " +"along." +msgstr "" + #: src/android/setup.md msgid "" "Cuttlefish is a reference Android device designed to work on generic Linux " @@ -11301,7 +13272,7 @@ msgid "" msgstr "" #: src/android/build-rules.md -msgid "The Android build system (Soong) supports Rust via a number of modules:" +msgid "The Android build system (Soong) supports Rust through several modules:" msgstr "" #: src/android/build-rules.md @@ -11389,37 +13360,25 @@ msgid "We will look at `rust_binary` and `rust_library` next." msgstr "" #: src/android/build-rules.md -msgid "Additional items speaker may mention:" +msgid "Additional items the speaker may mention:" msgstr "" #: src/android/build-rules.md msgid "" -"Cargo is not optimized for multi-language repos, and also downloads packages " -"from the internet." +"Cargo is not optimized for multi-language repositories, and also downloads " +"packages from the internet." msgstr "" #: src/android/build-rules.md msgid "" "For compliance and performance, Android must have crates in-tree. It must " -"also interop with C/C++/Java code. Soong fills that gap." +"also interoperate with C/C++/Java code. Soong fills that gap." msgstr "" #: src/android/build-rules.md msgid "" -"Soong has many similarities to Bazel, which is the open-source variant of " -"Blaze (used in google3)." -msgstr "" - -#: src/android/build-rules.md -msgid "" -"There is a plan to transition [Android](https://source.android.com/docs/" -"setup/build/bazel/introduction), [ChromeOS](https://chromium.googlesource." -"com/chromiumos/bazel/), and [Fuchsia](https://source.android.com/docs/setup/" -"build/bazel/introduction) to Bazel." -msgstr "" - -#: src/android/build-rules.md -msgid "Learning Bazel-like build rules is useful for all Rust OS developers." +"Soong has many similarities to [Bazel](https://bazel.build/), which is the " +"open-source variant of Blaze (used in google3)." msgstr "" #: src/android/build-rules.md @@ -11432,7 +13391,7 @@ msgstr "" #: src/android/build-rules/binary.md msgid "" -"Let us start with a simple application. At the root of an AOSP checkout, " +"Let's start with a simple application. At the root of an AOSP checkout, " "create the following files:" msgstr "" @@ -11478,6 +13437,24 @@ msgid "" "```" msgstr "" +#: src/android/build-rules/binary.md src/android/build-rules/library.md +msgid "" +"Go through the build steps and demonstrate them running in your emulator." +msgstr "" + +#: src/android/build-rules/binary.md +msgid "" +"Notice the extensive documentation comments? The Android build rules enforce " +"that all modules have documentation. Try removing it and see what error you " +"get." +msgstr "" + +#: src/android/build-rules/binary.md +msgid "" +"Stress that the Rust build rules look like the other Soong rules. This is by " +"design, to make using Rust as easy as C++ or Java." +msgstr "" + #: src/android/build-rules/library.md msgid "Rust Libraries" msgstr "" @@ -11496,9 +13473,9 @@ msgstr "" #: src/android/build-rules/library.md msgid "" -"`libtextwrap`, which is a crate already vendored in [`external/rust/crates/`]" -"(https://cs.android.com/android/platform/superproject/+/master:external/rust/" -"crates/)." +"`libtextwrap`, which is a crate already vendored in [`external/rust/android-" +"crates-io/crates/`](https://cs.android.com/android/platform/superproject/" +"main/+/main:external/rust/android-crates-io/crates/)." msgstr "" #: src/android/build-rules/library.md @@ -11522,11 +13499,16 @@ msgid "\"greetings\"" msgstr "" #: src/android/build-rules/library.md -#: src/android/aidl/example-service/service.md +#: src/android/aidl/example-service/service.md src/android/testing.md #: src/android/interoperability/java.md msgid "\"src/lib.rs\"" msgstr "" +#: src/android/build-rules/library.md +#: src/android/aidl/example-service/client.md +msgid "\"Bob\"" +msgstr "" + #: src/android/build-rules/library.md msgid "_hello_rust/src/lib.rs_:" msgstr "" @@ -11557,25 +13539,47 @@ msgid "" "```" msgstr "" -#: src/android/aidl.md +#: src/android/build-rules/library.md msgid "" -"The [Android Interface Definition Language (AIDL)](https://developer.android." -"com/guide/components/aidl) is supported in Rust:" +"A Rust crate named `greetings` must be built by a rule called " +"`libgreetings`. Note how the Rust code uses the crate name, as is normal in " +"Rust." +msgstr "" + +#: src/android/build-rules/library.md +msgid "" +"Again, the build rules enforce that we add documentation comments to all " +"public items." msgstr "" #: src/android/aidl.md -msgid "Rust code can call existing AIDL servers," +msgid "" +"Rust supports the [Android Interface Definition Language (AIDL)](https://" +"developer.android.com/guide/components/aidl):" +msgstr "" + +#: src/android/aidl.md +msgid "Rust code can call existing AIDL servers." msgstr "" #: src/android/aidl.md msgid "You can create new AIDL servers in Rust." msgstr "" +#: src/android/aidl.md +msgid "AIDL enables Android apps to interact with each other." +msgstr "" + +#: src/android/aidl.md +msgid "" +"Since Rust is a first-class citizen in this ecosystem, other processes on " +"the device can call Rust services." +msgstr "" + #: src/android/aidl/birthday-service.md msgid "" -"To illustrate how to use Rust with Binder, we're going to walk through the " -"process of creating a Binder interface. We're then going to both implement " -"the described service and write client code that talks to that service." +"To illustrate using Rust with Binder, we will create a Binder interface. " +"Then, we'll implement the service and write a client that talks to it." msgstr "" #: src/android/aidl/example-service/interface.md @@ -11588,6 +13592,8 @@ msgstr "" #: src/android/aidl/example-service/interface.md #: src/android/aidl/example-service/service-bindings.md +#: src/android/aidl/types/objects.md src/android/aidl/types/parcelables.md +#: src/android/aidl/types/file-descriptor.md msgid "" "_birthday_service/aidl/com/example/birthdayservice/IBirthdayService.aidl_:" msgstr "" @@ -11632,15 +13638,12 @@ msgid "Generated Service API" msgstr "" #: src/android/aidl/example-service/service-bindings.md -msgid "" -"Binder generates a trait corresponding to the interface definition. trait to " -"talk to the service." +msgid "Binder generates a trait for each interface definition." msgstr "" #: src/android/aidl/example-service/service-bindings.md -#, fuzzy -msgid "_Generated trait_:" -msgstr "āĻ…āύāĻŋāϰāĻžāĻĒāĻĻ āϰāĻžāĻ¸ā§āϟ" +msgid "_out/soong/.intermediates/.../com_example_birthdayservice.rs_:" +msgstr "" #: src/android/aidl/example-service/service-bindings.md msgid "" @@ -11648,16 +13651,10 @@ msgid "" "this trait to talk to the service." msgstr "" -#: src/android/aidl/example-service/service-bindings.md -msgid "" -"The generated bindings can be found at `out/soong/.intermediates//`." -msgstr "" - #: src/android/aidl/example-service/service-bindings.md msgid "" "Point out how the generated function signature, specifically the argument " -"and return types, correspond the interface definition." +"and return types, correspond to the interface definition." msgstr "" #: src/android/aidl/example-service/service-bindings.md @@ -11676,9 +13673,14 @@ msgstr "" #: src/android/aidl/example-service/service.md #: src/android/aidl/example-service/changing-implementation.md +#: src/android/aidl/types/file-descriptor.md msgid "_birthday_service/src/lib.rs_:" msgstr "" +#: src/android/aidl/example-service/service.md +msgid "//! Implementation of the `IBirthdayService` AIDL interface.\n" +msgstr "" + #: src/android/aidl/example-service/service.md msgid "/// The `IBirthdayService` implementation.\n" msgstr "" @@ -11712,22 +13714,41 @@ msgstr "" msgid "\"com.example.birthdayservice-rust\"" msgstr "" -#: src/android/aidl/example-service/service.md -#: src/android/aidl/example-service/server.md -#: src/android/aidl/example-service/client.md -msgid "\"libbinder_rs\"" -msgstr "" - #: src/android/aidl/example-service/service.md msgid "" "Point out the path to the generated `IBirthdayService` trait, and explain " "why each of the segments is necessary." msgstr "" +#: src/android/aidl/example-service/service.md +msgid "" +"Note that `wishHappyBirthday` and other AIDL IPC methods take `&self` " +"(instead of `&mut self`)." +msgstr "" + +#: src/android/aidl/example-service/service.md +msgid "" +"This is necessary because Binder responds to incoming requests on a thread " +"pool, allowing for multiple requests to be processed in parallel. This " +"requires that the service methods only get a shared reference to `self`." +msgstr "" + +#: src/android/aidl/example-service/service.md +msgid "" +"Any state that needs to be modified by the service will have to be put in " +"something like a `Mutex` to allow for safe mutation." +msgstr "" + +#: src/android/aidl/example-service/service.md +msgid "" +"The correct approach for managing service state depends heavily on the " +"details of your service." +msgstr "" + #: src/android/aidl/example-service/service.md msgid "" "TODO: What does the `binder::Interface` trait do? Are there methods to " -"override? Where source?" +"override? Where is the source?" msgstr "" #: src/android/aidl/example-service/server.md @@ -11769,9 +13790,9 @@ msgstr "" #: src/android/aidl/example-service/server.md msgid "" -"The process for taking a user-defined service implementation (in this case " +"The process for taking a user-defined service implementation (in this case, " "the `BirthdayService` type, which implements the `IBirthdayService`) and " -"starting it as a Binder service has multiple steps, and may appear more " +"starting it as a Binder service has multiple steps. This may appear more " "complicated than students are used to if they've used Binder from C++ or " "another language. Explain to students why each step is necessary." msgstr "" @@ -11782,11 +13803,11 @@ msgstr "" #: src/android/aidl/example-service/server.md msgid "" -"Wrap the service object in corresponding `Bn*` type (`BnBirthdayService` in " -"this case). This type is generated by Binder and provides the common Binder " -"functionality that would be provided by the `BnBinder` base class in C++. We " -"don't have inheritance in Rust, so instead we use composition, putting our " -"`BirthdayService` within the generated `BnBinderService`." +"Wrap the service object in the corresponding `Bn*` type (`BnBirthdayService` " +"in this case). This type is generated by Binder and provides common Binder " +"functionality, similar to the `BnBinder` base class in C++. Since Rust " +"doesn't have inheritance, we use composition, putting our `BirthdayService` " +"within the generated `BnBinderService`." msgstr "" #: src/android/aidl/example-service/server.md @@ -11834,6 +13855,8 @@ msgstr "" #: src/android/aidl/example-service/client.md #: src/android/aidl/example-service/changing-implementation.md +#: src/android/aidl/types/objects.md src/android/aidl/types/parcelables.md +#: src/android/aidl/types/file-descriptor.md msgid "_birthday_service/src/client.rs_:" msgstr "" @@ -11911,8 +13934,8 @@ msgstr "" #: src/android/aidl/example-service/changing-definition.md msgid "" -"Let us extend the API with more functionality: we want to let clients " -"specify a list of lines for the birthday card:" +"Let's extend the API: we'll let clients specify a list of lines for the " +"birthday card:" msgstr "" #: src/android/aidl/example-service/changing-definition.md @@ -11994,24 +14017,21 @@ msgid "Primitive types map (mostly) idiomatically:" msgstr "" #: src/android/aidl/types/primitives.md -#, fuzzy msgid "AIDL Type" -msgstr "AIDL" +msgstr "" #: src/android/aidl/types/primitives.md src/android/aidl/types/arrays.md #: src/android/interoperability/cpp/type-mapping.md -#, fuzzy msgid "Rust Type" -msgstr "āωāĻĻāĻžāĻšāϰāϪ⧇āϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ āϰāĻžāĻ¸ā§āϟ" +msgstr "" #: src/android/aidl/types/primitives.md msgid "Note" msgstr "" #: src/android/aidl/types/primitives.md -#, fuzzy msgid "`boolean`" -msgstr "`bool`" +msgstr "" #: src/android/aidl/types/primitives.md msgid "`byte`" @@ -12067,24 +14087,22 @@ msgstr "" #: src/android/aidl/types/arrays.md msgid "" -"The array types (`T[]`, `byte[]`, and `List`) get translated to the " +"The array types (`T[]`, `byte[]`, and `List`) are translated to the " "appropriate Rust array type depending on how they are used in the function " "signature:" msgstr "" #: src/android/aidl/types/arrays.md -#, fuzzy msgid "Position" -msgstr "āϏāĻŽāĻžāϧāĻžāύāϏāĻŽā§‚āĻš" +msgstr "" #: src/android/aidl/types/arrays.md msgid "`in` argument" msgstr "" #: src/android/aidl/types/arrays.md -#, fuzzy msgid "`&[T]`" -msgstr "Slices" +msgstr "" #: src/android/aidl/types/arrays.md msgid "`out`/`inout` argument" @@ -12107,8 +14125,8 @@ msgstr "" msgid "" "In Android 13 or higher, fixed-size arrays are supported, i.e. `T[N]` " "becomes `[T; N]`. Fixed-size arrays can have multiple dimensions (e.g. " -"int\\[3\\]\\[4\\]). In the Java backend, fixed-size arrays are represented " -"as array types." +"`int[3][4]`). In the Java backend, fixed-size arrays are represented as " +"array types." msgstr "" #: src/android/aidl/types/arrays.md @@ -12123,14 +14141,8 @@ msgstr "" #: src/android/aidl/types/objects.md msgid "" -"**birthday_service/aidl/com/example/birthdayservice/IBirthdayInfoProvider." -"aidl**:" -msgstr "" - -#: src/android/aidl/types/objects.md src/android/aidl/types/parcelables.md -#: src/android/aidl/types/file-descriptor.md -msgid "" -"**birthday_service/aidl/com/example/birthdayservice/IBirthdayService.aidl**:" +"_birthday_service/aidl/com/example/birthdayservice/IBirthdayInfoProvider." +"aidl_:" msgstr "" #: src/android/aidl/types/objects.md @@ -12141,11 +14153,6 @@ msgstr "" msgid "/** The same thing, but using `IBinder`. */" msgstr "" -#: src/android/aidl/types/objects.md src/android/aidl/types/parcelables.md -#: src/android/aidl/types/file-descriptor.md -msgid "**birthday_service/src/client.rs**:" -msgstr "" - #: src/android/aidl/types/objects.md msgid "/// Rust struct implementing the `IBirthdayInfoProvider` interface.\n" msgstr "" @@ -12174,8 +14181,7 @@ msgid "Binder for Rust supports sending parcelables directly:" msgstr "" #: src/android/aidl/types/parcelables.md -msgid "" -"**birthday_service/aidl/com/example/birthdayservice/BirthdayInfo.aidl**:" +msgid "_birthday_service/aidl/com/example/birthdayservice/BirthdayInfo.aidl_:" msgstr "" #: src/android/aidl/types/parcelables.md @@ -12212,10 +14218,6 @@ msgstr "" msgid "// Create a `ParcelFileDescriptor` from the file and send it.\n" msgstr "" -#: src/android/aidl/types/file-descriptor.md -msgid "**birthday_service/src/lib.rs**:" -msgstr "" - #: src/android/aidl/types/file-descriptor.md msgid "" "// Convert the file descriptor to a `File`. `ParcelFileDescriptor` wraps\n" @@ -12241,6 +14243,262 @@ msgid "" "UNIX sockets." msgstr "" +#: src/android/testing.md +msgid "Testing in Android" +msgstr "" + +#: src/android/testing.md +msgid "" +"Building on [Testing](../testing.md), we will now look at how unit tests " +"work in AOSP. Use the `rust_test` module for your unit tests:" +msgstr "" + +#: src/android/testing.md +msgid "_testing/Android.bp_:" +msgstr "" + +#: src/android/testing.md +msgid "\"libleftpad\"" +msgstr "" + +#: src/android/testing.md +msgid "\"leftpad\"" +msgstr "" + +#: src/android/testing.md +msgid "\"libleftpad_test\"" +msgstr "" + +#: src/android/testing.md +msgid "\"leftpad_test\"" +msgstr "" + +#: src/android/testing.md src/android/interoperability/with-c/run-our-binary.md +msgid "\"general-tests\"" +msgstr "" + +#: src/android/testing.md +msgid "\"libgoogletest_example\"" +msgstr "" + +#: src/android/testing.md +msgid "\"googletest_example\"" +msgstr "" + +#: src/android/testing.md +msgid "\"googletest.rs\"" +msgstr "" + +#: src/android/testing.md +msgid "\"libgoogletest_rust\"" +msgstr "" + +#: src/android/testing.md +msgid "\"libmockall_example\"" +msgstr "" + +#: src/android/testing.md +msgid "\"mockall_example\"" +msgstr "" + +#: src/android/testing.md +msgid "\"mockall.rs\"" +msgstr "" + +#: src/android/testing.md +msgid "\"libmockall\"" +msgstr "" + +#: src/android/testing.md +msgid "_testing/src/lib.rs_:" +msgstr "" + +#: src/android/testing.md +msgid "//! Left-padding library.\n" +msgstr "" + +#: src/android/testing.md +msgid "/// Left-pad `s` to `width`.\n" +msgstr "" + +#: src/android/testing.md +msgid "\"{s:>width$}\"" +msgstr "" + +#: src/android/testing.md +msgid "\" foo\"" +msgstr "" + +#: src/android/testing.md +msgid "\"foobar\"" +msgstr "" + +#: src/android/testing.md +msgid "You can now run the test with" +msgstr "" + +#: src/android/testing.md +msgid "The output looks like this:" +msgstr "" + +#: src/android/testing.md +msgid "" +"```text\n" +"INFO: Elapsed time: 2.666s, Critical Path: 2.40s\n" +"INFO: 3 processes: 2 internal, 1 linux-sandbox.\n" +"INFO: Build completed successfully, 3 total actions\n" +"//comprehensive-rust-android/testing:libleftpad_test_host PASSED " +"in 2.3s\n" +" PASSED libleftpad_test.tests::long_string (0.0s)\n" +" PASSED libleftpad_test.tests::short_string (0.0s)\n" +"Test cases: finished with 2 passing and 0 failing out of 2 test cases\n" +"```" +msgstr "" + +#: src/android/testing.md +msgid "" +"Notice how you only mention the root of the library crate. Tests are found " +"recursively in nested modules." +msgstr "" + +#: src/android/testing/googletest.md +msgid "" +"The [GoogleTest](https://docs.rs/googletest/) crate allows for flexible test " +"assertions using _matchers_:" +msgstr "" + +#: src/android/testing/googletest.md +msgid "\"bar\"" +msgstr "" + +#: src/android/testing/googletest.md +msgid "\"baz\"" +msgstr "" + +#: src/android/testing/googletest.md +msgid "\"xyz\"" +msgstr "" + +#: src/android/testing/googletest.md +msgid "" +"If we change the last element to `\"!\"`, the test fails with a structured " +"error message pin-pointing the error:" +msgstr "" + +#: src/android/testing/googletest.md +msgid "" +"GoogleTest is not part of the Rust Playground, so you need to run this " +"example in a local environment. Use `cargo add googletest` to quickly add it " +"to an existing Cargo project." +msgstr "" + +#: src/android/testing/googletest.md +msgid "" +"The `use googletest::prelude::*;` line imports a number of [commonly used " +"macros and types](https://docs.rs/googletest/latest/googletest/prelude/index." +"html)." +msgstr "" + +#: src/android/testing/googletest.md +msgid "" +"This just scratches the surface, there are many builtin matchers. Consider " +"going through the first chapter of [\"Advanced testing for Rust " +"applications\"](https://rust-exercises.com/advanced-testing/), a self-guided " +"Rust course: it provides a guided introduction to the library, with " +"exercises to help you get comfortable with `googletest` macros, its matchers " +"and its overall philosophy." +msgstr "" + +#: src/android/testing/googletest.md +msgid "" +"A particularly nice feature is that mismatches in multi-line strings are " +"shown as a diff:" +msgstr "" + +#: src/android/testing/googletest.md +msgid "" +"\"Memory safety found,\\n\\\n" +" Rust's strong typing guides the way,\\n\\\n" +" Secure code you'll write.\"" +msgstr "" + +#: src/android/testing/googletest.md +msgid "" +"\"Memory safety found,\\n\\\n" +" Rust's silly humor guides the way,\\n\\\n" +" Secure code you'll write.\"" +msgstr "" + +#: src/android/testing/googletest.md +msgid "shows a color-coded diff (colors not shown here):" +msgstr "" + +#: src/android/testing/googletest.md +msgid "" +"The crate is a Rust port of [GoogleTest for C++](https://google.github.io/" +"googletest/)." +msgstr "" + +#: src/android/testing/mocking.md +msgid "" +"For mocking, [Mockall](https://docs.rs/mockall/) is a widely used library. " +"You need to refactor your code to use traits, which you can then quickly " +"mock:" +msgstr "" + +#: src/android/testing/mocking.md +msgid "" +"Mockall is the recommended mocking library in Android (AOSP). There are " +"other [mocking libraries available on crates.io](https://crates.io/keywords/" +"mock), in particular in the area of mocking HTTP services. The other mocking " +"libraries work in a similar fashion as Mockall, meaning that they make it " +"easy to get a mock implementation of a given trait." +msgstr "" + +#: src/android/testing/mocking.md +msgid "" +"Note that mocking is somewhat _controversial_: mocks allow you to completely " +"isolate a test from its dependencies. The immediate result is faster and " +"more stable test execution. On the other hand, the mocks can be configured " +"wrongly and return output different from what the real dependencies would do." +msgstr "" + +#: src/android/testing/mocking.md +msgid "" +"If at all possible, it is recommended that you use the real dependencies. As " +"an example, many databases allow you to configure an in-memory backend. This " +"means that you get the correct behavior in your tests, plus they are fast " +"and will automatically clean up after themselves." +msgstr "" + +#: src/android/testing/mocking.md +msgid "" +"Similarly, many web frameworks allow you to start an in-process server which " +"binds to a random port on `localhost`. Always prefer this over mocking away " +"the framework since it helps you test your code in the real environment." +msgstr "" + +#: src/android/testing/mocking.md +msgid "" +"Mockall is not part of the Rust Playground, so you need to run this example " +"in a local environment. Use `cargo add mockall` to quickly add Mockall to an " +"existing Cargo project." +msgstr "" + +#: src/android/testing/mocking.md +msgid "" +"Mockall has extensive functionality. In particular, you can set up " +"expectations which depend on the arguments passed. Here we use this to mock " +"a cat which becomes hungry 3 hours after the last time it was fed:" +msgstr "" + +#: src/android/testing/mocking.md +msgid "" +"You can use `.times(n)` to limit the number of times a mock method can be " +"called to `n` --- the mock will automatically panic when dropped if this " +"isn't satisfied." +msgstr "" + #: src/android/logging.md msgid "" "You should use the `log` crate to automatically log to `logcat` (on-device) " @@ -12291,7 +14549,7 @@ msgstr "" msgid "\"Something went wrong!\"" msgstr "" -#: src/android/logging.md src/android/interoperability/with-c/bindgen.md +#: src/android/logging.md src/android/interoperability/with-c/run-our-binary.md #: src/android/interoperability/with-c/rust.md msgid "Build, push, and run the binary on your device:" msgstr "" @@ -12310,6 +14568,12 @@ msgstr "" msgid "The logs show up in `adb logcat`:" msgstr "" +#: src/android/logging.md +msgid "" +"The logger implementation in `liblogger` is only needed in the final binary, " +"if you're logging from a library you only need the `log` facade crate." +msgstr "" + #: src/android/interoperability.md msgid "" "Rust has excellent support for interoperability with other languages. This " @@ -12326,8 +14590,21 @@ msgstr "" #: src/android/interoperability.md msgid "" -"When you call functions in a foreign language we say that you're using a " -"_foreign function interface_, also known as FFI." +"When you call functions in a foreign language, you're using a _foreign " +"function interface_, also known as FFI." +msgstr "" + +#: src/android/interoperability.md +msgid "" +"This is a key ability of Rust: compiled code becomes indistinguishable from " +"compiled C or C++ code." +msgstr "" + +#: src/android/interoperability.md +msgid "" +"Technically, we say that Rust can be compiled to the same [ABI](https://en." +"wikipedia.org/wiki/Application_binary_interface) (application binary " +"interface) as C code." msgstr "" #: src/android/interoperability/with-c.md @@ -12344,14 +14621,14 @@ msgstr "" msgid "You can do it by hand if you want:" msgstr "" -#: src/android/interoperability/with-c.md +#: src/android/interoperability/with-c.md src/unsafe-deep-dive/ffi/abs.md msgid "\"{x}, {abs_x}\"" msgstr "" #: src/android/interoperability/with-c.md msgid "" -"We already saw this in the [Safe FFI Wrapper exercise](../../exercises/day-3/" -"safe-ffi-wrapper.md)." +"We already saw this in the [Safe FFI Wrapper exercise](../../unsafe-rust/" +"exercise.md)." msgstr "" #: src/android/interoperability/with-c.md @@ -12364,6 +14641,73 @@ msgstr "" msgid "We will look at better options next." msgstr "" +#: src/android/interoperability/with-c.md +msgid "" +"The [`\"C\"` part](https://doc.rust-lang.org/reference/items/external-blocks." +"html#abi) of the `extern` block tells Rust that `abs` can be called using " +"the C [ABI](https://en.wikipedia.org/wiki/Application_binary_interface) " +"(application binary interface)." +msgstr "" + +#: src/android/interoperability/with-c.md +msgid "" +"The `safe fn abs` part tells Rust that `abs` is a safe function. By default, " +"extern functions are unsafe, but since `abs(x)` can't trigger undefined " +"behavior with any `x`, we can declare it safe." +msgstr "" + +#: src/android/interoperability/with-c/c-library.md +msgid "Let's first create a small C library:" +msgstr "" + +#: src/android/interoperability/with-c/c-library.md +msgid "_interoperability/bindgen/libbirthday.h_:" +msgstr "" + +#: src/android/interoperability/with-c/c-library.md +msgid "_interoperability/bindgen/libbirthday.c_:" +msgstr "" + +#: src/android/interoperability/with-c/c-library.md +msgid "" +msgstr "" + +#: src/android/interoperability/with-c/c-library.md +#: src/android/interoperability/with-c/bindgen.md +msgid "\"libbirthday.h\"" +msgstr "" + +#: src/android/interoperability/with-c/c-library.md +msgid "\"+--------------\\n\"" +msgstr "" + +#: src/android/interoperability/with-c/c-library.md +msgid "\"| Happy Birthday %s!\\n\"" +msgstr "" + +#: src/android/interoperability/with-c/c-library.md +msgid "\"| Congratulations with the %i years!\\n\"" +msgstr "" + +#: src/android/interoperability/with-c/c-library.md +msgid "Add this to your `Android.bp` file:" +msgstr "" + +#: src/android/interoperability/with-c/c-library.md +#: src/android/interoperability/with-c/bindgen.md +#: src/android/interoperability/with-c/run-our-binary.md +msgid "_interoperability/bindgen/Android.bp_:" +msgstr "" + +#: src/android/interoperability/with-c/c-library.md +#: src/android/interoperability/with-c/bindgen.md +msgid "\"libbirthday\"" +msgstr "" + +#: src/android/interoperability/with-c/c-library.md +msgid "\"libbirthday.c\"" +msgstr "" + #: src/android/interoperability/with-c/bindgen.md msgid "Using Bindgen" msgstr "" @@ -12374,54 +14718,6 @@ msgid "" "tool can auto-generate bindings from a C header file." msgstr "" -#: src/android/interoperability/with-c/bindgen.md -msgid "First create a small C library:" -msgstr "" - -#: src/android/interoperability/with-c/bindgen.md -msgid "_interoperability/bindgen/libbirthday.h_:" -msgstr "" - -#: src/android/interoperability/with-c/bindgen.md -msgid "_interoperability/bindgen/libbirthday.c_:" -msgstr "" - -#: src/android/interoperability/with-c/bindgen.md -msgid "" -msgstr "" - -#: src/android/interoperability/with-c/bindgen.md -msgid "\"libbirthday.h\"" -msgstr "" - -#: src/android/interoperability/with-c/bindgen.md -msgid "\"+--------------\\n\"" -msgstr "" - -#: src/android/interoperability/with-c/bindgen.md -msgid "\"| Happy Birthday %s!\\n\"" -msgstr "" - -#: src/android/interoperability/with-c/bindgen.md -msgid "\"| Congratulations with the %i years!\\n\"" -msgstr "" - -#: src/android/interoperability/with-c/bindgen.md -msgid "Add this to your `Android.bp` file:" -msgstr "" - -#: src/android/interoperability/with-c/bindgen.md -msgid "_interoperability/bindgen/Android.bp_:" -msgstr "" - -#: src/android/interoperability/with-c/bindgen.md -msgid "\"libbirthday\"" -msgstr "" - -#: src/android/interoperability/with-c/bindgen.md -msgid "\"libbirthday.c\"" -msgstr "" - #: src/android/interoperability/with-c/bindgen.md msgid "" "Create a wrapper header file for the library (not strictly needed in this " @@ -12432,10 +14728,6 @@ msgstr "" msgid "_interoperability/bindgen/libbirthday_wrapper.h_:" msgstr "" -#: src/android/interoperability/with-c/bindgen.md -msgid "You can now auto-generate the bindings:" -msgstr "" - #: src/android/interoperability/with-c/bindgen.md msgid "\"libbirthday_bindgen\"" msgstr "" @@ -12473,11 +14765,30 @@ msgid "//! Bindgen demo.\n" msgstr "" #: src/android/interoperability/with-c/bindgen.md -msgid "// SAFETY: `print_card` is safe to call with a valid `card` pointer.\n" +msgid "" +"// SAFETY: The pointer we pass is valid because it came from a Rust\n" +" // reference, and the `name` it contains refers to `name` above which " +"also\n" +" // remains valid. `print_card` doesn't store either pointer to use " +"later\n" +" // after it returns.\n" msgstr "" #: src/android/interoperability/with-c/bindgen.md msgid "" +"The Android build rules will automatically call `bindgen` for you behind the " +"scenes." +msgstr "" + +#: src/android/interoperability/with-c/bindgen.md +msgid "" +"Notice that the Rust code in `main` is still hard to write. It is good " +"practice to encapsulate the output of `bindgen` in a Rust library which " +"exposes a safe interface to caller." +msgstr "" + +#: src/android/interoperability/with-c/run-our-binary.md +msgid "" "```shell\n" "m print_birthday_card\n" "adb push \"$ANDROID_PRODUCT_OUT/system/bin/print_birthday_card\" /data/local/" @@ -12486,82 +14797,90 @@ msgid "" "```" msgstr "" -#: src/android/interoperability/with-c/bindgen.md +#: src/android/interoperability/with-c/run-our-binary.md msgid "Finally, we can run auto-generated tests to ensure the bindings work:" msgstr "" -#: src/android/interoperability/with-c/bindgen.md +#: src/android/interoperability/with-c/run-our-binary.md msgid "\"libbirthday_bindgen_test\"" msgstr "" -#: src/android/interoperability/with-c/bindgen.md +#: src/android/interoperability/with-c/run-our-binary.md msgid "\":libbirthday_bindgen\"" msgstr "" -#: src/android/interoperability/with-c/bindgen.md -msgid "\"general-tests\"" -msgstr "" - -#: src/android/interoperability/with-c/bindgen.md +#: src/android/interoperability/with-c/run-our-binary.md msgid "\"none\"" msgstr "" -#: src/android/interoperability/with-c/bindgen.md +#: src/android/interoperability/with-c/run-our-binary.md msgid "// Generated file, skip linting\n" msgstr "" +#: src/android/interoperability/with-c/rust-library.md +msgid "" +"Exporting Rust functions and types to C is easy. Here's a simple Rust " +"library:" +msgstr "" + +#: src/android/interoperability/with-c/rust-library.md +msgid "_interoperability/rust/libanalyze/analyze.rs_" +msgstr "" + +#: src/android/interoperability/with-c/rust-library.md +msgid "//! Rust FFI demo.\n" +msgstr "" + +#: src/android/interoperability/with-c/rust-library.md +msgid "" +"/// Analyze the numbers.\n" +"// SAFETY: There is no other global function of this name.\n" +msgstr "" + +#: src/android/interoperability/with-c/rust-library.md +msgid "\"x ({x}) is smallest!\"" +msgstr "" + +#: src/android/interoperability/with-c/rust-library.md +msgid "\"y ({y}) is probably larger than x ({x})\"" +msgstr "" + +#: src/android/interoperability/with-c/rust-library.md +msgid "_interoperability/rust/libanalyze/Android.bp_" +msgstr "" + +#: src/android/interoperability/with-c/rust-library.md +#: src/android/interoperability/with-c/rust.md +msgid "\"libanalyze_ffi\"" +msgstr "" + +#: src/android/interoperability/with-c/rust-library.md +msgid "\"analyze_ffi\"" +msgstr "" + +#: src/android/interoperability/with-c/rust-library.md +msgid "\"analyze.rs\"" +msgstr "" + +#: src/android/interoperability/with-c/rust-library.md +msgid "" +"`#[unsafe(no_mangle)]` disables Rust's usual name mangling, so the exported " +"symbol will just be the name of the function. You can also use " +"`#[unsafe(export_name = \"some_name\")]` to specify whatever name you want." +msgstr "" + #: src/android/interoperability/with-c/rust.md msgid "Calling Rust" msgstr "" #: src/android/interoperability/with-c/rust.md -msgid "Exporting Rust functions and types to C is easy:" -msgstr "" - -#: src/android/interoperability/with-c/rust.md -msgid "_interoperability/rust/libanalyze/analyze.rs_" -msgstr "" - -#: src/android/interoperability/with-c/rust.md -msgid "//! Rust FFI demo.\n" -msgstr "" - -#: src/android/interoperability/with-c/rust.md -msgid "/// Analyze the numbers.\n" -msgstr "" - -#: src/android/interoperability/with-c/rust.md -msgid "\"x ({x}) is smallest!\"" -msgstr "" - -#: src/android/interoperability/with-c/rust.md -msgid "\"y ({y}) is probably larger than x ({x})\"" +msgid "We can now call this from a C binary:" msgstr "" #: src/android/interoperability/with-c/rust.md msgid "_interoperability/rust/libanalyze/analyze.h_" msgstr "" -#: src/android/interoperability/with-c/rust.md -msgid "_interoperability/rust/libanalyze/Android.bp_" -msgstr "" - -#: src/android/interoperability/with-c/rust.md -msgid "\"libanalyze_ffi\"" -msgstr "" - -#: src/android/interoperability/with-c/rust.md -msgid "\"analyze_ffi\"" -msgstr "" - -#: src/android/interoperability/with-c/rust.md -msgid "\"analyze.rs\"" -msgstr "" - -#: src/android/interoperability/with-c/rust.md -msgid "We can now call this from a C binary:" -msgstr "" - #: src/android/interoperability/with-c/rust.md msgid "_interoperability/rust/analyze/main.c_" msgstr "" @@ -12592,17 +14911,10 @@ msgid "" "```" msgstr "" -#: src/android/interoperability/with-c/rust.md -msgid "" -"`#[no_mangle]` disables Rust's usual name mangling, so the exported symbol " -"will just be the name of the function. You can also use `#[export_name = " -"\"some_name\"]` to specify whatever name you want." -msgstr "" - #: src/android/interoperability/cpp.md msgid "" -"The [CXX crate](https://cxx.rs/) makes it possible to do safe " -"interoperability between Rust and C++." +"The [CXX crate](https://cxx.rs/) enables safe interoperability between Rust " +"and C++." msgstr "" #: src/android/interoperability/cpp.md @@ -12636,9 +14948,8 @@ msgstr "" #: src/chromium/interoperability-with-cpp/example-bindings.md #: src/chromium/interoperability-with-cpp/error-handling-qr.md #: src/chromium/interoperability-with-cpp/error-handling-png.md -#, fuzzy msgid "\"Rust\"" -msgstr "Rustdoc" +msgstr "" #: src/android/interoperability/cpp/bridge.md #: src/android/interoperability/cpp/cpp-bridge.md @@ -12693,9 +15004,8 @@ msgid "// Method on `MyType`\n" msgstr "" #: src/android/interoperability/cpp/rust-bridge.md -#, fuzzy msgid "// Free function\n" -msgstr "āĻĢāĻžāĻ‚āĻļāύ" +msgstr "" #: src/android/interoperability/cpp/rust-bridge.md msgid "" @@ -12761,9 +15071,8 @@ msgid "" msgstr "" #: src/android/interoperability/cpp/shared-enums.md -#, fuzzy msgid "Generated Rust:" -msgstr "āĻ…āύāĻŋāϰāĻžāĻĒāĻĻ āϰāĻžāĻ¸ā§āϟ" +msgstr "" #: src/android/interoperability/cpp/shared-enums.md msgid "Generated C++:" @@ -12827,27 +15136,24 @@ msgid "" msgstr "" #: src/android/interoperability/cpp/type-mapping.md -#, fuzzy msgid "C++ Type" -msgstr "Types" +msgstr "" #: src/android/interoperability/cpp/type-mapping.md -#, fuzzy msgid "`rust::String`" -msgstr "String" +msgstr "" #: src/android/interoperability/cpp/type-mapping.md msgid "`&str`" -msgstr "`&str`" +msgstr "" #: src/android/interoperability/cpp/type-mapping.md msgid "`rust::Str`" msgstr "" #: src/android/interoperability/cpp/type-mapping.md -#, fuzzy msgid "`CxxString`" -msgstr "String" +msgstr "" #: src/android/interoperability/cpp/type-mapping.md msgid "`std::string`" @@ -12914,12 +15220,75 @@ msgid "" "semantics, so a `std::string` can't be passed by value to Rust." msgstr "" +#: src/android/interoperability/cpp/android-cpp-genrules.md #: src/android/interoperability/cpp/android-build-cpp.md +#: src/android/interoperability/cpp/android-build-rust.md +msgid "Building in Android" +msgstr "" + +#: src/android/interoperability/cpp/android-cpp-genrules.md +msgid "" +"Create two genrules: One to generate the CXX header, and one to generate the " +"CXX source file. These are then used as inputs to the `cc_library_static`." +msgstr "" + +#: src/android/interoperability/cpp/android-cpp-genrules.md +msgid "" +"// Generate a C++ header containing the C++ bindings\n" +"// to the Rust exported functions in lib.rs.\n" +msgstr "" + +#: src/android/interoperability/cpp/android-cpp-genrules.md +#: src/android/interoperability/cpp/android-build-cpp.md +msgid "\"libcxx_test_bridge_header\"" +msgstr "" + +#: src/android/interoperability/cpp/android-cpp-genrules.md +msgid "\"cxxbridge\"" +msgstr "" + +#: src/android/interoperability/cpp/android-cpp-genrules.md +msgid "\"$(location cxxbridge) $(in) --header > $(out)\"" +msgstr "" + #: src/android/interoperability/cpp/android-cpp-genrules.md #: src/android/interoperability/cpp/android-build-rust.md -#, fuzzy -msgid "Building in Android" -msgstr "āĻ…ā§āϝāĻžāĻ¨ā§āĻĄā§āϰāϝāĻŧ⧇āĻĄā§‡ āϰāĻžāĻ¸ā§āϟ" +msgid "\"lib.rs\"" +msgstr "" + +#: src/android/interoperability/cpp/android-cpp-genrules.md +msgid "\"lib.rs.h\"" +msgstr "" + +#: src/android/interoperability/cpp/android-cpp-genrules.md +msgid "// Generate the C++ code that Rust calls into.\n" +msgstr "" + +#: src/android/interoperability/cpp/android-cpp-genrules.md +#: src/android/interoperability/cpp/android-build-cpp.md +msgid "\"libcxx_test_bridge_code\"" +msgstr "" + +#: src/android/interoperability/cpp/android-cpp-genrules.md +msgid "\"$(location cxxbridge) $(in) > $(out)\"" +msgstr "" + +#: src/android/interoperability/cpp/android-cpp-genrules.md +msgid "\"lib.rs.cc\"" +msgstr "" + +#: src/android/interoperability/cpp/android-cpp-genrules.md +msgid "" +"The `cxxbridge` tool is a standalone tool that generates the C++ side of the " +"bridge module. It is included in Android and available as a Soong tool." +msgstr "" + +#: src/android/interoperability/cpp/android-cpp-genrules.md +msgid "" +"By convention, if your Rust source file is `lib.rs` your header file will be " +"named `lib.rs.h` and your source file will be named `lib.rs.cc`. This naming " +"convention isn't enforced, though." +msgstr "" #: src/android/interoperability/cpp/android-build-cpp.md msgid "" @@ -12940,16 +15309,6 @@ msgstr "" msgid "\"cxx-bridge-header\"" msgstr "" -#: src/android/interoperability/cpp/android-build-cpp.md -#: src/android/interoperability/cpp/android-cpp-genrules.md -msgid "\"libcxx_test_bridge_header\"" -msgstr "" - -#: src/android/interoperability/cpp/android-build-cpp.md -#: src/android/interoperability/cpp/android-cpp-genrules.md -msgid "\"libcxx_test_bridge_code\"" -msgstr "" - #: src/android/interoperability/cpp/android-build-cpp.md msgid "" "Point out that `libcxx_test_bridge_header` and `libcxx_test_bridge_code` are " @@ -12972,62 +15331,6 @@ msgid "" "instructions again in the future." msgstr "" -#: src/android/interoperability/cpp/android-cpp-genrules.md -msgid "" -"Create two genrules: One to generate the CXX header, and one to generate the " -"CXX source file. These are then used as inputs to the `cc_library_static`." -msgstr "" - -#: src/android/interoperability/cpp/android-cpp-genrules.md -msgid "// Generate a C++ header containing the C++ bindings" -msgstr "" - -#: src/android/interoperability/cpp/android-cpp-genrules.md -msgid "// to the Rust exported functions in lib.rs." -msgstr "" - -#: src/android/interoperability/cpp/android-cpp-genrules.md -msgid "\"cxxbridge\"" -msgstr "" - -#: src/android/interoperability/cpp/android-cpp-genrules.md -msgid "\"$(location cxxbridge) $(in) --header > $(out)\"" -msgstr "" - -#: src/android/interoperability/cpp/android-cpp-genrules.md -#: src/android/interoperability/cpp/android-build-rust.md -msgid "\"lib.rs\"" -msgstr "" - -#: src/android/interoperability/cpp/android-cpp-genrules.md -msgid "\"lib.rs.h\"" -msgstr "" - -#: src/android/interoperability/cpp/android-cpp-genrules.md -msgid "// Generate the C++ code that Rust calls into." -msgstr "" - -#: src/android/interoperability/cpp/android-cpp-genrules.md -msgid "\"$(location cxxbridge) $(in) > $(out)\"" -msgstr "" - -#: src/android/interoperability/cpp/android-cpp-genrules.md -msgid "\"lib.rs.cc\"" -msgstr "" - -#: src/android/interoperability/cpp/android-cpp-genrules.md -msgid "" -"The `cxxbridge` tool is a standalone tool that generates the C++ side of the " -"bridge module. It is included in Android and available as a Soong tool." -msgstr "" - -#: src/android/interoperability/cpp/android-cpp-genrules.md -msgid "" -"By convention, if your Rust source file is `lib.rs` your header file will be " -"named `lib.rs.h` and your source file will be named `lib.rs.cc`. This naming " -"convention isn't enforced, though." -msgstr "" - #: src/android/interoperability/cpp/android-build-rust.md msgid "" "Create a `rust_binary` that depends on `libcxx` and your `cc_library_static`." @@ -13065,7 +15368,9 @@ msgid "//! Rust <-> Java FFI demo.\n" msgstr "" #: src/android/interoperability/java.md -msgid "/// HelloWorld::hello method implementation.\n" +msgid "" +"/// HelloWorld::hello method implementation.\n" +"// SAFETY: There is no other global function of this name.\n" msgstr "" #: src/android/interoperability/java.md @@ -13105,37 +15410,28 @@ msgid "\"helloworld_jni\"" msgstr "" #: src/android/interoperability/java.md -#, fuzzy msgid "\"HelloWorld.java\"" -msgstr "Hello World!" +msgstr "" #: src/android/interoperability/java.md -#, fuzzy msgid "\"HelloWorld\"" -msgstr "Hello World!" +msgstr "" #: src/android/interoperability/java.md msgid "Finally, you can build, sync, and run the binary:" msgstr "" -#: src/exercises/android/morning.md +#: src/android/interoperability/java.md msgid "" -"This is a group exercise: We will look at one of the projects you work with " -"and try to integrate some Rust into it. Some suggestions:" +"The `unsafe(no_mangle)` attribute instructs Rust to emit the " +"`Java_HelloWorld_hello` symbol exactly as written. This is important so that " +"Java can recognize the symbol as a `hello` method on the `HelloWorld` class." msgstr "" -#: src/exercises/android/morning.md -msgid "Call your AIDL service with a client written in Rust." -msgstr "" - -#: src/exercises/android/morning.md -msgid "Move a function from your project to Rust and call it." -msgstr "" - -#: src/exercises/android/morning.md +#: src/android/interoperability/java.md msgid "" -"No solution is provided here since this is open-ended: it relies on someone " -"in the class having a piece of code which you can turn in to Rust on the fly." +"By default, Rust will mangle (rename) symbols so that a binary can link in " +"two versions of the same Rust crate." msgstr "" #: src/chromium.md @@ -13151,7 +15447,7 @@ msgstr "" #: src/chromium.md msgid "" "Today, we'll call into Rust to do something silly with strings. If you've " -"got a corner of the code where you're displaying a UTF8 string to the user, " +"got a corner of the code where you're displaying a UTF-8 string to the user, " "feel free to follow this recipe in your part of the codebase instead of the " "exact part we talk about." msgstr "" @@ -13186,7 +15482,7 @@ msgstr "" #: src/chromium/setup.md msgid "" -"This part of the course has a series of exercises which build on each other. " +"This part of the course has a series of exercises that build on each other. " "We'll be doing them spread throughout the course instead of just at the end. " "If you don't have time to complete a certain part, don't worry: you can " "catch up in the next slot." @@ -13231,9 +15527,8 @@ msgid "" msgstr "" #: src/chromium/cargo.md -#, fuzzy msgid "Mini exercise" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ" +msgstr "" #: src/chromium/cargo.md msgid "Split into small groups and:" @@ -13268,7 +15563,7 @@ msgstr "" msgid "" "It's fantastic that when writing a tool, or prototyping a part of Chromium, " "one has access to the rich ecosystem of crates.io libraries. There is a " -"crate for almost anything and they are usually quite pleasant to use. " +"crate for almost anything and they are typically quite pleasant to use. " "(`clap` for command-line parsing, `serde` for serializing/deserializing to/" "from various formats, `itertools` for working with iterators, etc.)." msgstr "" @@ -13313,9 +15608,8 @@ msgstr "" msgid "" "Perhaps surprisingly, Rust is becoming increasingly popular in the industry " "for writing command line tools. The breadth and ergonomics of libraries is " -"comparable to Python, while being more robust (thanks to the rich " -"typesystem) and running faster (as a compiled, rather than interpreted " -"language)." +"comparable to Python, while being more robust (thanks to the rich type " +"system) and running faster (as a compiled, rather than interpreted language)." msgstr "" #: src/chromium/cargo.md @@ -13323,7 +15617,7 @@ msgid "" "Participating in the Rust ecosystem requires using standard Rust tools like " "Cargo. Libraries that want to get external contributions, and want to be " "used outside of Chromium (e.g. in Bazel or Android/Soong build environments) " -"should probably use Cargo." +"should use Cargo." msgstr "" #: src/chromium/cargo.md @@ -13409,25 +15703,38 @@ msgstr "" #: src/chromium/policy.md msgid "" -"Chromium does not yet allow first-party Rust except in rare cases as " -"approved by Chromium's [Area Tech Leads](https://source.chromium.org/" -"chromium/chromium/src/+/main:ATL_OWNERS)." +"Chromium's Rust policy can be found [here](https://source.chromium.org/" +"chromium/chromium/src/+/main:docs/rust.md;l=22). Rust can be used for both " +"first-party and third-party code." +msgstr "" + +#: src/chromium/policy.md +msgid "Using Rust for pure first-party code looks like this:" msgstr "" #: src/chromium/policy.md msgid "" -"Chromium's policy on third party libraries is outlined [here](https://" -"chromium.googlesource.com/chromium/src/+/main/docs/adding_to_third_party." -"md#rust) - Rust is allowed for third party libraries under various " -"circumstances, including if they're the best option for performance or for " -"security." +"```bob\n" +"\"C++\" Rust\n" +".- - - - - - - - - -. .- - - - - - - - - - -.\n" +": : : :\n" +": Existing Chromium : : Chromium Rust :\n" +": \"C++\" : : code :\n" +": +---------------+ : : +----------------+ :\n" +": | | : : | | :\n" +": | o-----+-+-----------+-+-> | :\n" +": | | : Language : | | :\n" +": +---------------+ : boundary : +----------------+ :\n" +": : : :\n" +"`- - - - - - - - - -' `- - - - - - - - - - -'\n" +"```" msgstr "" #: src/chromium/policy.md msgid "" -"Very few Rust libraries directly expose a C/C++ API, so that means that " -"nearly all such libraries will require a small amount of first-party glue " -"code." +"The third-party case is also common. You will typically also need a small " +"amount of first-party glue code, because very few Rust libraries directly " +"expose a C/C++ API." msgstr "" #: src/chromium/policy.md @@ -13459,12 +15766,8 @@ msgstr "" #: src/chromium/policy.md msgid "" -"First-party Rust glue code for a particular third-party crate should " -"normally be kept in `third_party/rust///wrapper`." -msgstr "" - -#: src/chromium/policy.md -msgid "Because of this, today's course will be heavily focused on:" +"The scenario of using a third-party crate is the more complex one, so " +"today's course will focus on:" msgstr "" #: src/chromium/policy.md @@ -13472,21 +15775,18 @@ msgid "Bringing in third-party Rust libraries (\"crates\")" msgstr "" #: src/chromium/policy.md -msgid "Writing glue code to be able to use those crates from Chromium C++." -msgstr "" - -#: src/chromium/policy.md -msgid "If this policy changes over time, the course will evolve to keep up." +msgid "" +"Writing glue code to be able to use those crates from Chromium C++. (The " +"same techniques are used when working with first-party Rust code)." msgstr "" #: src/chromium/build-rules.md -#, fuzzy msgid "Build rules" -msgstr "āĻ—āĻ āύ⧇āϰ āύāĻŋāϝāĻŧāĻŽ" +msgstr "" #: src/chromium/build-rules.md msgid "" -"Rust code is usually built using `cargo`. Chromium builds with `gn` and " +"Rust code is typically built using `cargo`. Chromium builds with `gn` and " "`ninja` for efficiency --- its static rules allow maximum parallelism. Rust " "is no exception." msgstr "" @@ -13656,7 +15956,7 @@ msgstr "" #: src/chromium/build-rules/vscode.md msgid "" -"Demo **type annotations** (there are quote a few nice examples in the " +"Demo **type annotations** (there are quite a few nice examples in the " "`QrCode::with_bits` method)" msgstr "" @@ -13668,9 +15968,8 @@ msgid "" msgstr "" #: src/exercises/chromium/build-rules.md -#, fuzzy msgid "Build rules exercise" -msgstr "āĻ—āĻ āύ⧇āϰ āύāĻŋāϝāĻŧāĻŽ" +msgstr "" #: src/exercises/chromium/build-rules.md msgid "" @@ -13678,10 +15977,16 @@ msgid "" "containing:" msgstr "" +#: src/exercises/chromium/build-rules.md src/bare-metal/aps/inline-assembly.md +#: src/bare-metal/aps/uart/using.md src/bare-metal/aps/safemmio/using.md +#: src/bare-metal/aps/logging/using.md +msgid "// SAFETY: There is no other global function of this name.\n" +msgstr "" + #: src/exercises/chromium/build-rules.md msgid "" -"**Important**: note that `no_mangle` here is considered a type of unsafety " -"by the Rust compiler, so you'll need to to allow unsafe code in your `gn` " +"**Important:** note that `no_mangle` here is considered a type of unsafety " +"by the Rust compiler, so you'll need to allow unsafe code in your `gn` " "target." msgstr "" @@ -13721,8 +16026,8 @@ msgstr "" #: src/exercises/chromium/build-rules.md msgid "" -"Information about [`#[no_mangle]`](https://doc.rust-lang.org/beta/reference/" -"abi.html#the-no_mangle-attribute)" +"Information about [`#[unsafe(no_mangle)]`](https://doc.rust-lang.org/beta/" +"reference/abi.html#the-no_mangle-attribute)" msgstr "" #: src/exercises/chromium/build-rules.md @@ -13753,9 +16058,9 @@ msgstr "" #: src/exercises/chromium/build-rules.md msgid "" -"`allow_unsafe = true` is required here because `#[no_mangle]` might allow " -"Rust to generate two functions with the same name, and Rust can no longer " -"guarantee that the right one is called." +"`allow_unsafe = true` is required here because `#[unsafe(no_mangle)]` might " +"allow Rust to generate two functions with the same name, and Rust can no " +"longer guarantee that the right one is called." msgstr "" #: src/exercises/chromium/build-rules.md @@ -13827,10 +16132,10 @@ msgstr "" #: src/chromium/testing.md msgid "" -"Hypothetical/WIP PNG integration may need to implement memory-safe " -"implementation of pixel transformations that are provided by `libpng` but " -"missing in the `png` crate - e.g. RGBA => BGRA, or gamma correction. Such " -"functionality may benefit from separate tests authored in Rust." +"Hypothetical/WIP PNG integration may need memory-safe implementations of " +"pixel transformations that are provided by `libpng` but missing in the `png` " +"crate - e.g. RGBA => BGRA, or gamma correction. Such functionality may " +"benefit from separate tests authored in Rust." msgstr "" #: src/chromium/testing/rust-gtest-interop.md @@ -13852,9 +16157,8 @@ msgid "" msgstr "" #: src/chromium/testing/rust-gtest-interop.md -#, fuzzy msgid "Example:" -msgstr "āωāĻĻāĻžāĻšāϰāĻŖ" +msgstr "" #: src/chromium/testing/build-gn.md msgid "" @@ -13936,9 +16240,8 @@ msgid "" msgstr "" #: src/exercises/chromium/testing.md -#, fuzzy msgid "Testing exercise" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ⧇ āϰāĻžāĻ¸ā§āϟ" +msgstr "" #: src/exercises/chromium/testing.md msgid "Time for another exercise!" @@ -13977,7 +16280,7 @@ msgstr "" #: src/chromium/interoperability-with-cpp.md msgid "" "You describe your whole language boundary in an interface definition " -"language (which looks a lot like Rust) and then CXX tools generate " +"language (which closely resembles Rust) and then CXX tools generate " "declarations for functions and types in both Rust and C++." msgstr "" @@ -14035,7 +16338,7 @@ msgstr "" msgid "" "`rust::String` and `CxxString` types understand and maintain differences in " "string representation across the languages (e.g. `rust::String::lossy` can " -"build a Rust string from non-UTF8 input and `rust::String::c_str` can NUL-" +"build a Rust string from non-UTF-8 input and `rust::String::c_str` can NUL-" "terminate a string)." msgstr "" @@ -14050,7 +16353,7 @@ msgid "\"example/include/blobstore.h\"" msgstr "" #: src/chromium/interoperability-with-cpp/example-bindings.md -msgid "// Definitions of Rust types and functions go here" +msgid "// Definitions of Rust types and functions go here\n" msgstr "" #: src/chromium/interoperability-with-cpp/example-bindings.md @@ -14083,7 +16386,7 @@ msgstr "" #: src/chromium/interoperability-with-cpp/example-bindings.md msgid "" -"**Common misconception**: It _looks_ like a C++ header is being parsed by " +"**Common misconception:** It _looks_ like a C++ header is being parsed by " "Rust, but this is misleading. This header is never interpreted by Rust, but " "simply `#include`d in the generated C++ code for the benefit of C++ " "compilers." @@ -14191,9 +16494,8 @@ msgid "" msgstr "" #: src/chromium/interoperability-with-cpp/error-handling-qr.md -#, fuzzy msgid "CXX Error Handling: QR Example" -msgstr "āĻ¤ā§āϰ⧁āϟāĻŋ āϏāĻžāĻŽāϞāĻžāύ⧋" +msgstr "" #: src/chromium/interoperability-with-cpp/error-handling-qr.md msgid "" @@ -14232,9 +16534,8 @@ msgid "" msgstr "" #: src/chromium/interoperability-with-cpp/error-handling-png.md -#, fuzzy msgid "CXX Error Handling: PNG Example" -msgstr "āĻ¤ā§āϰ⧁āϟāĻŋ āϏāĻžāĻŽāϞāĻžāύ⧋" +msgstr "" #: src/chromium/interoperability-with-cpp/error-handling-png.md msgid "" @@ -14247,19 +16548,17 @@ msgid "\"gfx::rust_bindings\"" msgstr "" #: src/chromium/interoperability-with-cpp/error-handling-png.md -msgid "/// This returns an FFI-friendly equivalent of `Result," +msgid "" +"/// This returns an FFI-friendly equivalent of `Result,\n" +" /// ()>`.\n" msgstr "" #: src/chromium/interoperability-with-cpp/error-handling-png.md -msgid "/// ()>`." +msgid "/// C++ bindings for the `crate::png::ResultOfPngReader` type.\n" msgstr "" #: src/chromium/interoperability-with-cpp/error-handling-png.md -msgid "/// C++ bindings for the `crate::png::ResultOfPngReader` type." -msgstr "" - -#: src/chromium/interoperability-with-cpp/error-handling-png.md -msgid "/// C++ bindings for the `crate::png::PngReader` type." +msgid "/// C++ bindings for the `crate::png::PngReader` type.\n" msgstr "" #: src/chromium/interoperability-with-cpp/error-handling-png.md @@ -14346,9 +16645,8 @@ msgid "" msgstr "" #: src/exercises/chromium/interoperability-with-cpp.md -#, fuzzy msgid "Exercise: Interoperability with C++" -msgstr "āφāĻ¨ā§āϤāσāĻ•āĻžāĻ°ā§āϝāĻ•ā§āώāĻŽāϤāĻž" +msgstr "" #: src/exercises/chromium/interoperability-with-cpp.md msgid "Part one" @@ -14364,7 +16662,7 @@ msgstr "" #: src/exercises/chromium/interoperability-with-cpp.md msgid "" "Modify your previous `hello_from_rust` function to remove `extern \"C\"` and " -"`#[no_mangle]`. This is now just a standard Rust function." +"`#[unsafe(no_mangle)]`. This is now just a standard Rust function." msgstr "" #: src/exercises/chromium/interoperability-with-cpp.md @@ -14392,9 +16690,8 @@ msgid "" msgstr "" #: src/exercises/chromium/interoperability-with-cpp.md -#, fuzzy msgid "Some things to try:" -msgstr "āĻ•āĻŋāϛ⧁ āύ⧋āϟ:" +msgstr "" #: src/exercises/chromium/interoperability-with-cpp.md msgid "Call back into C++ from Rust. You will need:" @@ -14507,19 +16804,20 @@ msgid "" msgstr "" #: src/chromium/adding-third-party-crates.md -#, fuzzy +msgid "Property" +msgstr "" + +#: src/chromium/adding-third-party-crates.md msgid "C++ library" -msgstr "āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋ" +msgstr "" #: src/chromium/adding-third-party-crates.md -#, fuzzy msgid "Rust crate" -msgstr "āϰāĻžāĻ¸ā§āϟ āχāϕ⧋āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽ" +msgstr "" #: src/chromium/adding-third-party-crates.md -#, fuzzy msgid "Build system" -msgstr "āϰāĻžāĻ¸ā§āϟ āχāϕ⧋āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽ" +msgstr "" #: src/chromium/adding-third-party-crates.md msgid "Lots" @@ -14608,14 +16906,15 @@ msgstr "" msgid "" "As with any other `Cargo.toml`, you can specify [more details about the " "dependencies](https://doc.rust-lang.org/cargo/reference/specifying-" -"dependencies.html) --- most commonly, you'll want to specify the `features` " -"that you wish to enable in the crate." +"dependencies.html) --- typically, you'll want to specify the `features` that " +"you wish to enable in the crate." msgstr "" #: src/chromium/adding-third-party-crates/configuring-cargo-toml.md msgid "" -"When adding a crate to Chromium, you'll often need to provide some extra " -"information in an additional file, `gnrt_config.toml`, which we'll meet next." +"When adding a crate to Chromium, you'll frequently need to provide " +"additional information in an additional file, `gnrt_config.toml`, which " +"we'll meet next." msgstr "" #: src/chromium/adding-third-party-crates/configuring-gnrt-config-toml.md @@ -14671,9 +16970,8 @@ msgid "This `vendor` command may download:" msgstr "" #: src/chromium/adding-third-party-crates/downloading-crates.md -#, fuzzy msgid "Your crate" -msgstr "āĻĻāϰāĻ•āĻžāϰ⧀ āĻ•ā§āϰ⧇āϟ-āϏāĻŽā§‚āĻš" +msgstr "" #: src/chromium/adding-third-party-crates/downloading-crates.md msgid "Direct and transitive dependencies" @@ -14764,6 +17062,12 @@ msgstr "" msgid "Checking rustc version to configure features on and off" msgstr "" +#: src/chromium/adding-third-party-crates/resolving-problems.md +#: src/unsafe-deep-dive/introduction/responsibility-shift.md +#: src/unsafe-deep-dive/memory-lifecycle.md +msgid "Yes" +msgstr "" + #: src/chromium/adding-third-party-crates/resolving-problems.md msgid "None" msgstr "" @@ -14773,9 +17077,8 @@ msgid "Checking platform or CPU to configure features on and off" msgstr "" #: src/chromium/adding-third-party-crates/resolving-problems.md -#, fuzzy msgid "Generating code" -msgstr "āĻœā§‡āύ⧇āϰāĻŋāĻ•āϏ" +msgstr "" #: src/chromium/adding-third-party-crates/resolving-problems.md msgid "Yes - specify in `gnrt_config.toml`" @@ -14785,6 +17088,11 @@ msgstr "" msgid "Building C/C++" msgstr "" +#: src/chromium/adding-third-party-crates/resolving-problems.md +#: src/unsafe-deep-dive/memory-lifecycle.md +msgid "No" +msgstr "" + #: src/chromium/adding-third-party-crates/resolving-problems.md msgid "Patch around it" msgstr "" @@ -14902,8 +17210,9 @@ msgid "" "chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/rust." "md#Third_party-review), but of course also subject to security review. As " "you may be bringing in not just a single crate but also transitive " -"dependencies, there may be a lot of code to review. On the other hand, safe " -"Rust code can have limited negative side effects. How should you review it?" +"dependencies, there may be a substantial amount of code to review. On the " +"other hand, safe Rust code can have limited negative side effects. How " +"should you review it?" msgstr "" #: src/chromium/adding-third-party-crates/reviews-and-audits.md @@ -14952,7 +17261,7 @@ msgstr "" msgid "" "Read all the code at a sufficient level to look for anything out of place " "that might have been maliciously inserted. (You can't realistically aim for " -"100% perfection here: there's often just too much code.)" +"100% perfection here: there is often too much code.)" msgstr "" #: src/chromium/adding-third-party-crates/reviews-and-audits.md @@ -14991,7 +17300,7 @@ msgstr "" #: src/chromium/adding-third-party-crates/checking-in.md msgid "" -"**Important**: you need to use `git add -f` because otherwise `.gitignore` " +"**Important:** you need to use `git add -f` because otherwise `.gitignore` " "files may result in some files being skipped." msgstr "" @@ -15070,8 +17379,8 @@ msgstr "" #: src/exercises/chromium/third-party.md msgid "" -"If students are downloading even more than that, they probably forgot to " -"turn off the default features." +"If students are downloading even more than that, they likely forgot to turn " +"off the default features." msgstr "" #: src/exercises/chromium/third-party.md @@ -15144,9 +17453,9 @@ msgstr "" #: src/exercises/chromium/bringing-it-together.md msgid "" -"UTF16 vs UTF8. Students should be aware that Rust strings are always UTF8, " -"and will probably decide that it's better to do the conversion on the C++ " -"side using `base::UTF16ToUTF8` and back again." +"UTF-16 vs UTF-8. Students should be aware that Rust strings are always " +"UTF-8, and will typically decide that it's better to do the conversion on " +"the C++ side using `base::UTF16ToUTF8` and back again." msgstr "" #: src/exercises/chromium/bringing-it-together.md @@ -15154,8 +17463,8 @@ msgid "" "If students decide to do the conversion on the Rust side, they'll need to " "consider [`String::from_utf16`](https://doc.rust-lang.org/std/string/struct." "String.html#method.from_utf16), consider error handling, and consider which " -"[CXX supported types can transfer a lot of u16s](https://cxx.rs/binding/" -"slice.html)." +"[CXX supported types can transfer many u16s](https://cxx.rs/binding/slice." +"html)." msgstr "" #: src/exercises/chromium/bringing-it-together.md @@ -15172,8 +17481,8 @@ msgstr "" #: src/exercises/chromium/bringing-it-together.md msgid "" "The C++ target containing `ResourceBundle::MaybeMangleLocalizedString` will " -"need to depend on a `rust_static_library` target. The student probably " -"already did this." +"need to depend on a `rust_static_library` target. The student likely already " +"did this." msgstr "" #: src/exercises/chromium/bringing-it-together.md @@ -15188,6 +17497,14 @@ msgid "" "(https://chromium-review.googlesource.com/c/chromium/src/+/5096560)." msgstr "" +#: src/exercises/chromium/solutions.md +msgid "" +"Or, if you'd prefer \"standalone\" solutions that don't require applying " +"patchsets or integration with core Chromium code, you can find them in the " +"[`//chromium/src/codelabs/rust` subdirectory in Chromium](https://source." +"chromium.org/chromium/chromium/src/+/main:codelabs/rust/)." +msgstr "" + #: src/bare-metal.md msgid "Welcome to Bare Metal Rust" msgstr "" @@ -15226,7 +17543,7 @@ msgstr "" msgid "" "For the microcontroller part of the course we will use the [BBC micro:bit]" "(https://microbit.org/) v2 as an example. It's a [development board](https://" -"tech.microbit.org/hardware/) based on the Nordic nRF51822 microcontroller " +"tech.microbit.org/hardware/) based on the Nordic nRF52833 microcontroller " "with some LEDs and buttons, an I2C-connected accelerometer and compass, and " "an on-board SWD debugger." msgstr "" @@ -15241,6 +17558,14 @@ msgid "" "And give users in the `plugdev` group access to the micro:bit programmer:" msgstr "" +#: src/bare-metal.md +msgid "" +"You should see \"NXP ARM mbed\" in the output of `lsusb` if the device is " +"available. If you are using a Linux environment on a Chromebook, you will " +"need to share the USB device with Linux, via `chrome://os-settings/crostini/" +"sharedUsbDevices`." +msgstr "" + #: src/bare-metal.md src/bare-metal/microcontrollers/debugging.md msgid "On MacOS:" msgstr "" @@ -15269,6 +17594,14 @@ msgstr "" msgid "`Display`, `Debug`, `write!`..." msgstr "" +#: src/bare-metal/no_std.md +msgid "`Iterator`" +msgstr "" + +#: src/bare-metal/no_std.md +msgid "`Error`" +msgstr "" + #: src/bare-metal/no_std.md msgid "`panic!`, `assert_eq!`..." msgstr "" @@ -15301,10 +17634,6 @@ msgstr "" msgid "`String`, `CString`, `format!`" msgstr "" -#: src/bare-metal/no_std.md -msgid "`Error`" -msgstr "" - #: src/bare-metal/no_std.md msgid "`Mutex`, `Condvar`, `Barrier`, `Once`, `RwLock`, `mpsc`" msgstr "" @@ -15381,8 +17710,7 @@ msgid "" msgstr "" #: src/bare-metal/alloc.md -msgid "" -"// Safe because `HEAP` is only used here and `entry` is only called once.\n" +msgid "// SAFETY: `HEAP` is only used here and `entry` is only called once.\n" msgstr "" #: src/bare-metal/alloc.md @@ -15394,15 +17722,14 @@ msgid "// Now we can do things that require heap allocation.\n" msgstr "" #: src/bare-metal/alloc.md -#, fuzzy msgid "\"A string\"" -msgstr "String" +msgstr "" #: src/bare-metal/alloc.md msgid "" -"`buddy_system_allocator` is a third-party crate implementing a basic buddy " -"system allocator. Other crates are available, or you can write your own or " -"hook into your existing allocator." +"`buddy_system_allocator` is a crate implementing a basic buddy system " +"allocator. Other crates are available, or you can write your own or hook " +"into your existing allocator." msgstr "" #: src/bare-metal/alloc.md @@ -15476,8 +17803,8 @@ msgstr "" #: src/bare-metal/microcontrollers/mmio.md msgid "" -"// Safe because the pointers are to valid peripheral control registers, and\n" -" // no aliases exist.\n" +"// SAFETY: The pointers are to valid peripheral control registers, and no\n" +" // aliases exist.\n" msgstr "" #: src/bare-metal/microcontrollers/mmio.md @@ -15513,19 +17840,19 @@ msgstr "" #: src/bare-metal/microcontrollers/pacs.md msgid "" "SVD (System View Description) files are XML files typically provided by " -"silicon vendors which describe the memory map of the device." +"silicon vendors that describe the memory map of the device." msgstr "" #: src/bare-metal/microcontrollers/pacs.md msgid "" -"They are organised by peripheral, register, field and value, with names, " +"They are organized by peripheral, register, field and value, with names, " "descriptions, addresses and so on." msgstr "" #: src/bare-metal/microcontrollers/pacs.md msgid "" -"SVD files are often buggy and incomplete, so there are various projects " -"which patch the mistakes, add missing details, and publish the generated " +"SVD files are frequently buggy and incomplete, so there are various projects " +"that patch the mistakes, add missing details, and publish the generated " "crates." msgstr "" @@ -15579,7 +17906,7 @@ msgstr "" #: src/bare-metal/microcontrollers/board-support.md msgid "" "In this case the board support crate is just providing more useful names, " -"and a bit of initialisation." +"and a bit of initialization." msgstr "" #: src/bare-metal/microcontrollers/board-support.md @@ -15600,10 +17927,6 @@ msgstr "" msgid "// let gpio0_01_again = gpio0.p0_01; // Error, moved.\n" msgstr "" -#: src/bare-metal/microcontrollers/type-state.md -msgid "// ...\n" -msgstr "" - #: src/bare-metal/microcontrollers/type-state.md msgid "// pin_input.is_high(); // Error, moved.\n" msgstr "" @@ -15611,22 +17934,22 @@ msgstr "" #: src/bare-metal/microcontrollers/type-state.md msgid "" "Pins don't implement `Copy` or `Clone`, so only one instance of each can " -"exist. Once a pin is moved out of the port struct nobody else can take it." +"exist. Once a pin is moved out of the port struct, nobody else can take it." msgstr "" #: src/bare-metal/microcontrollers/type-state.md msgid "" "Changing the configuration of a pin consumes the old pin instance, so you " -"can’t keep use the old instance afterwards." +"can't use the old instance afterwards." msgstr "" #: src/bare-metal/microcontrollers/type-state.md msgid "" -"The type of a value indicates the state that it is in: e.g. in this case, " -"the configuration state of a GPIO pin. This encodes the state machine into " -"the type system, and ensures that you don't try to use a pin in a certain " -"way without properly configuring it first. Illegal state transitions are " -"caught at compile time." +"The type of a value indicates the state it is in: e.g., in this case, the " +"configuration state of a GPIO pin. This encodes the state machine into the " +"type system and ensures that you don't try to use a pin in a certain way " +"without properly configuring it first. Illegal state transitions are caught " +"at compile time." msgstr "" #: src/bare-metal/microcontrollers/type-state.md @@ -15642,7 +17965,7 @@ msgstr "" #: src/bare-metal/microcontrollers/embedded-hal.md msgid "" "The [`embedded-hal`](https://crates.io/crates/embedded-hal) crate provides a " -"number of traits covering common microcontroller peripherals." +"number of traits covering common microcontroller peripherals:" msgstr "" #: src/bare-metal/microcontrollers/embedded-hal.md @@ -15650,30 +17973,36 @@ msgid "GPIO" msgstr "" #: src/bare-metal/microcontrollers/embedded-hal.md -msgid "ADC" +msgid "PWM" msgstr "" #: src/bare-metal/microcontrollers/embedded-hal.md -msgid "I2C, SPI, UART, CAN" +msgid "Delay timers" msgstr "" #: src/bare-metal/microcontrollers/embedded-hal.md -msgid "RNG" +msgid "I2C and SPI buses and devices" msgstr "" #: src/bare-metal/microcontrollers/embedded-hal.md -msgid "Timers" -msgstr "" - -#: src/bare-metal/microcontrollers/embedded-hal.md -msgid "Watchdogs" +msgid "" +"Similar traits for byte streams (e.g. UARTs), CAN buses and RNGs are broken " +"out into [`embedded-io`](https://crates.io/crates/embedded-io), [`embedded-" +"can`](https://crates.io/crates/embedded-can) and [`rand_core`](https://" +"crates.io/crates/rand_core) respectively." msgstr "" #: src/bare-metal/microcontrollers/embedded-hal.md msgid "" "Other crates then implement [drivers](https://github.com/rust-embedded/" "awesome-embedded-rust#driver-crates) in terms of these traits, e.g. an " -"accelerometer driver might need an I2C or SPI bus implementation." +"accelerometer driver might need an I2C or SPI device instance." +msgstr "" + +#: src/bare-metal/microcontrollers/embedded-hal.md +msgid "" +"The traits cover using the peripherals but not initializing or configuring " +"them, as initialization and configuration is highly platform-specific." msgstr "" #: src/bare-metal/microcontrollers/embedded-hal.md @@ -15684,8 +18013,15 @@ msgstr "" #: src/bare-metal/microcontrollers/embedded-hal.md msgid "" -"There is work in progress on an `async` version of `embedded-hal`, but it " -"isn't stable yet." +"[`embedded-hal-async`](https://crates.io/crates/embedded-hal-async) provides " +"async versions of the traits." +msgstr "" + +#: src/bare-metal/microcontrollers/embedded-hal.md +msgid "" +"[`embedded-hal-nb`](https://crates.io/crates/embedded-hal-nb) provides " +"another approach to non-blocking I/O, based on the [`nb`](https://crates.io/" +"crates/nb) crate." msgstr "" #: src/bare-metal/microcontrollers/probe-rs.md @@ -15736,8 +18072,8 @@ msgstr "" #: src/bare-metal/microcontrollers/probe-rs.md msgid "" -"probe-rs is a library which you can integrate into your own tools if you " -"want to." +"probe-rs is a library that you can integrate into your own tools if you want " +"to." msgstr "" #: src/bare-metal/microcontrollers/probe-rs.md @@ -15754,7 +18090,7 @@ msgstr "" #: src/bare-metal/microcontrollers/probe-rs.md msgid "" "RTT (Real Time Transfers) is a mechanism to transfer data between the debug " -"host and the target through a number of ringbuffers." +"host and the target through a number of ring buffers." msgstr "" #: src/bare-metal/microcontrollers/debugging.md @@ -15787,12 +18123,12 @@ msgid "[RTIC](https://rtic.rs/)" msgstr "" #: src/bare-metal/microcontrollers/other-projects.md -msgid "\"Real-Time Interrupt-driven Concurrency\"" +msgid "\"Real-Time Interrupt-driven Concurrency\"." msgstr "" #: src/bare-metal/microcontrollers/other-projects.md msgid "" -"Shared resource management, message passing, task scheduling, timer queue" +"Shared resource management, message passing, task scheduling, timer queue." msgstr "" #: src/bare-metal/microcontrollers/other-projects.md @@ -15800,7 +18136,7 @@ msgid "[Embassy](https://embassy.dev/)" msgstr "" #: src/bare-metal/microcontrollers/other-projects.md -msgid "`async` executors with priorities, timers, networking, USB" +msgid "`async` executors with priorities, timers, networking, USB." msgstr "" #: src/bare-metal/microcontrollers/other-projects.md @@ -15810,7 +18146,7 @@ msgstr "" #: src/bare-metal/microcontrollers/other-projects.md msgid "" "Security-focused RTOS with preemptive scheduling and Memory Protection Unit " -"support" +"support." msgstr "" #: src/bare-metal/microcontrollers/other-projects.md @@ -15820,11 +18156,11 @@ msgstr "" #: src/bare-metal/microcontrollers/other-projects.md msgid "" "Microkernel RTOS from Oxide Computer Company with memory protection, " -"unprivileged drivers, IPC" +"unprivileged drivers, IPC." msgstr "" #: src/bare-metal/microcontrollers/other-projects.md -msgid "[Bindings for FreeRTOS](https://github.com/lobaro/FreeRTOS-rust)" +msgid "[Bindings for FreeRTOS](https://github.com/lobaro/FreeRTOS-rust)." msgstr "" #: src/bare-metal/microcontrollers/other-projects.md @@ -15868,7 +18204,7 @@ msgid "" "serial port." msgstr "" -#: src/exercises/bare-metal/morning.md src/exercises/concurrency/morning.md +#: src/exercises/bare-metal/morning.md msgid "" "After looking at the exercises, you can look at the [solutions](solutions-" "morning.md) provided." @@ -15905,9 +18241,9 @@ msgstr "" #: src/exercises/bare-metal/compass.md msgid "" -"The LSM303AGR driver needs something implementing the `embedded_hal::" -"blocking::i2c::WriteRead` trait. The [`microbit::hal::Twim`](https://docs.rs/" -"microbit-v2/latest/microbit/hal/struct.Twim.html) struct implements this." +"The LSM303AGR driver needs something implementing the `embedded_hal::i2c::" +"I2c` trait. The [`microbit::hal::Twim`](https://docs.rs/microbit-v2/latest/" +"microbit/hal/struct.Twim.html) struct implements this." msgstr "" #: src/exercises/bare-metal/compass.md @@ -16012,16 +18348,31 @@ msgstr "" #: src/bare-metal/aps.md msgid "" "So far we've talked about microcontrollers, such as the Arm Cortex-M series. " -"Now let's try writing something for Cortex-A. For simplicity we'll just work " -"with QEMU's aarch64 ['virt'](https://qemu-project.gitlab.io/qemu/system/arm/" -"virt.html) board." +"These are typically small systems with very limited resources." +msgstr "" + +#: src/bare-metal/aps.md +msgid "" +"Larger systems with more resources are typically called application " +"processors, built around processors such as the ARM Cortex-A or Intel Atom." +msgstr "" + +#: src/bare-metal/aps.md +msgid "" +"For simplicity we'll just work with QEMU's aarch64 ['virt'](https://qemu-" +"project.gitlab.io/qemu/system/arm/virt.html) board." msgstr "" #: src/bare-metal/aps.md msgid "" "Broadly speaking, microcontrollers don't have an MMU or multiple levels of " -"privilege (exception levels on Arm CPUs, rings on x86), while application " -"processors do." +"privilege (exception levels on Arm CPUs, rings on x86)." +msgstr "" + +#: src/bare-metal/aps.md +msgid "" +"Application processors have more resources, and often run an operating " +"system, instead of directly executing the target application on startup." msgstr "" #: src/bare-metal/aps.md @@ -16031,21 +18382,42 @@ msgid "" "hardware, but is designed purely for virtual machines." msgstr "" +#: src/bare-metal/aps.md +msgid "" +"We will still address this board as bare-metal, as if we were writing an " +"operating system." +msgstr "" + #: src/bare-metal/aps/entry-point.md msgid "" -"Before we can start running Rust code, we need to do some initialisation." +"Before we can start running Rust code, we need to do some initialization." msgstr "" #: src/bare-metal/aps/entry-point.md msgid "" "```armasm\n" +"/**\n" +" * This is a generic entry point for an image. It carries out the\n" +" * operations required to prepare the loaded image to be run.\n" +" * Specifically, it\n" +" *\n" +" * - sets up the MMU with an identity map of virtual to physical\n" +" * addresses, and enables caching\n" +" * - enables floating point\n" +" * - zeroes the bss section using registers x25 and above\n" +" * - prepares the stack, pointing to a section within the image\n" +" * - sets up the exception vector\n" +" * - branches to the Rust `main` function\n" +" *\n" +" * It preserves x0-x3 for the Rust entry point, as these may contain\n" +" * boot parameters.\n" +" */\n" ".section .init.entry, \"ax\"\n" ".global entry\n" "entry:\n" " /*\n" -" * Load and apply the memory management configuration, ready to enable " -"MMU and\n" -" * caches.\n" +" * Load and apply the memory management configuration, ready to\n" +" * enable MMU and caches.\n" " */\n" " adrp x30, idmap\n" " msr ttbr0_el1, x30\n" @@ -16063,9 +18435,9 @@ msgid "" " mov_i x30, .Lsctlrval\n" "\n" " /*\n" -" * Ensure everything before this point has completed, then invalidate " -"any\n" -" * potentially stale local TLB entries before they start being used.\n" +" * Ensure everything before this point has completed, then\n" +" * invalidate any potentially stale local TLB entries before they\n" +" * start being used.\n" " */\n" " isb\n" " tlbi vmalle1\n" @@ -16074,9 +18446,8 @@ msgid "" " isb\n" "\n" " /*\n" -" * Configure sctlr_el1 to enable MMU and cache and don't proceed until " -"this\n" -" * has completed.\n" +" * Configure sctlr_el1 to enable MMU and cache and don't proceed\n" +" * until this has completed.\n" " */\n" " msr sctlr_el1, x30\n" " isb\n" @@ -16114,22 +18485,29 @@ msgstr "" #: src/bare-metal/aps/entry-point.md msgid "" -"This is the same as it would be for C: initialising the processor state, " +"This code is in `src/bare-metal/aps/examples/src/entry.S`. It's not " +"necessary to understand this in detail -- the takeaway is that some low-" +"level setup is needed to meet Rust's expectations of the system." +msgstr "" + +#: src/bare-metal/aps/entry-point.md +msgid "" +"This is the same as it would be for C: initializing the processor state, " "zeroing the BSS, and setting up the stack pointer." msgstr "" #: src/bare-metal/aps/entry-point.md msgid "" "The BSS (block starting symbol, for historical reasons) is the part of the " -"object file which containing statically allocated variables which are " -"initialised to zero. They are omitted from the image, to avoid wasting space " +"object file that contains statically allocated variables that are " +"initialized to zero. They are omitted from the image, to avoid wasting space " "on zeroes. The compiler assumes that the loader will take care of zeroing " "them." msgstr "" #: src/bare-metal/aps/entry-point.md msgid "" -"The BSS may already be zeroed, depending on how memory is initialised and " +"The BSS may already be zeroed, depending on how memory is initialized and " "the image is loaded, but we zero it to be sure." msgstr "" @@ -16142,7 +18520,7 @@ msgstr "" #: src/bare-metal/aps/entry-point.md msgid "" "Unaligned accesses will fault. We build the Rust code for the `aarch64-" -"unknown-none` target which sets `+strict-align` to prevent the compiler " +"unknown-none` target that sets `+strict-align` to prevent the compiler from " "generating unaligned accesses, so it should be fine in this case, but this " "is not necessarily the case in general." msgstr "" @@ -16160,7 +18538,7 @@ msgstr "" #: src/bare-metal/aps/entry-point.md msgid "" -"For simplicity, we just use a hardcoded pagetable (see `idmap.S`) which " +"For simplicity, we just use a hardcoded pagetable (see `idmap.S`) that " "identity maps the first 1 GiB of address space for devices, the next 1 GiB " "for DRAM, and another 1 GiB higher up for more devices. This matches the " "memory layout that QEMU uses." @@ -16175,7 +18553,7 @@ msgstr "" #: src/bare-metal/aps/entry-point.md msgid "" "All examples this afternoon assume we will be running at exception level 1 " -"(EL1). If you need to run at a different exception level you'll need to " +"(EL1). If you need to run at a different exception level, you'll need to " "modify `entry.S` accordingly." msgstr "" @@ -16192,8 +18570,8 @@ msgstr "" #: src/bare-metal/aps/inline-assembly.md msgid "" -"// Safe because this only uses the declared registers and doesn't do\n" -" // anything with memory.\n" +"// SAFETY: this only uses the declared registers and doesn't do anything\n" +" // with memory.\n" msgstr "" #: src/bare-metal/aps/inline-assembly.md @@ -16247,7 +18625,7 @@ msgstr "" #: src/bare-metal/aps/inline-assembly.md msgid "" -"The `0 => _` syntax means initialise the register to 0 before running the " +"The `0 => _` syntax means initialize the register to 0 before running the " "inline assembly code, and ignore its contents afterwards. We need to use " "`inout` rather than `in` because the call could potentially clobber the " "contents of the registers." @@ -16255,8 +18633,16 @@ msgstr "" #: src/bare-metal/aps/inline-assembly.md msgid "" -"This `main` function needs to be `#[no_mangle]` and `extern \"C\"` because " -"it is called from our entry point in `entry.S`." +"This `main` function needs to be `#[unsafe(no_mangle)]` and `extern \"C\"` " +"because it is called from our entry point in `entry.S`." +msgstr "" + +#: src/bare-metal/aps/inline-assembly.md +msgid "" +"Just `#[no_mangle]` would be sufficient but [RFC3325](https://rust-lang." +"github.io/rfcs/3325-unsafe-attributes.html) uses this notation to draw " +"reviewer attention to attributes that might cause undefined behavior if used " +"incorrectly." msgstr "" #: src/bare-metal/aps/inline-assembly.md @@ -16280,19 +18666,29 @@ msgid "Volatile memory access for MMIO" msgstr "" #: src/bare-metal/aps/mmio.md -msgid "Use `pointer::read_volatile` and `pointer::write_volatile`." -msgstr "" - -#: src/bare-metal/aps/mmio.md -msgid "Never hold a reference." +msgid "" +"Use [`pointer::read_volatile`](https://doc.rust-lang.org/stable/core/" +"primitive.pointer.html#method.read_volatile) and [`pointer::write_volatile`]" +"(https://doc.rust-lang.org/stable/core/primitive.pointer.html#method." +"write_volatile)." msgstr "" #: src/bare-metal/aps/mmio.md msgid "" -"`addr_of!` lets you get fields of structs without creating an intermediate " +"Never hold a reference to a location being accessed with these methods. Rust " +"may read from (or write to, for `&mut`) a reference at any time." +msgstr "" + +#: src/bare-metal/aps/mmio.md +msgid "" +"Use `&raw` to get fields of structs without creating an intermediate " "reference." msgstr "" +#: src/bare-metal/aps/mmio.md +msgid "// SAFETY: Some device is mapped at this address.\n" +msgstr "" + #: src/bare-metal/aps/mmio.md msgid "" "Volatile access: read or write operations may have side-effects, so prevent " @@ -16301,22 +18697,26 @@ msgstr "" #: src/bare-metal/aps/mmio.md msgid "" -"Usually if you write and then read, e.g. via a mutable reference, the " -"compiler may assume that the value read is the same as the value just " -"written, and not bother actually reading memory." +"If you write and then read, e.g. via a mutable reference, the compiler may " +"assume that the value read is the same as the value just written, and not " +"bother actually reading memory." msgstr "" #: src/bare-metal/aps/mmio.md msgid "" "Some existing crates for volatile access to hardware do hold references, but " -"this is unsound. Whenever a reference exist, the compiler may choose to " +"this is unsound. Whenever a reference exists, the compiler may choose to " "dereference it." msgstr "" +#: src/bare-metal/aps/mmio.md +msgid "Use `&raw` to get struct field pointers from a pointer to the struct." +msgstr "" + #: src/bare-metal/aps/mmio.md msgid "" -"Use the `addr_of!` macro to get struct field pointers from a pointer to the " -"struct." +"For compatibility with old versions of Rust you can use the [`addr_of!`]" +"(https://doc.rust-lang.org/stable/core/ptr/macro.addr_of.html) macro instead." msgstr "" #: src/bare-metal/aps/uart.md @@ -16333,7 +18733,7 @@ msgstr "" msgid "/// Minimal driver for a PL011 UART.\n" msgstr "" -#: src/bare-metal/aps/uart.md src/bare-metal/aps/better-uart/driver.md +#: src/bare-metal/aps/uart.md msgid "" "/// Constructs a new instance of the UART driver for a PL011 device at the\n" " /// given base address.\n" @@ -16348,24 +18748,28 @@ msgid "" msgstr "" #: src/bare-metal/aps/uart.md src/bare-metal/aps/better-uart/driver.md +#: src/bare-metal/aps/safemmio/driver.md msgid "/// Writes a single byte to the UART.\n" msgstr "" #: src/bare-metal/aps/uart.md src/bare-metal/aps/better-uart/driver.md +#: src/bare-metal/aps/safemmio/driver.md msgid "// Wait until there is room in the TX buffer.\n" msgstr "" #: src/bare-metal/aps/uart.md msgid "" -"// Safe because we know that the base address points to the control\n" +"// SAFETY: We know that the base address points to the control\n" " // registers of a PL011 device which is appropriately mapped.\n" msgstr "" #: src/bare-metal/aps/uart.md src/bare-metal/aps/better-uart/driver.md +#: src/bare-metal/aps/safemmio/driver.md msgid "// Write to the TX buffer.\n" msgstr "" #: src/bare-metal/aps/uart.md src/bare-metal/aps/better-uart/driver.md +#: src/bare-metal/aps/safemmio/driver.md msgid "// Wait until the UART is no longer busy.\n" msgstr "" @@ -16404,9 +18808,8 @@ msgid "" msgstr "" #: src/bare-metal/aps/uart/traits.md -#: src/exercises/bare-metal/solutions-afternoon.md msgid "" -"// Safe because it just contains a pointer to device memory, which can be\n" +"// SAFETY: `Uart` just contains a pointer to device memory, which can be\n" "// accessed from any context.\n" msgstr "" @@ -16418,6 +18821,47 @@ msgstr "" #: src/bare-metal/aps/uart/traits.md msgid "" +"`Send` is an auto-trait, but not implemented automatically because it is not " +"implemented for pointers." +msgstr "" + +#: src/bare-metal/aps/uart/using.md src/bare-metal/aps/logging/using.md +msgid "Using it" +msgstr "" + +#: src/bare-metal/aps/uart/using.md +msgid "" +"Let's write a small program using our driver to write to the serial console." +msgstr "" + +#: src/bare-metal/aps/uart/using.md src/bare-metal/aps/safemmio/using.md +#: src/bare-metal/aps/logging/using.md src/bare-metal/aps/aarch64-rt.md +#: src/exercises/bare-metal/solutions-afternoon.md +msgid "/// Base address of the primary PL011 UART.\n" +msgstr "" + +#: src/bare-metal/aps/uart/using.md src/bare-metal/aps/safemmio/using.md +#: src/bare-metal/aps/logging/using.md src/bare-metal/aps/aarch64-rt.md +#: src/exercises/bare-metal/solutions-afternoon.md +msgid "" +"// SAFETY: `PL011_BASE_ADDRESS` is the base address of a PL011 device, and\n" +" // nothing else accesses that address range.\n" +msgstr "" + +#: src/bare-metal/aps/uart/using.md src/bare-metal/aps/safemmio/using.md +#: src/bare-metal/aps/logging/using.md src/bare-metal/aps/aarch64-rt.md +msgid "\"main({x0:#x}, {x1:#x}, {x2:#x}, {x3:#x})\"" +msgstr "" + +#: src/bare-metal/aps/uart/using.md +msgid "" +"As in the [inline assembly](../inline-assembly.md) example, this `main` " +"function is called from our entry point code in `entry.S`. See the speaker " +"notes there for details." +msgstr "" + +#: src/bare-metal/aps/uart/using.md +msgid "" "Run the example in QEMU with `make qemu_minimal` under `src/bare-metal/aps/" "examples`." msgstr "" @@ -16428,11 +18872,11 @@ msgstr "" #: src/bare-metal/aps/better-uart.md msgid "" -"The PL011 actually has [a bunch more registers](https://developer.arm.com/" +"The PL011 actually has [more registers](https://developer.arm.com/" "documentation/ddi0183/g/programmers-model/summary-of-registers), and adding " "offsets to construct pointers to access them is error-prone and hard to " -"read. Plus, some of them are bit fields which would be nice to access in a " -"structured way." +"read. Additionally, some of them are bit fields, which would be nice to " +"access in a structured way." msgstr "" #: src/bare-metal/aps/better-uart.md @@ -16467,6 +18911,10 @@ msgstr "" msgid "RSR" msgstr "" +#: src/bare-metal/aps/better-uart.md +msgid "4" +msgstr "" + #: src/bare-metal/aps/better-uart.md msgid "0x18" msgstr "" @@ -16487,6 +18935,10 @@ msgstr "" msgid "ILPR" msgstr "" +#: src/bare-metal/aps/better-uart.md +msgid "8" +msgstr "" + #: src/bare-metal/aps/better-uart.md msgid "0x24" msgstr "" @@ -16507,6 +18959,10 @@ msgstr "" msgid "FBRD" msgstr "" +#: src/bare-metal/aps/better-uart.md +msgid "6" +msgstr "" + #: src/bare-metal/aps/better-uart.md msgid "0x2c" msgstr "" @@ -16576,7 +19032,11 @@ msgid "DMACR" msgstr "" #: src/bare-metal/aps/better-uart.md -msgid "There are also some ID registers which have been omitted for brevity." +msgid "3" +msgstr "" + +#: src/bare-metal/aps/better-uart.md +msgid "There are also some ID registers that have been omitted for brevity." msgstr "" #: src/bare-metal/aps/better-uart/bitflags.md @@ -16627,8 +19087,8 @@ msgstr "" #: src/bare-metal/aps/better-uart/bitflags.md msgid "" -"The `bitflags!` macro creates a newtype something like `Flags(u16)`, along " -"with a bunch of method implementations to get and set flags." +"The `bitflags!` macro creates a newtype something like `struct Flags(u16)`, " +"along with a bunch of method implementations to get and set flags." msgstr "" #: src/bare-metal/aps/better-uart/registers.md @@ -16650,87 +19110,227 @@ msgid "" msgstr "" #: src/bare-metal/aps/better-uart/driver.md +#: src/bare-metal/aps/safemmio/driver.md msgid "Now let's use the new `Registers` struct in our driver." msgstr "" #: src/bare-metal/aps/better-uart/driver.md +#: src/bare-metal/aps/safemmio/driver.md msgid "/// Driver for a PL011 UART.\n" msgstr "" #: src/bare-metal/aps/better-uart/driver.md msgid "" -"// Safe because we know that self.registers points to the control\n" -" // registers of a PL011 device which is appropriately mapped.\n" +"/// Constructs a new instance of the UART driver for a PL011 device with " +"the\n" +" /// given set of registers.\n" +" ///\n" +" /// # Safety\n" +" ///\n" +" /// The given pointer must point to the 8 MMIO control registers of a " +"PL011\n" +" /// device, which must be mapped into the address space of the process " +"as\n" +" /// device memory and not have any other aliases.\n" msgstr "" #: src/bare-metal/aps/better-uart/driver.md msgid "" +"// SAFETY: We know that self.registers points to the control registers\n" +" // of a PL011 device which is appropriately mapped.\n" +msgstr "" + +#: src/bare-metal/aps/better-uart/driver.md +#: src/bare-metal/aps/safemmio/driver.md +msgid "" "/// Reads and returns a pending byte, or `None` if nothing has been\n" " /// received.\n" msgstr "" #: src/bare-metal/aps/better-uart/driver.md +msgid "" +"// SAFETY: We know that self.registers points to the control\n" +" // registers of a PL011 device which is appropriately mapped.\n" +msgstr "" + +#: src/bare-metal/aps/better-uart/driver.md +#: src/bare-metal/aps/safemmio/driver.md msgid "// TODO: Check for error conditions in bits 8-11.\n" msgstr "" #: src/bare-metal/aps/better-uart/driver.md msgid "" -"Note the use of `addr_of!` / `addr_of_mut!` to get pointers to individual " +"Note the use of `&raw const` / `&raw mut` to get pointers to individual " "fields without creating an intermediate reference, which would be unsound." msgstr "" -#: src/bare-metal/aps/better-uart/using.md src/bare-metal/aps/logging/using.md -msgid "Using it" +#: src/bare-metal/aps/better-uart/driver.md +msgid "" +"The example isn't included in the slides because it is very similar to the " +"`safe-mmio` example which comes next. You can run it in QEMU with `make " +"qemu` under `src/bare-metal/aps/examples` if you need to." msgstr "" -#: src/bare-metal/aps/better-uart/using.md +#: src/bare-metal/aps/safemmio/registers.md +msgid "" +"The [`safe-mmio`](https://crates.io/crates/safe-mmio) crate provides types " +"to wrap registers that can be read or written safely." +msgstr "" + +#: src/bare-metal/aps/safemmio/registers.md +msgid "Can't read" +msgstr "" + +#: src/bare-metal/aps/safemmio/registers.md +msgid "Read has no side-effects" +msgstr "" + +#: src/bare-metal/aps/safemmio/registers.md +msgid "Read has side-effects" +msgstr "" + +#: src/bare-metal/aps/safemmio/registers.md +msgid "Can't write" +msgstr "" + +#: src/bare-metal/aps/safemmio/registers.md +msgid "" +"[`ReadPure`](https://docs.rs/safe-mmio/latest/safe_mmio/fields/struct." +"ReadPure.html)" +msgstr "" + +#: src/bare-metal/aps/safemmio/registers.md +msgid "" +"[`ReadOnly`](https://docs.rs/safe-mmio/latest/safe_mmio/fields/struct." +"ReadOnly.html)" +msgstr "" + +#: src/bare-metal/aps/safemmio/registers.md +msgid "Can write" +msgstr "" + +#: src/bare-metal/aps/safemmio/registers.md +msgid "" +"[`WriteOnly`](https://docs.rs/safe-mmio/latest/safe_mmio/fields/struct." +"WriteOnly.html)" +msgstr "" + +#: src/bare-metal/aps/safemmio/registers.md +msgid "" +"[`ReadPureWrite`](https://docs.rs/safe-mmio/latest/safe_mmio/fields/struct." +"ReadPureWrite.html)" +msgstr "" + +#: src/bare-metal/aps/safemmio/registers.md +msgid "" +"[`ReadWrite`](https://docs.rs/safe-mmio/latest/safe_mmio/fields/struct." +"ReadWrite.html)" +msgstr "" + +#: src/bare-metal/aps/safemmio/registers.md +msgid "Reading `dr` has a side effect: it pops a byte from the receive FIFO." +msgstr "" + +#: src/bare-metal/aps/safemmio/registers.md +msgid "" +"Reading `rsr` (and other registers) has no side-effects. It is a 'pure' read." +msgstr "" + +#: src/bare-metal/aps/safemmio/registers.md +msgid "" +"There are a number of different crates providing safe abstractions around " +"MMIO operations; we recommend the `safe-mmio` crate." +msgstr "" + +#: src/bare-metal/aps/safemmio/registers.md +msgid "" +"The difference between `ReadPure` or `ReadOnly` (and likewise between " +"`ReadPureWrite` and `ReadWrite`) is whether reading a register can have side-" +"effects that change the state of the device, e.g., reading the data register " +"pops a byte from the receive FIFO. `ReadPure` means that reads have no side-" +"effects, they are purely reading data." +msgstr "" + +#: src/bare-metal/aps/safemmio/driver.md +msgid "" +"/// Constructs a new instance of the UART driver for a PL011 device with " +"the\n" +" /// given set of registers.\n" +msgstr "" + +#: src/bare-metal/aps/safemmio/driver.md +msgid "The driver no longer needs any unsafe code!" +msgstr "" + +#: src/bare-metal/aps/safemmio/driver.md +msgid "" +"`UniqueMmioPointer` is a wrapper around a raw pointer to an MMIO device or " +"register. The caller of `UniqueMmioPointer::new` promises that it is valid " +"and unique for the given lifetime, so it can provide safe methods to read " +"and write fields." +msgstr "" + +#: src/bare-metal/aps/safemmio/driver.md +msgid "" +"Note that `Uart::new` is now safe; `UniqueMmioPointer::new` is unsafe " +"instead." +msgstr "" + +#: src/bare-metal/aps/safemmio/driver.md +msgid "" +"These MMIO accesses are generally a wrapper around `read_volatile` and " +"`write_volatile`, though on aarch64 they are instead implemented in assembly " +"to work around a bug where the compiler can emit instructions that prevent " +"MMIO virtualization." +msgstr "" + +#: src/bare-metal/aps/safemmio/driver.md +msgid "" +"The `field!` and `field_shared!` macros internally use `&raw mut` and `&raw " +"const` to get pointers to individual fields without creating an intermediate " +"reference, which would be unsound." +msgstr "" + +#: src/bare-metal/aps/safemmio/driver.md +msgid "" +"`field!` needs a mutable reference to a `UniqueMmioPointer`, and returns a " +"`UniqueMmioPointer` that allows reads with side effects and writes." +msgstr "" + +#: src/bare-metal/aps/safemmio/driver.md +msgid "" +"`field_shared!` works with a shared reference to either a " +"`UniqueMmioPointer` or a `SharedMmioPointer`. It returns a " +"`SharedMmioPointer` that only allows pure reads." +msgstr "" + +#: src/bare-metal/aps/safemmio/using.md msgid "" "Let's write a small program using our driver to write to the serial console, " "and echo incoming bytes." msgstr "" -#: src/bare-metal/aps/better-uart/using.md src/bare-metal/aps/logging/using.md -#: src/exercises/bare-metal/solutions-afternoon.md -msgid "/// Base address of the primary PL011 UART.\n" -msgstr "" - -#: src/bare-metal/aps/better-uart/using.md src/bare-metal/aps/logging/using.md -#: src/exercises/bare-metal/solutions-afternoon.md -msgid "" -"// Safe because `PL011_BASE_ADDRESS` is the base address of a PL011 device,\n" -" // and nothing else accesses that address range.\n" -msgstr "" - -#: src/bare-metal/aps/better-uart/using.md src/bare-metal/aps/logging/using.md -msgid "\"main({x0:#x}, {x1:#x}, {x2:#x}, {x3:#x})\"" -msgstr "" - -#: src/bare-metal/aps/better-uart/using.md +#: src/bare-metal/aps/safemmio/using.md msgid "b'\\r'" msgstr "" -#: src/bare-metal/aps/better-uart/using.md src/async/pitfalls/cancellation.md +#: src/bare-metal/aps/safemmio/using.md +#: src/concurrency/async-pitfalls/cancellation.md msgid "b'\\n'" msgstr "" -#: src/bare-metal/aps/better-uart/using.md +#: src/bare-metal/aps/safemmio/using.md msgid "b'q'" msgstr "" -#: src/bare-metal/aps/better-uart/using.md -msgid "\"Bye!\"" +#: src/bare-metal/aps/safemmio/using.md +msgid "\"\\n\\nBye!\"" msgstr "" -#: src/bare-metal/aps/better-uart/using.md +#: src/bare-metal/aps/safemmio/using.md msgid "" -"As in the [inline assembly](../inline-assembly.md) example, this `main` " -"function is called from our entry point code in `entry.S`. See the speaker " -"notes there for details." -msgstr "" - -#: src/bare-metal/aps/better-uart/using.md -msgid "" -"Run the example in QEMU with `make qemu` under `src/bare-metal/aps/examples`." +"Run the example in QEMU with `make qemu_safemmio` under `src/bare-metal/aps/" +"examples`." msgstr "" #: src/bare-metal/aps/logging.md @@ -16750,8 +19350,9 @@ msgstr "" #: src/bare-metal/aps/logging.md msgid "" -"The unwrap in `log` is safe because we initialise `LOGGER` before calling " -"`set_logger`." +"The first unwrap in `log` will succeed because we initialize `LOGGER` before " +"calling `set_logger`. The second will succeed because `Uart::write_str` " +"always returns `Ok`." msgstr "" #: src/bare-metal/aps/logging/using.md @@ -16808,12 +19409,99 @@ msgid "" "it in something like a `Mutex` and put it in a static." msgstr "" +#: src/bare-metal/aps/exceptions.md +msgid "The assembly code for the exception vector:" +msgstr "" + +#: src/bare-metal/aps/aarch64-rt.md +msgid "" +"The `aarch64-rt` crate provides the assembly entry point and exception " +"vector that we implemented before. We just need to mark our main function " +"with the `entry!` macro." +msgstr "" + +#: src/bare-metal/aps/aarch64-rt.md +msgid "" +"It also provides the `initial_pagetable!` macro to let us define an initial " +"static pagetable in Rust, rather than in assembly code like we did before." +msgstr "" + +#: src/bare-metal/aps/aarch64-rt.md +msgid "" +"We can also use the UART driver from the `arm-pl011-uart` crate rather than " +"writing our own." +msgstr "" + +#: src/bare-metal/aps/aarch64-rt.md +#: src/exercises/bare-metal/solutions-afternoon.md +msgid "/// Attributes to use for device memory in the initial identity map.\n" +msgstr "" + +#: src/bare-metal/aps/aarch64-rt.md +#: src/exercises/bare-metal/solutions-afternoon.md +msgid "/// Attributes to use for normal memory in the initial identity map.\n" +msgstr "" + +#: src/bare-metal/aps/aarch64-rt.md +#: src/exercises/bare-metal/solutions-afternoon.md +msgid "// 1 GiB of device memory.\n" +msgstr "" + +#: src/bare-metal/aps/aarch64-rt.md +#: src/exercises/bare-metal/solutions-afternoon.md +msgid "// 1 GiB of normal memory.\n" +msgstr "" + +#: src/bare-metal/aps/aarch64-rt.md +#: src/exercises/bare-metal/solutions-afternoon.md +msgid "// Another 1 GiB of device memory starting at 256 GiB.\n" +msgstr "" + +#: src/bare-metal/aps/aarch64-rt.md +#: src/exercises/bare-metal/solutions-afternoon.md +msgid "\"system_off returned\"" +msgstr "" + +#: src/bare-metal/aps/aarch64-rt.md +msgid "" +"Run the example in QEMU with `make qemu_rt` under `src/bare-metal/aps/" +"examples`." +msgstr "" + +#: src/bare-metal/aps/aarch64-rt/exceptions.md +msgid "" +"`aarch64-rt` provides a trait to define exception handlers, and a macro to " +"generate the assembly code for the exception vector to call them." +msgstr "" + +#: src/bare-metal/aps/aarch64-rt/exceptions.md +msgid "" +"The trait has default implementations for each method which simply panic, so " +"we can omit methods for exceptions we don't expect to happen." +msgstr "" + +#: src/bare-metal/aps/aarch64-rt/exceptions.md +msgid "" +"The `exception_handlers` macro generates a `global_asm!` block with the " +"exception vector to call into the Rust code, similar to the `exceptions.S` " +"we had before." +msgstr "" + +#: src/bare-metal/aps/aarch64-rt/exceptions.md +msgid "" +"`RegisterStateRef` wraps a reference to the stack frame where the register " +"values were saved by the assembly code when the exception happed. This can " +"be used for example to extract the parameters for an SMC or HVC call from a " +"lower EL, and update the values to be restored when the exception handler " +"returns." +msgstr "" + #: src/bare-metal/aps/other-projects.md msgid "[oreboot](https://github.com/oreboot/oreboot)" msgstr "" #: src/bare-metal/aps/other-projects.md -msgid "\"coreboot without the C\"" +msgid "\"coreboot without the C\"." msgstr "" #: src/bare-metal/aps/other-projects.md @@ -16832,13 +19520,13 @@ msgstr "" #: src/bare-metal/aps/other-projects.md msgid "" -"Initialisation, UART driver, simple bootloader, JTAG, exception levels, " -"exception handling, page tables" +"Initialization, UART driver, simple bootloader, JTAG, exception levels, " +"exception handling, page tables." msgstr "" #: src/bare-metal/aps/other-projects.md msgid "" -"Some dodginess around cache maintenance and initialisation in Rust, not " +"Some caveats around cache maintenance and initialization in Rust, not " "necessarily a good example to copy for production code." msgstr "" @@ -16853,35 +19541,18 @@ msgstr "" #: src/bare-metal/aps/other-projects.md msgid "" "The RaspberryPi OS tutorial runs Rust code before the MMU and caches are " -"enabled. This will read and write memory (e.g. the stack). However:" -msgstr "" - -#: src/bare-metal/aps/other-projects.md -msgid "" -"Without the MMU and cache, unaligned accesses will fault. It builds with " -"`aarch64-unknown-none` which sets `+strict-align` to prevent the compiler " -"generating unaligned accesses so it should be alright, but this is not " -"necessarily the case in general." -msgstr "" - -#: src/bare-metal/aps/other-projects.md -msgid "" -"If it were running in a VM, this can lead to cache coherency issues. The " -"problem is that the VM is accessing memory directly with the cache disabled, " -"while the host has cacheable aliases to the same memory. Even if the host " -"doesn't explicitly access the memory, speculative accesses can lead to cache " -"fills, and then changes from one or the other will get lost. Again this is " -"alright in this particular case (running directly on the hardware with no " -"hypervisor), but isn't a good pattern in general." +"enabled. This will read and write memory (e.g. the stack). However, this has " +"the problems mentioned at the beginning of this session regarding unaligned " +"access and cache coherency." msgstr "" #: src/bare-metal/useful-crates.md msgid "Useful crates" -msgstr "āĻĻāϰāĻ•āĻžāϰ⧀ āĻ•ā§āϰ⧇āϟ-āϏāĻŽā§‚āĻš" +msgstr "" #: src/bare-metal/useful-crates.md msgid "" -"We'll go over a few crates which solve some common problems in bare-metal " +"We'll look at a few crates that solve some common problems in bare-metal " "programming." msgstr "" @@ -16932,46 +19603,41 @@ msgid "" msgstr "" #: src/bare-metal/useful-crates/aarch64-paging.md -msgid "// Create a new page table with identity mapping." +msgid "// Create a new page table with identity mapping.\n" msgstr "" #: src/bare-metal/useful-crates/aarch64-paging.md -msgid "// Map a 2 MiB region of memory as read-only." +msgid "// Map a 2 MiB region of memory as read-only.\n" msgstr "" #: src/bare-metal/useful-crates/aarch64-paging.md -msgid "// Set `TTBR0_EL1` to activate the page table." -msgstr "" - -#: src/bare-metal/useful-crates/aarch64-paging.md -msgid "" -"For now it only supports EL1, but support for other exception levels should " -"be straightforward to add." +msgid "// Set `TTBR0_EL1` to activate the page table.\n" msgstr "" #: src/bare-metal/useful-crates/aarch64-paging.md msgid "" "This is used in Android for the [Protected VM Firmware](https://cs.android." -"com/android/platform/superproject/+/master:packages/modules/Virtualization/" -"pvmfw/)." +"com/android/platform/superproject/main/+/main:packages/modules/" +"Virtualization/guest/pvmfw/)." msgstr "" #: src/bare-metal/useful-crates/aarch64-paging.md msgid "" -"There's no easy way to run this example, as it needs to run on real hardware " -"or under QEMU." +"There's no easy way to run this example by itself, as it needs to run on " +"real hardware or under QEMU." msgstr "" #: src/bare-metal/useful-crates/buddy_system_allocator.md msgid "" "[`buddy_system_allocator`](https://crates.io/crates/buddy_system_allocator) " -"is a third-party crate implementing a basic buddy system allocator. It can " -"be used both for [`LockedHeap`](https://docs.rs/buddy_system_allocator/0.9.0/" -"buddy_system_allocator/struct.LockedHeap.html) implementing [`GlobalAlloc`]" -"(https://doc.rust-lang.org/core/alloc/trait.GlobalAlloc.html) so you can use " -"the standard `alloc` crate (as we saw [before](../alloc.md)), or for " -"allocating other address space. For example, we might want to allocate MMIO " -"space for PCI BARs:" +"is a crate that implements a basic buddy system allocator. It can be used " +"both to implement [`GlobalAlloc`](https://doc.rust-lang.org/core/alloc/trait." +"GlobalAlloc.html) (using [`LockedHeap`](https://docs.rs/" +"buddy_system_allocator/0.9.0/buddy_system_allocator/struct.LockedHeap.html)) " +"so you can use the standard `alloc` crate (as we saw [before](../alloc.md)), " +"or for allocating other address space (using [`FrameAllocator`](https://docs." +"rs/buddy_system_allocator/0.9.0/buddy_system_allocator/struct.FrameAllocator." +"html)) . For example, we might want to allocate MMIO space for PCI BARs:" msgstr "" #: src/bare-metal/useful-crates/buddy_system_allocator.md @@ -16987,17 +19653,17 @@ msgstr "" #: src/bare-metal/useful-crates/tinyvec.md msgid "" -"Sometimes you want something which can be resized like a `Vec`, but without " +"Sometimes you want something that can be resized like a `Vec`, but without " "heap allocation. [`tinyvec`](https://crates.io/crates/tinyvec) provides " "this: a vector backed by an array or slice, which could be statically " -"allocated or on the stack, which keeps track of how many elements are used " +"allocated or on the stack, that keeps track of how many elements are used " "and panics if you try to use more than are allocated." msgstr "" #: src/bare-metal/useful-crates/tinyvec.md msgid "" "`tinyvec` requires that the element type implement `Default` for " -"initialisation." +"initialization." msgstr "" #: src/bare-metal/useful-crates/tinyvec.md @@ -17025,13 +19691,13 @@ msgstr "" #: src/bare-metal/useful-crates/spin.md msgid "" "`spin` also has a ticket lock mutex implementation; equivalents of `RwLock`, " -"`Barrier` and `Once` from `std::sync`; and `Lazy` for lazy initialisation." +"`Barrier` and `Once` from `std::sync`; and `Lazy` for lazy initialization." msgstr "" #: src/bare-metal/useful-crates/spin.md msgid "" "The [`once_cell`](https://crates.io/crates/once_cell) crate also has some " -"useful types for late initialisation with a slightly different approach to " +"useful types for late initialization with a slightly different approach to " "`spin::once::Once`." msgstr "" @@ -17050,14 +19716,14 @@ msgstr "" #: src/bare-metal/android/vmbase.md msgid "vmbase" -msgstr "vmbase" +msgstr "" #: src/bare-metal/android/vmbase.md msgid "" "For VMs running under crosvm on aarch64, the [vmbase](https://android." -"googlesource.com/platform/packages/modules/Virtualization/+/refs/heads/" -"master/vmbase/) library provides a linker script and useful defaults for the " -"build rules, along with an entry point, UART console logging and more." +"googlesource.com/platform/packages/modules/Virtualization/+/refs/heads/main/" +"libs/libvmbase/) library provides a linker script and useful defaults for " +"the build rules, along with an entry point, UART console logging and more." msgstr "" #: src/bare-metal/android/vmbase.md @@ -17076,7 +19742,7 @@ msgstr "" msgid "We will write a driver for the PL031 real-time clock device." msgstr "" -#: src/exercises/bare-metal/afternoon.md src/exercises/concurrency/afternoon.md +#: src/exercises/bare-metal/afternoon.md msgid "" "After looking at the exercises, you can look at the [solutions](solutions-" "afternoon.md) provided." @@ -17140,28 +19806,12 @@ msgstr "" msgid "_src/logger.rs_ (you shouldn't need to change this):" msgstr "" -#: src/exercises/bare-metal/rtc.md -msgid "_src/pl011.rs_ (you shouldn't need to change this):" -msgstr "" - #: src/exercises/bare-metal/rtc.md msgid "_build.rs_ (you shouldn't need to change this):" msgstr "" #: src/exercises/bare-metal/rtc.md -msgid "_entry.S_ (you shouldn't need to change this):" -msgstr "" - -#: src/exercises/bare-metal/rtc.md -msgid "_exceptions.S_ (you shouldn't need to change this):" -msgstr "" - -#: src/exercises/bare-metal/rtc.md -msgid "_idmap.S_ (you shouldn't need to change this):" -msgstr "" - -#: src/exercises/bare-metal/rtc.md -msgid "_image.ld_ (you shouldn't need to change this):" +msgid "_memory.ld_ (you shouldn't need to change this):" msgstr "" #: src/exercises/bare-metal/rtc.md @@ -17174,7 +19824,7 @@ msgstr "" #: src/exercises/bare-metal/solutions-afternoon.md msgid "Bare Metal Rust Afternoon" -msgstr "Bare Metal Rust: āĻŦāĻŋāĻ•āĻžāϞ" +msgstr "" #: src/exercises/bare-metal/solutions-afternoon.md msgid "([back to exercise](rtc.md))" @@ -17202,15 +19852,15 @@ msgstr "" #: src/exercises/bare-metal/solutions-afternoon.md msgid "" -"// Safe because `GICD_BASE_ADDRESS` and `GICR_BASE_ADDRESS` are the base\n" +"// SAFETY: `GICD_BASE_ADDRESS` and `GICR_BASE_ADDRESS` are the base\n" " // addresses of a GICv3 distributor and redistributor respectively, and\n" " // nothing else accesses those address ranges.\n" msgstr "" #: src/exercises/bare-metal/solutions-afternoon.md msgid "" -"// Safe because `PL031_BASE_ADDRESS` is the base address of a PL031 device,\n" -" // and nothing else accesses that address range.\n" +"// SAFETY: `PL031_BASE_ADDRESS` is the base address of a PL031 device, and\n" +" // nothing else accesses that address range.\n" msgstr "" #: src/exercises/bare-metal/solutions-afternoon.md @@ -17279,28 +19929,14 @@ msgstr "" #: src/exercises/bare-metal/solutions-afternoon.md msgid "" -"/// Constructs a new instance of the RTC driver for a PL031 device at the\n" -" /// given base address.\n" -" ///\n" -" /// # Safety\n" -" ///\n" -" /// The given base address must point to the MMIO control registers of " -"a\n" -" /// PL031 device, which must be mapped into the address space of the " -"process\n" -" /// as device memory and not have any other aliases.\n" +"/// Constructs a new instance of the RTC driver for a PL031 device with the\n" +" /// given set of registers.\n" msgstr "" #: src/exercises/bare-metal/solutions-afternoon.md msgid "/// Reads the current RTC value.\n" msgstr "" -#: src/exercises/bare-metal/solutions-afternoon.md -msgid "" -"// Safe because we know that self.registers points to the control\n" -" // registers of a PL031 device which is appropriately mapped.\n" -msgstr "" - #: src/exercises/bare-metal/solutions-afternoon.md msgid "" "/// Writes a match value. When the RTC value matches this then an interrupt\n" @@ -17335,117 +19971,251 @@ msgstr "" msgid "/// Clears a pending interrupt, if any.\n" msgstr "" -#: src/concurrency.md +#: src/concurrency/welcome.md msgid "Welcome to Concurrency in Rust" msgstr "" -#: src/concurrency.md +#: src/concurrency/welcome.md msgid "" "Rust has full support for concurrency using OS threads with mutexes and " "channels." msgstr "" -#: src/concurrency.md +#: src/concurrency/welcome.md msgid "" "The Rust type system plays an important role in making many concurrency bugs " -"compile time bugs. This is often referred to as _fearless concurrency_ since " -"you can rely on the compiler to ensure correctness at runtime." +"compile time errors. This idea is known as _fearless concurrency_ since you " +"can rely on the compiler to ensure correctness at runtime." msgstr "" -#: src/concurrency/threads.md +#: src/concurrency/welcome.md +msgid "" +"Including 10 minute breaks, this session should take about 3 hours and 20 " +"minutes. It contains:" +msgstr "" + +#: src/concurrency/welcome.md +msgid "" +"Rust lets us access OS concurrency toolkit: threads, sync. primitives, etc." +msgstr "" + +#: src/concurrency/welcome.md +msgid "" +"The type system gives us safety for concurrency without any special features." +msgstr "" + +#: src/concurrency/welcome.md +msgid "" +"The same tools that help with \"concurrent\" access in a single thread (e." +"g., a called function that might mutate an argument or save references to it " +"to read later) save us from multi-threading issues." +msgstr "" + +#: src/concurrency/threads/plain.md msgid "Rust threads work similarly to threads in other languages:" msgstr "" -#: src/concurrency/threads.md +#: src/concurrency/threads/plain.md msgid "\"Count in thread: {i}!\"" msgstr "" -#: src/concurrency/threads.md +#: src/concurrency/threads/plain.md msgid "\"Main thread: {i}\"" msgstr "" -#: src/concurrency/threads.md -msgid "Threads are all daemon threads, the main thread does not wait for them." +#: src/concurrency/threads/plain.md +msgid "" +"Spawning new threads does not automatically delay program termination at the " +"end of `main`." msgstr "" -#: src/concurrency/threads.md +#: src/concurrency/threads/plain.md msgid "Thread panics are independent of each other." msgstr "" -#: src/concurrency/threads.md -msgid "Panics can carry a payload, which can be unpacked with `downcast_ref`." -msgstr "" - -#: src/concurrency/threads.md +#: src/concurrency/threads/plain.md msgid "" -"Notice that the thread is stopped before it reaches 10 --- the main thread " -"is not waiting." +"Panics can carry a payload, which can be unpacked with [`Any::downcast_ref`]" +"(https://doc.rust-lang.org/std/any/trait.Any.html#method.downcast_ref)." msgstr "" -#: src/concurrency/threads.md +#: src/concurrency/threads/plain.md +msgid "Run the example." +msgstr "" + +#: src/concurrency/threads/plain.md +msgid "" +"5ms timing is loose enough that main and spawned threads stay mostly in " +"lockstep." +msgstr "" + +#: src/concurrency/threads/plain.md +msgid "Notice that the program ends before the spawned thread reaches 10!" +msgstr "" + +#: src/concurrency/threads/plain.md +msgid "" +"This is because `main` ends the program and spawned threads do not make it " +"persist." +msgstr "" + +#: src/concurrency/threads/plain.md +msgid "Compare to `pthreads`/C++ `std::thread`/`boost::thread` if desired." +msgstr "" + +#: src/concurrency/threads/plain.md +msgid "How do we wait around for the spawned thread to complete?" +msgstr "" + +#: src/concurrency/threads/plain.md +msgid "" +"[`thread::spawn`](https://doc.rust-lang.org/std/thread/fn.spawn.html) " +"returns a `JoinHandle`. Look at the docs." +msgstr "" + +#: src/concurrency/threads/plain.md +msgid "" +"`JoinHandle` has a [`.join()`](https://doc.rust-lang.org/std/thread/struct." +"JoinHandle.html#method.join) method that blocks." +msgstr "" + +#: src/concurrency/threads/plain.md msgid "" "Use `let handle = thread::spawn(...)` and later `handle.join()` to wait for " -"the thread to finish." +"the thread to finish and have the program count all the way to 10." msgstr "" -#: src/concurrency/threads.md -msgid "Trigger a panic in the thread, notice how this doesn't affect `main`." +#: src/concurrency/threads/plain.md +msgid "Now what if we want to return a value?" msgstr "" -#: src/concurrency/threads.md +#: src/concurrency/threads/plain.md +msgid "Look at docs again:" +msgstr "" + +#: src/concurrency/threads/plain.md +msgid "" +"[`thread::spawn`](https://doc.rust-lang.org/std/thread/fn.spawn.html)'s " +"closure returns `T`" +msgstr "" + +#: src/concurrency/threads/plain.md +msgid "" +"`JoinHandle` [`.join()`](https://doc.rust-lang.org/std/thread/struct." +"JoinHandle.html#method.join) returns `thread::Result`" +msgstr "" + +#: src/concurrency/threads/plain.md msgid "" "Use the `Result` return value from `handle.join()` to get access to the " -"panic payload. This is a good time to talk about [`Any`](https://doc.rust-" -"lang.org/std/any/index.html)." +"returned value." msgstr "" -#: src/concurrency/scoped-threads.md +#: src/concurrency/threads/plain.md +msgid "Ok, what about the other case?" +msgstr "" + +#: src/concurrency/threads/plain.md +msgid "Trigger a panic in the thread. Note that this doesn't panic `main`." +msgstr "" + +#: src/concurrency/threads/plain.md +msgid "" +"Access the panic payload. This is a good time to talk about [`Any`](https://" +"doc.rust-lang.org/std/any/index.html)." +msgstr "" + +#: src/concurrency/threads/plain.md +msgid "Now we can return values from threads! What about taking inputs?" +msgstr "" + +#: src/concurrency/threads/plain.md +msgid "Capture something by reference in the thread closure." +msgstr "" + +#: src/concurrency/threads/plain.md +msgid "An error message indicates we must move it." +msgstr "" + +#: src/concurrency/threads/plain.md +msgid "Move it in, see we can compute and then return a derived value." +msgstr "" + +#: src/concurrency/threads/plain.md +msgid "If we want to borrow?" +msgstr "" + +#: src/concurrency/threads/plain.md +msgid "" +"Main kills child threads when it returns, but another function would just " +"return and leave them running." +msgstr "" + +#: src/concurrency/threads/plain.md +msgid "That would be stack use-after-return, which violates memory safety!" +msgstr "" + +#: src/concurrency/threads/plain.md +msgid "How do we avoid this? See next slide." +msgstr "" + +#: src/concurrency/threads/scoped.md msgid "Normal threads cannot borrow from their environment:" msgstr "" -#: src/concurrency/scoped-threads.md +#: src/concurrency/threads/scoped.md msgid "" "However, you can use a [scoped thread](https://doc.rust-lang.org/std/thread/" "fn.scope.html) for this:" msgstr "" -#: src/concurrency/scoped-threads.md +#: src/concurrency/threads/scoped.md msgid "" "The reason for that is that when the `thread::scope` function completes, all " "the threads are guaranteed to be joined, so they can return borrowed data." msgstr "" -#: src/concurrency/scoped-threads.md +#: src/concurrency/threads/scoped.md msgid "" "Normal Rust borrowing rules apply: you can either borrow mutably by one " "thread, or immutably by any number of threads." msgstr "" -#: src/concurrency/channels.md -msgid "" -"Rust channels have two parts: a `Sender` and a `Receiver`. The two " -"parts are connected via the channel, but you only see the end-points." +#: src/concurrency/channels.md src/concurrency/async-control-flow.md +msgid "This segment should take about 20 minutes. It contains:" msgstr "" -#: src/concurrency/channels.md +#: src/concurrency/channels/senders-receivers.md +msgid "" +"Rust channels have two parts: a [`Sender`](https://doc.rust-lang.org/std/" +"sync/mpsc/struct.Sender.html) and a [`Receiver`](https://doc.rust-lang." +"org/std/sync/mpsc/struct.Receiver.html). The two parts are connected via the " +"channel, but you only see the end-points." +msgstr "" + +#: src/concurrency/channels/senders-receivers.md msgid "\"Received: {:?}\"" msgstr "" -#: src/concurrency/channels.md +#: src/concurrency/channels/senders-receivers.md msgid "" -"`mpsc` stands for Multi-Producer, Single-Consumer. `Sender` and `SyncSender` " -"implement `Clone` (so you can make multiple producers) but `Receiver` does " -"not." +"[`mpsc`](https://doc.rust-lang.org/std/sync/mpsc/index.html) stands for " +"Multi-Producer, Single-Consumer. `Sender` and `SyncSender` implement `Clone` " +"(so you can make multiple producers) but `Receiver` does not." msgstr "" -#: src/concurrency/channels.md +#: src/concurrency/channels/senders-receivers.md msgid "" -"`send()` and `recv()` return `Result`. If they return `Err`, it means the " +"[`send()`](https://doc.rust-lang.org/std/sync/mpsc/struct.Sender.html#method." +"send) and [`recv()`](https://doc.rust-lang.org/std/sync/mpsc/struct.Receiver." +"html#method.recv) return `Result`. If they return `Err`, it means the " "counterpart `Sender` or `Receiver` is dropped and the channel is closed." msgstr "" #: src/concurrency/channels/unbounded.md -msgid "You get an unbounded and asynchronous channel with `mpsc::channel()`:" +msgid "" +"You get an unbounded and asynchronous channel with [`mpsc::channel()`]" +"(https://doc.rust-lang.org/std/sync/mpsc/fn.channel.html):" msgstr "" #: src/concurrency/channels/unbounded.md src/concurrency/channels/bounded.md @@ -17464,63 +20234,88 @@ msgstr "" msgid "\"Main: got {msg}\"" msgstr "" -#: src/concurrency/channels/bounded.md +#: src/concurrency/channels/unbounded.md msgid "" -"With bounded (synchronous) channels, `send` can block the current thread:" +"An unbounded channel will allocate as much space as is necessary to store " +"pending messages. The `send()` method will not block the calling thread." +msgstr "" + +#: src/concurrency/channels/unbounded.md +msgid "" +"A call to `send()` will abort with an error (that is why it returns " +"`Result`) if the channel is closed. A channel is closed when the receiver is " +"dropped." msgstr "" #: src/concurrency/channels/bounded.md msgid "" -"Calling `send` will block the current thread until there is space in the " +"With bounded (synchronous) channels, [`send()`](https://doc.rust-lang.org/" +"std/sync/mpsc/struct.SyncSender.html#method.send) can block the current " +"thread:" +msgstr "" + +#: src/concurrency/channels/bounded.md +msgid "" +"Calling `send()` will block the current thread until there is space in the " "channel for the new message. The thread can be blocked indefinitely if there " "is nobody who reads from the channel." msgstr "" #: src/concurrency/channels/bounded.md msgid "" -"A call to `send` will abort with an error (that is why it returns `Result`) " -"if the channel is closed. A channel is closed when the receiver is dropped." +"Like unbounded channels, a call to `send()` will abort with an error if the " +"channel is closed." msgstr "" #: src/concurrency/channels/bounded.md msgid "" "A bounded channel with a size of zero is called a \"rendezvous channel\". " -"Every send will block the current thread until another thread calls `read`." +"Every send will block the current thread until another thread calls " +"[`recv()`](https://doc.rust-lang.org/std/sync/mpsc/struct.Receiver." +"html#method.recv)." msgstr "" #: src/concurrency/send-sync.md +msgid "Send" +msgstr "" + +#: src/concurrency/send-sync.md +msgid "Sync" +msgstr "" + +#: src/concurrency/send-sync/marker-traits.md msgid "" "How does Rust know to forbid shared access across threads? The answer is in " "two traits:" msgstr "" -#: src/concurrency/send-sync.md +#: src/concurrency/send-sync/marker-traits.md msgid "" "[`Send`](https://doc.rust-lang.org/std/marker/trait.Send.html): a type `T` " "is `Send` if it is safe to move a `T` across a thread boundary." msgstr "" -#: src/concurrency/send-sync.md +#: src/concurrency/send-sync/marker-traits.md msgid "" "[`Sync`](https://doc.rust-lang.org/std/marker/trait.Sync.html): a type `T` " "is `Sync` if it is safe to move a `&T` across a thread boundary." msgstr "" -#: src/concurrency/send-sync.md +#: src/concurrency/send-sync/marker-traits.md msgid "" -"`Send` and `Sync` are [unsafe traits](../unsafe/unsafe-traits.md). The " -"compiler will automatically derive them for your types as long as they only " -"contain `Send` and `Sync` types. You can also implement them manually when " -"you know it is valid." +"`Send` and `Sync` are [unsafe traits](../../unsafe-rust/unsafe-traits.md). " +"The compiler will automatically derive them for your types as long as they " +"only contain `Send` and `Sync` types. You can also implement them manually " +"when you know it is valid." msgstr "" -#: src/concurrency/send-sync.md +#: src/concurrency/send-sync/marker-traits.md msgid "" "One can think of these traits as markers that the type has certain thread-" "safety properties." msgstr "" -#: src/concurrency/send-sync.md +#: src/concurrency/send-sync/marker-traits.md msgid "They can be used in the generic constraints as normal traits." msgstr "" @@ -17601,6 +20396,10 @@ msgstr "" msgid "`Mutex`: Explicitly thread-safe via internal locking." msgstr "" +#: src/concurrency/send-sync/examples.md +msgid "`mpsc::Sender`: As of 1.72.0." +msgstr "" + #: src/concurrency/send-sync/examples.md msgid "`AtomicBool`, `AtomicU8`, ...: Uses special atomic instructions." msgstr "" @@ -17621,10 +20420,6 @@ msgid "" "Typically because of interior mutability:" msgstr "" -#: src/concurrency/send-sync/examples.md -msgid "`mpsc::Sender`" -msgstr "" - #: src/concurrency/send-sync/examples.md msgid "`mpsc::Receiver`" msgstr "" @@ -17643,13 +20438,16 @@ msgstr "" #: src/concurrency/send-sync/examples.md msgid "" -"These types are thread-safe, but they cannot be moved to another thread:" +"These types are safe to access (via shared references) from multiple " +"threads, but they cannot be moved to another thread:" msgstr "" #: src/concurrency/send-sync/examples.md msgid "" -"`MutexGuard`: Uses OS level primitives which must be deallocated on " -"the thread which created them." +"`MutexGuard`: Uses OS level primitives which must be deallocated on the " +"thread which created them. However, an already-locked mutex can have its " +"guarded variable read by any thread with which the guard is shared (unless " +"`T` itself is `!Sync`)." msgstr "" #: src/concurrency/send-sync/examples.md @@ -17672,119 +20470,121 @@ msgid "" "considerations." msgstr "" -#: src/concurrency/shared_state.md -msgid "" -"Rust uses the type system to enforce synchronization of shared data. This is " -"primarily done via two types:" +#: src/concurrency/shared-state.md +msgid "Arc" msgstr "" -#: src/concurrency/shared_state.md +#: src/concurrency/shared-state/arc.md msgid "" -"[`Arc`](https://doc.rust-lang.org/std/sync/struct.Arc.html), atomic " -"reference counted `T`: handles sharing between threads and takes care to " -"deallocate `T` when the last reference is dropped," +"[`Arc`](https://doc.rust-lang.org/std/sync/struct.Arc.html) allows " +"shared, read-only ownership via `Arc::clone`:" msgstr "" -#: src/concurrency/shared_state.md -msgid "" -"[`Mutex`](https://doc.rust-lang.org/std/sync/struct.Mutex.html): ensures " -"mutually exclusive access to the `T` value." +#: src/concurrency/shared-state/arc.md +msgid "/// A struct that prints which thread drops it.\n" msgstr "" -#: src/concurrency/shared_state/arc.md -msgid "" -"[`Arc`](https://doc.rust-lang.org/std/sync/struct.Arc.html) allows shared " -"read-only access via `Arc::clone`:" +#: src/concurrency/shared-state/arc.md +msgid "\"Dropped by {:?}\"" msgstr "" -#: src/concurrency/shared_state/arc.md +#: src/concurrency/shared-state/arc.md +msgid "// Sleep for 0-500ms.\n" +msgstr "" + +#: src/concurrency/shared-state/arc.md msgid "\"{thread_id:?}: {v:?}\"" msgstr "" -#: src/concurrency/shared_state/arc.md src/concurrency/shared_state/example.md -msgid "\"v: {v:?}\"" +#: src/concurrency/shared-state/arc.md +msgid "// Now only the spawned threads will hold clones of `v`.\n" msgstr "" -#: src/concurrency/shared_state/arc.md +#: src/concurrency/shared-state/arc.md +msgid "" +"// When the last spawned thread finishes, it will drop `v`'s contents.\n" +msgstr "" + +#: src/concurrency/shared-state/arc.md msgid "" "`Arc` stands for \"Atomic Reference Counted\", a thread safe version of `Rc` " "that uses atomic operations." msgstr "" -#: src/concurrency/shared_state/arc.md +#: src/concurrency/shared-state/arc.md msgid "" "`Arc` implements `Clone` whether or not `T` does. It implements `Send` " "and `Sync` if and only if `T` implements them both." msgstr "" -#: src/concurrency/shared_state/arc.md +#: src/concurrency/shared-state/arc.md msgid "" "`Arc::clone()` has the cost of atomic operations that get executed, but " "after that the use of the `T` is free." msgstr "" -#: src/concurrency/shared_state/arc.md +#: src/concurrency/shared-state/arc.md msgid "" "Beware of reference cycles, `Arc` does not use a garbage collector to detect " "them." msgstr "" -#: src/concurrency/shared_state/arc.md +#: src/concurrency/shared-state/arc.md msgid "`std::sync::Weak` can help." msgstr "" -#: src/concurrency/shared_state/mutex.md +#: src/concurrency/shared-state/mutex.md msgid "" "[`Mutex`](https://doc.rust-lang.org/std/sync/struct.Mutex.html) ensures " "mutual exclusion _and_ allows mutable access to `T` behind a read-only " "interface (another form of [interior mutability](../../borrowing/interior-" -"mutability)):" +"mutability.md)):" msgstr "" -#: src/concurrency/shared_state/mutex.md +#: src/concurrency/shared-state/mutex.md msgid "\"v: {:?}\"" msgstr "" -#: src/concurrency/shared_state/mutex.md +#: src/concurrency/shared-state/mutex.md msgid "" "Notice how we have a [`impl Sync for Mutex`](https://doc.rust-" "lang.org/std/sync/struct.Mutex.html#impl-Sync-for-Mutex%3CT%3E) blanket " "implementation." msgstr "" -#: src/concurrency/shared_state/mutex.md +#: src/concurrency/shared-state/mutex.md msgid "" "`Mutex` in Rust looks like a collection with just one element --- the " "protected data." msgstr "" -#: src/concurrency/shared_state/mutex.md +#: src/concurrency/shared-state/mutex.md msgid "" "It is not possible to forget to acquire the mutex before accessing the " "protected data." msgstr "" -#: src/concurrency/shared_state/mutex.md +#: src/concurrency/shared-state/mutex.md msgid "" "You can get an `&mut T` from an `&Mutex` by taking the lock. The " "`MutexGuard` ensures that the `&mut T` doesn't outlive the lock being held." msgstr "" -#: src/concurrency/shared_state/mutex.md +#: src/concurrency/shared-state/mutex.md msgid "" -"`Mutex` implements both `Send` and `Sync` iff (if and only if) `T` " -"implements `Send`." +"`Mutex` implements both `Send` and `Sync` if and only if `T` implements " +"`Send`." msgstr "" -#: src/concurrency/shared_state/mutex.md +#: src/concurrency/shared-state/mutex.md msgid "A read-write lock counterpart: `RwLock`." msgstr "" -#: src/concurrency/shared_state/mutex.md +#: src/concurrency/shared-state/mutex.md msgid "Why does `lock()` return a `Result`?" msgstr "" -#: src/concurrency/shared_state/mutex.md +#: src/concurrency/shared-state/mutex.md msgid "" "If the thread that held the `Mutex` panicked, the `Mutex` becomes " "\"poisoned\" to signal that the data it protected might be in an " @@ -17793,185 +20593,182 @@ msgid "" "You can call `into_inner()` on the error to recover the data regardless." msgstr "" -#: src/concurrency/shared_state/example.md +#: src/concurrency/shared-state/example.md msgid "Let us see `Arc` and `Mutex` in action:" msgstr "" -#: src/concurrency/shared_state/example.md -msgid "// use std::sync::{Arc, Mutex};" +#: src/concurrency/shared-state/example.md +msgid "// use std::sync::{Arc, Mutex};\n" msgstr "" -#: src/concurrency/shared_state/example.md +#: src/concurrency/shared-state/example.md +msgid "\"v: {v:?}\"" +msgstr "" + +#: src/concurrency/shared-state/example.md msgid "Possible solution:" msgstr "" -#: src/concurrency/shared_state/example.md +#: src/concurrency/shared-state/example.md msgid "Notable parts:" msgstr "" -#: src/concurrency/shared_state/example.md +#: src/concurrency/shared-state/example.md msgid "" "`v` is wrapped in both `Arc` and `Mutex`, because their concerns are " "orthogonal." msgstr "" -#: src/concurrency/shared_state/example.md +#: src/concurrency/shared-state/example.md msgid "" "Wrapping a `Mutex` in an `Arc` is a common pattern to share mutable state " "between threads." msgstr "" -#: src/concurrency/shared_state/example.md +#: src/concurrency/shared-state/example.md msgid "" -"`v: Arc<_>` needs to be cloned as `v2` before it can be moved into another " +"`v: Arc<_>` needs to be cloned to make a new reference for each new spawned " "thread. Note `move` was added to the lambda signature." msgstr "" -#: src/concurrency/shared_state/example.md +#: src/concurrency/shared-state/example.md msgid "" "Blocks are introduced to narrow the scope of the `LockGuard` as much as " "possible." msgstr "" -#: src/exercises/concurrency/morning.md -msgid "Let us practice our new concurrency skills with" +#: src/concurrency/sync-exercises.md src/concurrency/async-exercises.md +#: src/unsafe-deep-dive/introduction.md +msgid "This segment should take about 1 hour and 10 minutes. It contains:" msgstr "" -#: src/exercises/concurrency/morning.md -msgid "Dining philosophers: a classic problem in concurrency." -msgstr "" - -#: src/exercises/concurrency/morning.md -msgid "" -"Multi-threaded link checker: a larger project where you'll use Cargo to " -"download dependencies and then check links in parallel." -msgstr "" - -#: src/exercises/concurrency/dining-philosophers.md +#: src/concurrency/sync-exercises/dining-philosophers.md msgid "The dining philosophers problem is a classic problem in concurrency:" msgstr "" -#: src/exercises/concurrency/dining-philosophers.md +#: src/concurrency/sync-exercises/dining-philosophers.md msgid "" "Five philosophers dine together at the same table. Each philosopher has " -"their own place at the table. There is a fork between each plate. The dish " -"served is a kind of spaghetti which has to be eaten with two forks. Each " +"their own place at the table. There is a chopstick between each plate. The " +"dish served is spaghetti which requires two chopsticks to eat. Each " "philosopher can only alternately think and eat. Moreover, a philosopher can " -"only eat their spaghetti when they have both a left and right fork. Thus two " -"forks will only be available when their two nearest neighbors are thinking, " -"not eating. After an individual philosopher finishes eating, they will put " -"down both forks." +"only eat their spaghetti when they have both a left and right chopstick. " +"Thus two chopsticks will only be available when their two nearest neighbors " +"are thinking, not eating. After an individual philosopher finishes eating, " +"they will put down both chopsticks." msgstr "" -#: src/exercises/concurrency/dining-philosophers.md +#: src/concurrency/sync-exercises/dining-philosophers.md msgid "" "You will need a local [Cargo installation](../../cargo/running-locally.md) " "for this exercise. Copy the code below to a file called `src/main.rs`, fill " "out the blanks, and test that `cargo run` does not deadlock:" msgstr "" -#: src/exercises/concurrency/dining-philosophers.md -#: src/exercises/concurrency/dining-philosophers-async.md -msgid "// left_fork: ..." +#: src/concurrency/sync-exercises/dining-philosophers.md +#: src/concurrency/async-exercises/dining-philosophers.md +msgid "" +"// left_chopstick: ...\n" +" // right_chopstick: ...\n" +" // thoughts: ...\n" msgstr "" -#: src/exercises/concurrency/dining-philosophers.md -#: src/exercises/concurrency/dining-philosophers-async.md -msgid "// right_fork: ..." -msgstr "" - -#: src/exercises/concurrency/dining-philosophers.md -#: src/exercises/concurrency/dining-philosophers-async.md -msgid "// thoughts: ..." -msgstr "" - -#: src/exercises/concurrency/dining-philosophers.md -#: src/exercises/concurrency/solutions-morning.md -#: src/exercises/concurrency/dining-philosophers-async.md -#: src/exercises/concurrency/solutions-afternoon.md +#: src/concurrency/sync-exercises/dining-philosophers.md +#: src/concurrency/sync-exercises/solutions.md +#: src/concurrency/async-exercises/dining-philosophers.md +#: src/concurrency/async-exercises/solutions.md msgid "\"Eureka! {} has a new idea!\"" msgstr "" -#: src/exercises/concurrency/dining-philosophers.md -msgid "// Pick up forks..." +#: src/concurrency/sync-exercises/dining-philosophers.md +msgid "// Pick up chopsticks...\n" msgstr "" -#: src/exercises/concurrency/dining-philosophers.md -#: src/exercises/concurrency/solutions-morning.md -#: src/exercises/concurrency/dining-philosophers-async.md -#: src/exercises/concurrency/solutions-afternoon.md +#: src/concurrency/sync-exercises/dining-philosophers.md +#: src/concurrency/sync-exercises/solutions.md +#: src/concurrency/async-exercises/dining-philosophers.md +#: src/concurrency/async-exercises/solutions.md msgid "\"{} is eating...\"" msgstr "" -#: src/exercises/concurrency/dining-philosophers.md -#: src/exercises/concurrency/solutions-morning.md -#: src/exercises/concurrency/dining-philosophers-async.md -#: src/exercises/concurrency/solutions-afternoon.md +#: src/concurrency/sync-exercises/dining-philosophers.md +#: src/concurrency/sync-exercises/solutions.md +#: src/concurrency/async-exercises/dining-philosophers.md +#: src/concurrency/async-exercises/solutions.md msgid "\"Socrates\"" msgstr "" -#: src/exercises/concurrency/dining-philosophers.md -#: src/exercises/concurrency/solutions-morning.md -#: src/exercises/concurrency/dining-philosophers-async.md -#: src/exercises/concurrency/solutions-afternoon.md +#: src/concurrency/sync-exercises/dining-philosophers.md +#: src/concurrency/sync-exercises/solutions.md +#: src/concurrency/async-exercises/dining-philosophers.md +#: src/concurrency/async-exercises/solutions.md msgid "\"Hypatia\"" msgstr "" -#: src/exercises/concurrency/dining-philosophers.md -#: src/exercises/concurrency/solutions-morning.md -#: src/exercises/concurrency/dining-philosophers-async.md -#: src/exercises/concurrency/solutions-afternoon.md +#: src/concurrency/sync-exercises/dining-philosophers.md +#: src/concurrency/sync-exercises/solutions.md msgid "\"Plato\"" msgstr "" -#: src/exercises/concurrency/dining-philosophers.md -#: src/exercises/concurrency/solutions-morning.md -#: src/exercises/concurrency/dining-philosophers-async.md -#: src/exercises/concurrency/solutions-afternoon.md +#: src/concurrency/sync-exercises/dining-philosophers.md +#: src/concurrency/sync-exercises/solutions.md msgid "\"Aristotle\"" msgstr "" -#: src/exercises/concurrency/dining-philosophers.md -#: src/exercises/concurrency/solutions-morning.md -#: src/exercises/concurrency/dining-philosophers-async.md -#: src/exercises/concurrency/solutions-afternoon.md +#: src/concurrency/sync-exercises/dining-philosophers.md +#: src/concurrency/sync-exercises/solutions.md msgid "\"Pythagoras\"" msgstr "" -#: src/exercises/concurrency/dining-philosophers.md -#: src/exercises/concurrency/dining-philosophers-async.md -msgid "// Create forks" +#: src/concurrency/sync-exercises/dining-philosophers.md +#: src/concurrency/async-exercises/dining-philosophers.md +#: src/concurrency/async-exercises/solutions.md +msgid "// Create chopsticks\n" msgstr "" -#: src/exercises/concurrency/dining-philosophers.md -#: src/exercises/concurrency/dining-philosophers-async.md -msgid "// Create philosophers" +#: src/concurrency/sync-exercises/dining-philosophers.md +#: src/concurrency/async-exercises/dining-philosophers.md +#: src/concurrency/async-exercises/solutions.md +msgid "// Create philosophers\n" msgstr "" -#: src/exercises/concurrency/dining-philosophers.md -msgid "// Make each of them think and eat 100 times" +#: src/concurrency/sync-exercises/dining-philosophers.md +msgid "// Make each of them think and eat 100 times\n" msgstr "" -#: src/exercises/concurrency/dining-philosophers.md -#: src/exercises/concurrency/dining-philosophers-async.md -msgid "// Output their thoughts" +#: src/concurrency/sync-exercises/dining-philosophers.md +#: src/concurrency/async-exercises/dining-philosophers.md +#: src/concurrency/async-exercises/solutions.md +msgid "// Output their thoughts\n" msgstr "" -#: src/exercises/concurrency/dining-philosophers.md +#: src/concurrency/sync-exercises/dining-philosophers.md msgid "You can use the following `Cargo.toml`:" msgstr "" -#: src/exercises/concurrency/dining-philosophers.md +#: src/concurrency/sync-exercises/dining-philosophers.md msgid "" "```toml\n" "[package]\n" "name = \"dining-philosophers\"\n" "version = \"0.1.0\"\n" -"edition = \"2021\"\n" +"edition = \"2024\"\n" "```" msgstr "" -#: src/exercises/concurrency/link-checker.md +#: src/concurrency/sync-exercises/dining-philosophers.md +msgid "" +"Encourage students to focus first on implementing a solution that \"mostly\" " +"works." +msgstr "" + +#: src/concurrency/sync-exercises/dining-philosophers.md +msgid "" +"The deadlock in the simplest solution is a general concurrency problem and " +"highlights that Rust does not automatically prevent this sort of bug." +msgstr "" + +#: src/concurrency/sync-exercises/link-checker.md msgid "" "Let us use our new knowledge to create a multi-threaded link checker. It " "should start at a webpage and check that links on the page are valid. It " @@ -17979,177 +20776,165 @@ msgid "" "until all pages have been validated." msgstr "" -#: src/exercises/concurrency/link-checker.md +#: src/concurrency/sync-exercises/link-checker.md msgid "" "For this, you will need an HTTP client such as [`reqwest`](https://docs.rs/" -"reqwest/). Create a new Cargo project and `reqwest` it as a dependency with:" +"reqwest/). You will also need a way to find links, we can use [`scraper`]" +"(https://docs.rs/scraper/). Finally, we'll need some way of handling errors, " +"we will use [`thiserror`](https://docs.rs/thiserror/)." msgstr "" -#: src/exercises/concurrency/link-checker.md +#: src/concurrency/sync-exercises/link-checker.md +msgid "Create a new Cargo project and `reqwest` it as a dependency with:" +msgstr "" + +#: src/concurrency/sync-exercises/link-checker.md msgid "" "If `cargo add` fails with `error: no such subcommand`, then please edit the " "`Cargo.toml` file by hand. Add the dependencies listed below." msgstr "" -#: src/exercises/concurrency/link-checker.md -msgid "" -"You will also need a way to find links. We can use [`scraper`](https://docs." -"rs/scraper/) for that:" -msgstr "" - -#: src/exercises/concurrency/link-checker.md -msgid "" -"Finally, we'll need some way of handling errors. We use [`thiserror`]" -"(https://docs.rs/thiserror/) for that:" -msgstr "" - -#: src/exercises/concurrency/link-checker.md +#: src/concurrency/sync-exercises/link-checker.md msgid "" "The `cargo add` calls will update the `Cargo.toml` file to look like this:" msgstr "" -#: src/exercises/concurrency/link-checker.md +#: src/concurrency/sync-exercises/link-checker.md msgid "" "```toml\n" "[package]\n" "name = \"link-checker\"\n" "version = \"0.1.0\"\n" -"edition = \"2021\"\n" +"edition = \"2024\"\n" "publish = false\n" "\n" "[dependencies]\n" -"reqwest = { version = \"0.11.12\", features = [\"blocking\", \"rustls-" -"tls\"] }\n" -"scraper = \"0.13.0\"\n" -"thiserror = \"1.0.37\"\n" +"reqwest = { version = \"0.13.1\", features = [\"blocking\"] }\n" +"scraper = \"0.25.0\"\n" +"thiserror = \"2.0.18\"\n" "```" msgstr "" -#: src/exercises/concurrency/link-checker.md +#: src/concurrency/sync-exercises/link-checker.md msgid "" "You can now download the start page. Try with a small site such as `https://" "www.google.org/`." msgstr "" -#: src/exercises/concurrency/link-checker.md +#: src/concurrency/sync-exercises/link-checker.md msgid "Your `src/main.rs` file should look something like this:" msgstr "" -#: src/exercises/concurrency/link-checker.md -#: src/exercises/concurrency/solutions-morning.md +#: src/concurrency/sync-exercises/link-checker.md +#: src/concurrency/sync-exercises/solutions.md msgid "\"request error: {0}\"" msgstr "" -#: src/exercises/concurrency/link-checker.md -#: src/exercises/concurrency/solutions-morning.md +#: src/concurrency/sync-exercises/link-checker.md +#: src/concurrency/sync-exercises/solutions.md msgid "\"bad http response: {0}\"" msgstr "" -#: src/exercises/concurrency/link-checker.md -#: src/exercises/concurrency/solutions-morning.md +#: src/concurrency/sync-exercises/link-checker.md +#: src/concurrency/sync-exercises/solutions.md msgid "\"Checking {:#}\"" msgstr "" -#: src/exercises/concurrency/link-checker.md -#: src/exercises/concurrency/solutions-morning.md +#: src/concurrency/sync-exercises/link-checker.md +#: src/concurrency/sync-exercises/solutions.md msgid "\"href\"" msgstr "" -#: src/exercises/concurrency/link-checker.md -#: src/exercises/concurrency/solutions-morning.md +#: src/concurrency/sync-exercises/link-checker.md +#: src/concurrency/sync-exercises/solutions.md msgid "\"On {base_url:#}: ignored unparsable {href:?}: {err}\"" msgstr "" -#: src/exercises/concurrency/link-checker.md -#: src/exercises/concurrency/solutions-morning.md +#: src/concurrency/sync-exercises/link-checker.md +#: src/concurrency/sync-exercises/solutions.md msgid "\"https://www.google.org\"" msgstr "" -#: src/exercises/concurrency/link-checker.md +#: src/concurrency/sync-exercises/link-checker.md msgid "\"Links: {links:#?}\"" msgstr "" -#: src/exercises/concurrency/link-checker.md +#: src/concurrency/sync-exercises/link-checker.md msgid "\"Could not extract links: {err:#}\"" msgstr "" -#: src/exercises/concurrency/link-checker.md +#: src/concurrency/sync-exercises/link-checker.md msgid "Run the code in `src/main.rs` with" msgstr "" -#: src/exercises/concurrency/link-checker.md +#: src/concurrency/sync-exercises/link-checker.md msgid "" "Use threads to check the links in parallel: send the URLs to be checked to a " "channel and let a few threads check the URLs in parallel." msgstr "" -#: src/exercises/concurrency/link-checker.md +#: src/concurrency/sync-exercises/link-checker.md msgid "" "Extend this to recursively extract links from all pages on the `www.google." "org` domain. Put an upper limit of 100 pages or so so that you don't end up " "being blocked by the site." msgstr "" -#: src/exercises/concurrency/solutions-morning.md -msgid "Concurrency Morning Exercise" +#: src/concurrency/sync-exercises/link-checker.md +msgid "" +"This is a complex exercise and intended to give students an opportunity to " +"work on a larger project than others. A success condition for this exercise " +"is to get stuck on some \"real\" issue and work through it with the support " +"of other students or the instructor." msgstr "" -#: src/exercises/concurrency/solutions-morning.md -msgid "([back to exercise](dining-philosophers.md))" -msgstr "" - -#: src/exercises/concurrency/solutions-morning.md +#: src/concurrency/sync-exercises/solutions.md msgid "\"{} is trying to eat\"" msgstr "" -#: src/exercises/concurrency/solutions-morning.md +#: src/concurrency/sync-exercises/solutions.md msgid "" "// To avoid a deadlock, we have to break the symmetry\n" -" // somewhere. This will swap the forks without deinitializing\n" +" // somewhere. This will swap the chopsticks without deinitializing\n" " // either of them.\n" msgstr "" -#: src/exercises/concurrency/solutions-morning.md +#: src/concurrency/sync-exercises/solutions.md msgid "\"{thought}\"" msgstr "" -#: src/exercises/concurrency/solutions-morning.md -#, fuzzy +#: src/concurrency/sync-exercises/solutions.md msgid "Link Checker" -msgstr "āĻŽāĻžāĻ˛ā§āϟāĻŋ āĻĨā§āϰ⧇āĻĄā§‡āĻĄ āϞāĻŋāĻ™ā§āĻ• āĻšā§‡āĻ•āĻžāϰ" - -#: src/exercises/concurrency/solutions-morning.md -msgid "([back to exercise](link-checker.md))" msgstr "" -#: src/exercises/concurrency/solutions-morning.md +#: src/concurrency/sync-exercises/solutions.md msgid "" "/// Determine whether links within the given page should be extracted.\n" msgstr "" -#: src/exercises/concurrency/solutions-morning.md +#: src/concurrency/sync-exercises/solutions.md msgid "" "/// Mark the given page as visited, returning false if it had already\n" " /// been visited.\n" msgstr "" -#: src/exercises/concurrency/solutions-morning.md +#: src/concurrency/sync-exercises/solutions.md +msgid "// To multiplex the non-cloneable Receiver, wrap it in Arc>.\n" +msgstr "" + +#: src/concurrency/sync-exercises/solutions.md msgid "// The sender got dropped. No more commands coming in.\n" msgstr "" -#: src/exercises/concurrency/solutions-morning.md +#: src/concurrency/sync-exercises/solutions.md msgid "\"Got crawling error: {:#}\"" msgstr "" -#: src/exercises/concurrency/solutions-morning.md +#: src/concurrency/sync-exercises/solutions.md msgid "\"Bad URLs: {:#?}\"" msgstr "" -#: src/async.md -msgid "Async Rust" -msgstr "" - -#: src/async.md +#: src/concurrency/welcome-async.md msgid "" "\"Async\" is a concurrency model where multiple tasks are executed " "concurrently by executing each task until it would block, then switching to " @@ -18159,88 +20944,90 @@ msgid "" "primitives for efficiently identifying I/O that is able to proceed." msgstr "" -#: src/async.md +#: src/concurrency/welcome-async.md msgid "" "Rust's asynchronous operation is based on \"futures\", which represent work " "that may be completed in the future. Futures are \"polled\" until they " "signal that they are complete." msgstr "" -#: src/async.md +#: src/concurrency/welcome-async.md msgid "" "Futures are polled by an async runtime, and several different runtimes are " "available." msgstr "" -#: src/async.md +#: src/concurrency/welcome-async.md msgid "" "Python has a similar model in its `asyncio`. However, its `Future` type is " "callback-based, and not polled. Async Python programs require a \"loop\", " "similar to a runtime in Rust." msgstr "" -#: src/async.md +#: src/concurrency/welcome-async.md msgid "" "JavaScript's `Promise` is similar, but again callback-based. The language " -"runtime implements the event loop, so many of the details of Promise " +"runtime implements the event loop, so the majority of the details of Promise " "resolution are hidden." msgstr "" -#: src/async/async-await.md +#: src/concurrency/welcome-async.md +msgid "" +"Including 10 minute breaks, this session should take about 3 hours and 30 " +"minutes. It contains:" +msgstr "" + +#: src/concurrency/async.md +msgid "async/await" +msgstr "" + +#: src/concurrency/async/async-await.md msgid "" "At a high level, async Rust code looks very much like \"normal\" sequential " "code:" msgstr "" -#: src/async/async-await.md +#: src/concurrency/async/async-await.md msgid "\"Count is: {i}!\"" msgstr "" -#: src/async/async-await.md +#: src/concurrency/async/async-await.md msgid "" "Note that this is a simplified example to show the syntax. There is no long " "running operation or any real concurrency in it!" msgstr "" -#: src/async/async-await.md -msgid "What is the return type of an async call?" -msgstr "" - -#: src/async/async-await.md -msgid "Use `let future: () = async_main(10);` in `main` to see the type." -msgstr "" - -#: src/async/async-await.md +#: src/concurrency/async/async-await.md msgid "" "The \"async\" keyword is syntactic sugar. The compiler replaces the return " "type with a future." msgstr "" -#: src/async/async-await.md +#: src/concurrency/async/async-await.md msgid "" "You cannot make `main` async, without additional instructions to the " "compiler on how to use the returned future." msgstr "" -#: src/async/async-await.md +#: src/concurrency/async/async-await.md msgid "" "You need an executor to run async code. `block_on` blocks the current thread " "until the provided future has run to completion." msgstr "" -#: src/async/async-await.md +#: src/concurrency/async/async-await.md msgid "" "`.await` asynchronously waits for the completion of another operation. " "Unlike `block_on`, `.await` doesn't block the current thread." msgstr "" -#: src/async/async-await.md +#: src/concurrency/async/async-await.md msgid "" "`.await` can only be used inside an `async` function (or block; these are " "introduced later)." msgstr "" -#: src/async/futures.md +#: src/concurrency/async/futures.md msgid "" "[`Future`](https://doc.rust-lang.org/std/future/trait.Future.html) is a " "trait, implemented by objects that represent an operation that may not be " @@ -18248,7 +21035,7 @@ msgid "" "doc.rust-lang.org/std/task/enum.Poll.html)." msgstr "" -#: src/async/futures.md +#: src/concurrency/async/futures.md msgid "" "An async function returns an `impl Future`. It's also possible (but " "uncommon) to implement `Future` for your own types. For example, the " @@ -18256,76 +21043,169 @@ msgid "" "joining to it." msgstr "" -#: src/async/futures.md +#: src/concurrency/async/futures.md msgid "" "The `.await` keyword, applied to a Future, causes the current async function " "to pause until that Future is ready, and then evaluates to its output." msgstr "" -#: src/async/futures.md +#: src/concurrency/async/futures.md msgid "" "The `Future` and `Poll` types are implemented exactly as shown; click the " "links to show the implementations in the docs." msgstr "" -#: src/async/futures.md -msgid "" -"We will not get to `Pin` and `Context`, as we will focus on writing async " -"code, rather than building new async primitives. Briefly:" -msgstr "" - -#: src/async/futures.md +#: src/concurrency/async/futures.md msgid "" "`Context` allows a Future to schedule itself to be polled again when an " -"event occurs." +"event such as a timeout occurs." msgstr "" -#: src/async/futures.md +#: src/concurrency/async/futures.md msgid "" "`Pin` ensures that the Future isn't moved in memory, so that pointers into " "that future remain valid. This is required to allow references to remain " -"valid after an `.await`." +"valid after an `.await`. We will address `Pin` in the \"Pitfalls\" segment." msgstr "" -#: src/async/runtimes.md +#: src/concurrency/async/state-machine.md +msgid "" +"Rust transforms an async function or block to a hidden type that implements " +"`Future`, using a state machine to track the function's progress. The " +"details of this transform are complex, but it is beneficial to have a " +"schematic understanding of what is happening. The following function" +msgstr "" + +#: src/concurrency/async/state-machine.md +msgid "/// Sum two D10 rolls plus a modifier.\n" +msgstr "" + +#: src/concurrency/async/state-machine.md +msgid "is transformed to something like" +msgstr "" + +#: src/concurrency/async/state-machine.md +msgid "// Function has not begun yet.\n" +msgstr "" + +#: src/concurrency/async/state-machine.md +msgid "// Waiting for first `.await` to complete.\n" +msgstr "" + +#: src/concurrency/async/state-machine.md +msgid "// Waiting for second `.await` to complete.\n" +msgstr "" + +#: src/concurrency/async/state-machine.md +msgid "// Create future for first dice roll.\n" +msgstr "" + +#: src/concurrency/async/state-machine.md +msgid "// Poll sub-future for first dice roll.\n" +msgstr "" + +#: src/concurrency/async/state-machine.md +msgid "// Create future for second roll.\n" +msgstr "" + +#: src/concurrency/async/state-machine.md +msgid "// Poll sub-future for second dice roll.\n" +msgstr "" + +#: src/concurrency/async/state-machine.md +msgid "" +"This example is illustrative, and isn't an accurate representation of the " +"Rust compiler's transformation. The important things to notice here are:" +msgstr "" + +#: src/concurrency/async/state-machine.md +msgid "" +"Calling an async function does nothing but construct and return a future." +msgstr "" + +#: src/concurrency/async/state-machine.md +msgid "" +"All local variables are stored in the function's future, using an enum to " +"identify where execution is currently suspended." +msgstr "" + +#: src/concurrency/async/state-machine.md +msgid "" +"An `.await` in the async function is translated into an a new state " +"containing all live variables and the awaited future. The `loop` then " +"handles that updated state, polling the future until it returns `Poll::" +"Ready`." +msgstr "" + +#: src/concurrency/async/state-machine.md +msgid "" +"Execution continues eagerly until a `Poll::Pending` occurs. In this simple " +"example, every future is ready immediately." +msgstr "" + +#: src/concurrency/async/state-machine.md +msgid "" +"`main` contains a naïve executor, which just busy-loops until the future is " +"ready. We will discuss real executors shortly." +msgstr "" + +#: src/concurrency/async/state-machine.md +msgid "" +"Imagine the `Future` data structure for a deeply nested stack of async " +"functions. Each function's `Future` contains the `Future` structures for the " +"functions it calls. This can result in unexpectedly large compiler-generated " +"`Future` types." +msgstr "" + +#: src/concurrency/async/state-machine.md +msgid "" +"This also means that recursive async functions are challenging. Compare to " +"the common error of building recursive type, such as" +msgstr "" + +#: src/concurrency/async/state-machine.md +msgid "" +"The fix for a recursive type is to add a layer of indrection, such as with " +"`Box`. Similarly, a recursive async function must box the recursive future:" +msgstr "" + +#: src/concurrency/async/state-machine.md +msgid "\"{n}\"" +msgstr "" + +#: src/concurrency/async/runtimes.md msgid "" "A _runtime_ provides support for performing operations asynchronously (a " "_reactor_) and is responsible for executing futures (an _executor_). Rust " "does not have a \"built-in\" runtime, but several options are available:" msgstr "" -#: src/async/runtimes.md +#: src/concurrency/async/runtimes.md msgid "" "[Tokio](https://tokio.rs/): performant, with a well-developed ecosystem of " "functionality like [Hyper](https://hyper.rs/) for HTTP or [Tonic](https://" "github.com/hyperium/tonic) for gRPC." msgstr "" -#: src/async/runtimes.md -msgid "" -"[async-std](https://async.rs/): aims to be a \"std for async\", and includes " -"a basic runtime in `async::task`." -msgstr "" - -#: src/async/runtimes.md +#: src/concurrency/async/runtimes.md msgid "[smol](https://docs.rs/smol/latest/smol/): simple and lightweight" msgstr "" -#: src/async/runtimes.md +#: src/concurrency/async/runtimes.md msgid "" "Several larger applications have their own runtimes. For example, [Fuchsia]" "(https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/src/lib/fuchsia-" "async/src/lib.rs) already has one." msgstr "" -#: src/async/runtimes.md +#: src/concurrency/async/runtimes.md msgid "" "Note that of the listed runtimes, only Tokio is supported in the Rust " "playground. The playground also does not permit any I/O, so most interesting " "async things can't run in the playground." msgstr "" -#: src/async/runtimes.md +#: src/concurrency/async/runtimes.md msgid "" "Futures are \"inert\" in that they do not do anything (not even start an I/O " "operation) unless there is an executor polling them. This differs from JS " @@ -18333,66 +21213,66 @@ msgid "" "used." msgstr "" -#: src/async/runtimes/tokio.md +#: src/concurrency/async/runtimes/tokio.md msgid "Tokio provides:" msgstr "" -#: src/async/runtimes/tokio.md +#: src/concurrency/async/runtimes/tokio.md msgid "A multi-threaded runtime for executing asynchronous code." msgstr "" -#: src/async/runtimes/tokio.md +#: src/concurrency/async/runtimes/tokio.md msgid "An asynchronous version of the standard library." msgstr "" -#: src/async/runtimes/tokio.md +#: src/concurrency/async/runtimes/tokio.md msgid "A large ecosystem of libraries." msgstr "" -#: src/async/runtimes/tokio.md +#: src/concurrency/async/runtimes/tokio.md msgid "\"Count in task: {i}!\"" msgstr "" -#: src/async/runtimes/tokio.md +#: src/concurrency/async/runtimes/tokio.md msgid "\"Main task: {i}\"" msgstr "" -#: src/async/runtimes/tokio.md +#: src/concurrency/async/runtimes/tokio.md msgid "With the `tokio::main` macro we can now make `main` async." msgstr "" -#: src/async/runtimes/tokio.md +#: src/concurrency/async/runtimes/tokio.md msgid "The `spawn` function creates a new, concurrent \"task\"." msgstr "" -#: src/async/runtimes/tokio.md +#: src/concurrency/async/runtimes/tokio.md msgid "Note: `spawn` takes a `Future`, you don't call `.await` on `count_to`." msgstr "" -#: src/async/runtimes/tokio.md +#: src/concurrency/async/runtimes/tokio.md msgid "**Further exploration:**" msgstr "" -#: src/async/runtimes/tokio.md +#: src/concurrency/async/runtimes/tokio.md msgid "" -"Why does `count_to` not (usually) get to 10? This is an example of async " -"cancellation. `tokio::spawn` returns a handle which can be awaited to wait " -"until it finishes." +"Why does `count_to` not get to 10? This is an example of async cancellation. " +"`tokio::spawn` returns a handle which can be awaited to wait until it " +"finishes." msgstr "" -#: src/async/runtimes/tokio.md +#: src/concurrency/async/runtimes/tokio.md msgid "Try `count_to(10).await` instead of spawning." msgstr "" -#: src/async/runtimes/tokio.md +#: src/concurrency/async/runtimes/tokio.md msgid "Try awaiting the task returned from `tokio::spawn`." msgstr "" -#: src/async/tasks.md +#: src/concurrency/async/tasks.md msgid "Rust has a task system, which is a form of lightweight threading." msgstr "" -#: src/async/tasks.md +#: src/concurrency/async/tasks.md msgid "" "A task has a single top-level future which the executor polls to make " "progress. That future may have one or more nested futures that its `poll` " @@ -18401,170 +21281,155 @@ msgid "" "and an I/O operation." msgstr "" -#: src/async/tasks.md +#: src/concurrency/async/tasks.md msgid "\"127.0.0.1:0\"" msgstr "" -#: src/async/tasks.md +#: src/concurrency/async/tasks.md msgid "\"listening on port {}\"" msgstr "" -#: src/async/tasks.md +#: src/concurrency/async/tasks.md msgid "\"connection from {addr:?}\"" msgstr "" -#: src/async/tasks.md +#: src/concurrency/async/tasks.md msgid "b\"Who are you?\\n\"" msgstr "" -#: src/async/tasks.md +#: src/concurrency/async/tasks.md msgid "\"socket error\"" msgstr "" -#: src/async/tasks.md +#: src/concurrency/async/tasks.md msgid "\"Thanks for dialing in, {name}!\\n\"" msgstr "" -#: src/async/tasks.md src/async/control-flow/join.md +#: src/concurrency/async/tasks.md src/concurrency/async-control-flow/join.md msgid "" "Copy this example into your prepared `src/main.rs` and run it from there." msgstr "" -#: src/async/tasks.md +#: src/concurrency/async/tasks.md msgid "" "Try connecting to it with a TCP connection tool like [nc](https://www.unix." "com/man-page/linux/1/nc/) or [telnet](https://www.unix.com/man-page/linux/1/" "telnet/)." msgstr "" -#: src/async/tasks.md +#: src/concurrency/async/tasks.md msgid "" "Ask students to visualize what the state of the example server would be with " "a few connected clients. What tasks exist? What are their Futures?" msgstr "" -#: src/async/tasks.md +#: src/concurrency/async/tasks.md msgid "" "This is the first time we've seen an `async` block. This is similar to a " "closure, but does not take any arguments. Its return value is a Future, " "similar to an `async fn`." msgstr "" -#: src/async/tasks.md +#: src/concurrency/async/tasks.md msgid "" "Refactor the async block into a function, and improve the error handling " "using `?`." msgstr "" -#: src/async/channels.md +#: src/concurrency/async-control-flow/channels.md msgid "" "Several crates have support for asynchronous channels. For instance `tokio`:" msgstr "" -#: src/async/channels.md +#: src/concurrency/async-control-flow/channels.md msgid "\"Received {count} pings so far.\"" msgstr "" -#: src/async/channels.md +#: src/concurrency/async-control-flow/channels.md msgid "\"ping_handler complete\"" msgstr "" -#: src/async/channels.md +#: src/concurrency/async-control-flow/channels.md msgid "\"Failed to send ping.\"" msgstr "" -#: src/async/channels.md +#: src/concurrency/async-control-flow/channels.md msgid "\"Sent {} pings so far.\"" msgstr "" -#: src/async/channels.md +#: src/concurrency/async-control-flow/channels.md msgid "\"Something went wrong in ping handler task.\"" msgstr "" -#: src/async/channels.md +#: src/concurrency/async-control-flow/channels.md msgid "Change the channel size to `3` and see how it affects the execution." msgstr "" -#: src/async/channels.md +#: src/concurrency/async-control-flow/channels.md msgid "" "Overall, the interface is similar to the `sync` channels as seen in the " -"[morning class](concurrency/channels.md)." +"[morning class](../channels.md)." msgstr "" -#: src/async/channels.md +#: src/concurrency/async-control-flow/channels.md msgid "Try removing the `std::mem::drop` call. What happens? Why?" msgstr "" -#: src/async/channels.md +#: src/concurrency/async-control-flow/channels.md msgid "" "The [Flume](https://docs.rs/flume/latest/flume/) crate has channels that " "implement both `sync` and `async` `send` and `recv`. This can be convenient " "for complex applications with both IO and heavy CPU processing tasks." msgstr "" -#: src/async/channels.md +#: src/concurrency/async-control-flow/channels.md msgid "" "What makes working with `async` channels preferable is the ability to " "combine them with other `future`s to combine them and create complex control " "flow." msgstr "" -#: src/async/control-flow.md -msgid "Futures Control Flow" -msgstr "" - -#: src/async/control-flow.md -msgid "" -"Futures can be combined together to produce concurrent compute flow graphs. " -"We have already seen tasks, that function as independent threads of " -"execution." -msgstr "" - -#: src/async/control-flow.md -msgid "[Join](control-flow/join.md)" -msgstr "" - -#: src/async/control-flow.md -msgid "[Select](control-flow/select.md)" -msgstr "" - -#: src/async/control-flow/join.md +#: src/concurrency/async-control-flow/join.md msgid "" "A join operation waits until all of a set of futures are ready, and returns " "a collection of their results. This is similar to `Promise.all` in " "JavaScript or `asyncio.gather` in Python." msgstr "" -#: src/async/control-flow/join.md +#: src/concurrency/async-control-flow/join.md msgid "\"https://google.com\"" msgstr "" -#: src/async/control-flow/join.md +#: src/concurrency/async-control-flow/join.md msgid "\"https://httpbin.org/ip\"" msgstr "" -#: src/async/control-flow/join.md +#: src/concurrency/async-control-flow/join.md msgid "\"https://play.rust-lang.org/\"" msgstr "" -#: src/async/control-flow/join.md +#: src/concurrency/async-control-flow/join.md msgid "\"BAD_URL\"" msgstr "" -#: src/async/control-flow/join.md +#: src/concurrency/async-control-flow/join.md +msgid "\"{page_sizes_dict:?}\"" +msgstr "" + +#: src/concurrency/async-control-flow/join.md msgid "" "For multiple futures of disjoint types, you can use `std::future::join!` but " "you must know how many futures you will have at compile time. This is " "currently in the `futures` crate, soon to be stabilised in `std::future`." msgstr "" -#: src/async/control-flow/join.md +#: src/concurrency/async-control-flow/join.md msgid "" "The risk of `join` is that one of the futures may never resolve, this would " "cause your program to stall." msgstr "" -#: src/async/control-flow/join.md +#: src/concurrency/async-control-flow/join.md msgid "" "You can also combine `join_all` with `join!` for instance to join all " "requests to an http service as well as a database query. Try adding a " @@ -18573,7 +21438,7 @@ msgid "" "demonstrates `join!`." msgstr "" -#: src/async/control-flow/select.md +#: src/concurrency/async-control-flow/select.md msgid "" "A select operation waits until any of a set of futures is ready, and " "responds to that future's result. In JavaScript, this is similar to `Promise." @@ -18581,7 +21446,7 @@ msgid "" "FIRST_COMPLETED)`." msgstr "" -#: src/async/control-flow/select.md +#: src/concurrency/async-control-flow/select.md msgid "" "Similar to a match statement, the body of `select!` has a number of arms, " "each of the form `pattern = future => statement`. When a `future` is ready, " @@ -18590,95 +21455,53 @@ msgid "" "of the `select!` macro." msgstr "" -#: src/async/control-flow/select.md -msgid "\"Felix\"" +#: src/concurrency/async-control-flow/select.md +msgid "\"got: {msg}\"" msgstr "" -#: src/async/control-flow/select.md -msgid "\"Failed to send cat.\"" +#: src/concurrency/async-control-flow/select.md +msgid "\"timeout\"" msgstr "" -#: src/async/control-flow/select.md -msgid "\"Rex\"" +#: src/concurrency/async-control-flow/select.md +msgid "\"Failed to send greeting\"" msgstr "" -#: src/async/control-flow/select.md -msgid "\"Failed to send dog.\"" +#: src/concurrency/async-control-flow/select.md +msgid "\"Listener failed\"" msgstr "" -#: src/async/control-flow/select.md -msgid "\"Failed to receive winner\"" -msgstr "" - -#: src/async/control-flow/select.md -msgid "\"Winner is {winner:?}\"" -msgstr "" - -#: src/async/control-flow/select.md +#: src/concurrency/async-control-flow/select.md msgid "" -"In this example, we have a race between a cat and a dog. " -"`first_animal_to_finish_race` listens to both channels and will pick " -"whichever arrives first. Since the dog takes 50ms, it wins against the cat " -"that take 500ms." +"The `listener` async block here is a common form: wait for some async event, " +"or for a timeout. Change the `sleep` to sleep longer to see it fail. Why " +"does the `send` also fail in this situation?" msgstr "" -#: src/async/control-flow/select.md +#: src/concurrency/async-control-flow/select.md msgid "" -"You can use `oneshot` channels in this example as the channels are supposed " -"to receive only one `send`." +"`select!` is also frequently used in a loop in \"actor\" architectures, " +"where a task reacts to events in a loop. That has some pitfalls, which will " +"be discussed in the next segment." msgstr "" -#: src/async/control-flow/select.md -msgid "" -"Try adding a deadline to the race, demonstrating selecting different sorts " -"of futures." -msgstr "" - -#: src/async/control-flow/select.md -msgid "" -"Note that `select!` drops unmatched branches, which cancels their futures. " -"It is easiest to use when every execution of `select!` creates new futures." -msgstr "" - -#: src/async/control-flow/select.md -msgid "" -"An alternative is to pass `&mut future` instead of the future itself, but " -"this can lead to issues, further discussed in the pinning slide." -msgstr "" - -#: src/async/pitfalls.md -msgid "Pitfalls of async/await" -msgstr "" - -#: src/async/pitfalls.md +#: src/concurrency/async-pitfalls.md msgid "" "Async / await provides convenient and efficient abstraction for concurrent " "asynchronous programming. However, the async/await model in Rust also comes " "with its share of pitfalls and footguns. We illustrate some of them in this " -"chapter:" +"chapter." msgstr "" -#: src/async/pitfalls.md -msgid "[Blocking the Executor](pitfalls/blocking-executor.md)" +#: src/concurrency/async-pitfalls.md +msgid "Pin" msgstr "" -#: src/async/pitfalls.md -msgid "[Pin](pitfalls/pin.md)" -msgstr "" - -#: src/async/pitfalls.md -msgid "[Async Traits](pitfalls/async-traits.md)" -msgstr "" - -#: src/async/pitfalls.md -msgid "[Cancellation](pitfalls/cancellation.md)" -msgstr "" - -#: src/async/pitfalls/blocking-executor.md +#: src/concurrency/async-pitfalls/blocking-executor.md msgid "Blocking the executor" msgstr "" -#: src/async/pitfalls/blocking-executor.md +#: src/concurrency/async-pitfalls/blocking-executor.md msgid "" "Most async runtimes only allow IO tasks to run concurrently. This means that " "CPU blocking tasks will block the executor and prevent other tasks from " @@ -18686,69 +21509,63 @@ msgid "" "possible." msgstr "" -#: src/async/pitfalls/blocking-executor.md +#: src/concurrency/async-pitfalls/blocking-executor.md msgid "\"future {id} slept for {duration_ms}ms, finished after {}ms\"" msgstr "" -#: src/async/pitfalls/blocking-executor.md +#: src/concurrency/async-pitfalls/blocking-executor.md msgid "\"current_thread\"" msgstr "" -#: src/async/pitfalls/blocking-executor.md +#: src/concurrency/async-pitfalls/blocking-executor.md msgid "" "Run the code and see that the sleeps happen consecutively rather than " "concurrently." msgstr "" -#: src/async/pitfalls/blocking-executor.md +#: src/concurrency/async-pitfalls/blocking-executor.md msgid "" "The `\"current_thread\"` flavor puts all tasks on a single thread. This " "makes the effect more obvious, but the bug is still present in the multi-" "threaded flavor." msgstr "" -#: src/async/pitfalls/blocking-executor.md +#: src/concurrency/async-pitfalls/blocking-executor.md msgid "" "Switch the `std::thread::sleep` to `tokio::time::sleep` and await its result." msgstr "" -#: src/async/pitfalls/blocking-executor.md +#: src/concurrency/async-pitfalls/blocking-executor.md msgid "" "Another fix would be to `tokio::task::spawn_blocking` which spawns an actual " "thread and transforms its handle into a future without blocking the executor." msgstr "" -#: src/async/pitfalls/blocking-executor.md +#: src/concurrency/async-pitfalls/blocking-executor.md msgid "" -"You should not think of tasks as OS threads. They do not map 1 to 1 and most " -"executors will allow many tasks to run on a single OS thread. This is " +"You should not think of tasks as OS threads. They do not map 1 to 1 and " +"executors will allow multiple tasks to run on a single OS thread. This is " "particularly problematic when interacting with other libraries via FFI, " "where that library might depend on thread-local storage or map to specific " "OS threads (e.g., CUDA). Prefer `tokio::task::spawn_blocking` in such " "situations." msgstr "" -#: src/async/pitfalls/blocking-executor.md +#: src/concurrency/async-pitfalls/blocking-executor.md msgid "" "Use sync mutexes with care. Holding a mutex over an `.await` may cause " "another task to block, and that task may be running on the same thread." msgstr "" -#: src/async/pitfalls/pin.md +#: src/concurrency/async-pitfalls/pin.md msgid "" -"Async blocks and functions return types implementing the `Future` trait. The " -"type returned is the result of a compiler transformation which turns local " -"variables into data stored inside the future." +"Recall an async function or block creates a type implementing `Future` and " +"containing all of the local variables. Some of those variables can hold " +"references (pointers) to other local variables. To ensure those remain " +"valid, the future can never be moved to a different memory location." msgstr "" -#: src/async/pitfalls/pin.md -msgid "" -"Some of those variables can hold pointers to other local variables. Because " -"of that, the future should never be moved to a different memory location, as " -"it would invalidate those pointers." -msgstr "" - -#: src/async/pitfalls/pin.md +#: src/concurrency/async-pitfalls/pin.md msgid "" "To prevent moving the future type in memory, it can only be polled through a " "pinned pointer. `Pin` is a wrapper around a reference that disallows all " @@ -18756,97 +21573,95 @@ msgid "" "location." msgstr "" -#: src/async/pitfalls/pin.md -msgid "// A work item. In this case, just sleep for the given time and respond" +#: src/concurrency/async-pitfalls/pin.md +msgid "" +"// A work item. In this case, just sleep for the given time and respond\n" +"// with a message on the `respond_on` channel.\n" msgstr "" -#: src/async/pitfalls/pin.md -msgid "// with a message on the `respond_on` channel." +#: src/concurrency/async-pitfalls/pin.md +msgid "// A worker which listens for work on a queue and performs it.\n" msgstr "" -#: src/async/pitfalls/pin.md -msgid "// A worker which listens for work on a queue and performs it." +#: src/concurrency/async-pitfalls/pin.md +msgid "// Pretend to work.\n" msgstr "" -#: src/async/pitfalls/pin.md -msgid "// Pretend to work." -msgstr "" - -#: src/async/pitfalls/pin.md +#: src/concurrency/async-pitfalls/pin.md msgid "\"failed to send response\"" msgstr "" -#: src/async/pitfalls/pin.md -msgid "// TODO: report number of iterations every 100ms" +#: src/concurrency/async-pitfalls/pin.md +msgid "// TODO: report number of iterations every 100ms\n" msgstr "" -#: src/async/pitfalls/pin.md -msgid "// A requester which requests work and waits for it to complete." +#: src/concurrency/async-pitfalls/pin.md +msgid "// A requester which requests work and waits for it to complete.\n" msgstr "" -#: src/async/pitfalls/pin.md +#: src/concurrency/async-pitfalls/pin.md msgid "\"failed to send on work queue\"" msgstr "" -#: src/async/pitfalls/pin.md +#: src/concurrency/async-pitfalls/pin.md msgid "\"failed waiting for response\"" msgstr "" -#: src/async/pitfalls/pin.md +#: src/concurrency/async-pitfalls/pin.md msgid "\"work result for iteration {i}: {resp}\"" msgstr "" -#: src/async/pitfalls/pin.md +#: src/concurrency/async-pitfalls/pin.md msgid "" "You may recognize this as an example of the actor pattern. Actors typically " "call `select!` in a loop." msgstr "" -#: src/async/pitfalls/pin.md +#: src/concurrency/async-pitfalls/pin.md msgid "" "This serves as a summation of a few of the previous lessons, so take your " "time with it." msgstr "" -#: src/async/pitfalls/pin.md +#: src/concurrency/async-pitfalls/pin.md msgid "" "Naively add a `_ = sleep(Duration::from_millis(100)) => { println!(..) }` to " "the `select!`. This will never execute. Why?" msgstr "" -#: src/async/pitfalls/pin.md +#: src/concurrency/async-pitfalls/pin.md msgid "" "Instead, add a `timeout_fut` containing that future outside of the `loop`:" msgstr "" -#: src/async/pitfalls/pin.md +#: src/concurrency/async-pitfalls/pin.md msgid "" "This still doesn't work. Follow the compiler errors, adding `&mut` to the " "`timeout_fut` in the `select!` to work around the move, then using `Box::" "pin`:" msgstr "" -#: src/async/pitfalls/pin.md +#: src/concurrency/async-pitfalls/pin.md msgid "" "This compiles, but once the timeout expires it is `Poll::Ready` on every " "iteration (a fused future would help with this). Update to reset " -"`timeout_fut` every time it expires." +"`timeout_fut` every time it expires:" msgstr "" -#: src/async/pitfalls/pin.md +#: src/concurrency/async-pitfalls/pin.md msgid "" "Box allocates on the heap. In some cases, `std::pin::pin!` (only recently " "stabilized, with older code often using `tokio::pin!`) is also an option, " "but that is difficult to use for a future that is reassigned." msgstr "" -#: src/async/pitfalls/pin.md +#: src/concurrency/async-pitfalls/pin.md msgid "" "Another alternative is to not use `pin` at all but spawn another task that " "will send to a `oneshot` channel every 100ms." msgstr "" -#: src/async/pitfalls/pin.md +#: src/concurrency/async-pitfalls/pin.md msgid "" "Data that contains pointers to itself is called self-referential. Normally, " "the Rust borrow checker would prevent self-referential data from being " @@ -18855,64 +21670,94 @@ msgid "" "borrow checker." msgstr "" -#: src/async/pitfalls/pin.md +#: src/concurrency/async-pitfalls/pin.md msgid "" "`Pin` is a wrapper around a reference. An object cannot be moved from its " "place using a pinned pointer. However, it can still be moved through an " "unpinned pointer." msgstr "" -#: src/async/pitfalls/pin.md +#: src/concurrency/async-pitfalls/pin.md msgid "" "The `poll` method of the `Future` trait uses `Pin<&mut Self>` instead of " "`&mut Self` to refer to the instance. That's why it can only be called on a " "pinned pointer." msgstr "" -#: src/async/pitfalls/async-traits.md +#: src/concurrency/async-pitfalls/async-traits.md msgid "" -"Async methods in traits are not yet supported in the stable channel ([An " -"experimental feature exists in nightly and should be stabilized in the mid " -"term.](https://blog.rust-lang.org/inside-rust/2022/11/17/async-fn-in-trait-" -"nightly.html))" +"Async methods in traits were stabilized in the 1.75 release. This required " +"support for using return-position `impl Trait` in traits, as the desugaring " +"for `async fn` includes `-> impl Future`." msgstr "" -#: src/async/pitfalls/async-traits.md +#: src/concurrency/async-pitfalls/async-traits.md msgid "" -"The crate [async_trait](https://docs.rs/async-trait/latest/async_trait/) " -"provides a workaround through a macro:" +"However, even with the native support, there are specific pitfalls around " +"`async fn`:" msgstr "" -#: src/async/pitfalls/async-traits.md -msgid "\"running all sleepers..\"" +#: src/concurrency/async-pitfalls/async-traits.md +msgid "" +"Return-position `impl Trait` captures all in-scope lifetimes (so certain " +"patterns of borrowing cannot be expressed)." msgstr "" -#: src/async/pitfalls/async-traits.md -msgid "\"slept for {}ms\"" +#: src/concurrency/async-pitfalls/async-traits.md +msgid "" +"Async traits cannot be used with [trait objects](../../smart-pointers/trait-" +"objects.md) (`dyn Trait` support)." msgstr "" -#: src/async/pitfalls/async-traits.md +#: src/concurrency/async-pitfalls/async-traits.md +msgid "" +"The [async_trait](https://docs.rs/async-trait/) crate provides a workaround " +"for `dyn` support through a macro, with specific caveats:" +msgstr "" + +#: src/concurrency/async-pitfalls/async-traits.md +msgid "\"Running all sleepers...\"" +msgstr "" + +#: src/concurrency/async-pitfalls/async-traits.md +msgid "\"Slept for {} ms\"" +msgstr "" + +#: src/concurrency/async-pitfalls/async-traits.md msgid "" "`async_trait` is easy to use, but note that it's using heap allocations to " "achieve this. This heap allocation has performance overhead." msgstr "" -#: src/async/pitfalls/async-traits.md +#: src/concurrency/async-pitfalls/async-traits.md msgid "" -"The challenges in language support for `async trait` are deep Rust and " -"probably not worth describing in-depth. Niko Matsakis did a good job of " -"explaining them in [this post](https://smallcultfollowing.com/babysteps/" -"blog/2019/10/26/async-fn-in-traits-are-hard/) if you are interested in " -"digging deeper." +"The challenges in language support for `async trait` are too deep to " +"describe in-depth in this class. See [this blog post](https://" +"smallcultfollowing.com/babysteps/blog/2019/10/26/async-fn-in-traits-are-" +"hard/) by Niko Matsakis if you are interested in digging deeper. See also " +"these keywords:" msgstr "" -#: src/async/pitfalls/async-traits.md +#: src/concurrency/async-pitfalls/async-traits.md +msgid "" +"[RPIT](https://doc.rust-lang.org/reference/types/impl-trait.html#abstract-" +"return-types): short for [return-position `impl Trait`](../../generics/impl-" +"trait.md)." +msgstr "" + +#: src/concurrency/async-pitfalls/async-traits.md +msgid "" +"[RPITIT](https://blog.rust-lang.org/2023/12/21/async-fn-rpit-in-traits." +"html): short for return-position `impl Trait` in trait (RPIT in trait)." +msgstr "" + +#: src/concurrency/async-pitfalls/async-traits.md msgid "" "Try creating a new sleeper struct that will sleep for a random amount of " -"time and adding it to the Vec." +"time and adding it to the `Vec`." msgstr "" -#: src/async/pitfalls/cancellation.md +#: src/concurrency/async-pitfalls/cancellation.md msgid "" "Dropping a future implies it can never be polled again. This is called " "_cancellation_ and it can occur at any `await` point. Care is needed to " @@ -18920,128 +21765,116 @@ msgid "" "example, it shouldn't deadlock or lose data." msgstr "" -#: src/async/pitfalls/cancellation.md +#: src/concurrency/async-pitfalls/cancellation.md msgid "\"not UTF-8\"" msgstr "" -#: src/async/pitfalls/cancellation.md +#: src/concurrency/async-pitfalls/cancellation.md msgid "\"hi\\nthere\\n\"" msgstr "" -#: src/async/pitfalls/cancellation.md +#: src/concurrency/async-pitfalls/cancellation.md msgid "\"tick!\"" msgstr "" -#: src/async/pitfalls/cancellation.md +#: src/concurrency/async-pitfalls/cancellation.md msgid "" "The compiler doesn't help with cancellation-safety. You need to read API " "documentation and consider what state your `async fn` holds." msgstr "" -#: src/async/pitfalls/cancellation.md +#: src/concurrency/async-pitfalls/cancellation.md msgid "" "Unlike `panic` and `?`, cancellation is part of normal control flow (vs " "error-handling)." msgstr "" -#: src/async/pitfalls/cancellation.md +#: src/concurrency/async-pitfalls/cancellation.md msgid "The example loses parts of the string." msgstr "" -#: src/async/pitfalls/cancellation.md +#: src/concurrency/async-pitfalls/cancellation.md msgid "" "Whenever the `tick()` branch finishes first, `next()` and its `buf` are " "dropped." msgstr "" -#: src/async/pitfalls/cancellation.md +#: src/concurrency/async-pitfalls/cancellation.md msgid "" "`LinesReader` can be made cancellation-safe by making `buf` part of the " "struct:" msgstr "" -#: src/async/pitfalls/cancellation.md -msgid "// prefix buf and bytes with self." +#: src/concurrency/async-pitfalls/cancellation.md +msgid "// prefix buf and bytes with self.\n" msgstr "" -#: src/async/pitfalls/cancellation.md +#: src/concurrency/async-pitfalls/cancellation.md msgid "" "[`Interval::tick`](https://docs.rs/tokio/latest/tokio/time/struct.Interval." "html#method.tick) is cancellation-safe because it keeps track of whether a " "tick has been 'delivered'." msgstr "" -#: src/async/pitfalls/cancellation.md +#: src/concurrency/async-pitfalls/cancellation.md msgid "" "[`AsyncReadExt::read`](https://docs.rs/tokio/latest/tokio/io/trait." "AsyncReadExt.html#method.read) is cancellation-safe because it either " "returns or doesn't read data." msgstr "" -#: src/async/pitfalls/cancellation.md +#: src/concurrency/async-pitfalls/cancellation.md msgid "" "[`AsyncBufReadExt::read_line`](https://docs.rs/tokio/latest/tokio/io/trait." "AsyncBufReadExt.html#method.read_line) is similar to the example and _isn't_ " "cancellation-safe. See its documentation for details and alternatives." msgstr "" -#: src/exercises/concurrency/afternoon.md -msgid "" -"To practice your Async Rust skills, we have again two exercises for you:" -msgstr "" - -#: src/exercises/concurrency/afternoon.md -msgid "" -"Dining philosophers: we already saw this problem in the morning. This time " -"you are going to implement it with Async Rust." -msgstr "" - -#: src/exercises/concurrency/afternoon.md -msgid "" -"A Broadcast Chat Application: this is a larger project that allows you " -"experiment with more advanced Async Rust features." -msgstr "" - -#: src/exercises/concurrency/dining-philosophers-async.md -#: src/exercises/concurrency/solutions-afternoon.md -#, fuzzy +#: src/concurrency/async-exercises/dining-philosophers.md +#: src/concurrency/async-exercises/solutions.md msgid "Dining Philosophers --- Async" -msgstr "Dining āĻĻāĻžāĻ°ā§āĻļāύāĻŋāĻ•" - -#: src/exercises/concurrency/dining-philosophers-async.md -msgid "" -"See [dining philosophers](dining-philosophers.md) for a description of the " -"problem." msgstr "" -#: src/exercises/concurrency/dining-philosophers-async.md +#: src/concurrency/async-exercises/dining-philosophers.md +msgid "" +"See [dining philosophers](../sync-exercises/dining-philosophers.md) for a " +"description of the problem." +msgstr "" + +#: src/concurrency/async-exercises/dining-philosophers.md msgid "" "As before, you will need a local [Cargo installation](../../cargo/running-" "locally.md) for this exercise. Copy the code below to a file called `src/" "main.rs`, fill out the blanks, and test that `cargo run` does not deadlock:" msgstr "" -#: src/exercises/concurrency/dining-philosophers-async.md -msgid "// Keep trying until we have both forks" +#: src/concurrency/async-exercises/dining-philosophers.md +msgid "// Keep trying until we have both chopsticks\n" msgstr "" -#: src/exercises/concurrency/dining-philosophers-async.md -msgid "// Make them think and eat" +#: src/concurrency/async-exercises/dining-philosophers.md +#: src/concurrency/async-exercises/solutions.md +msgid "// tokio scheduler doesn't deadlock with 5 philosophers, so have 2.\n" msgstr "" -#: src/exercises/concurrency/dining-philosophers-async.md +#: src/concurrency/async-exercises/dining-philosophers.md +#: src/concurrency/async-exercises/solutions.md +msgid "// Make them think and eat\n" +msgstr "" + +#: src/concurrency/async-exercises/dining-philosophers.md msgid "" "Since this time you are using Async Rust, you'll need a `tokio` dependency. " "You can use the following `Cargo.toml`:" msgstr "" -#: src/exercises/concurrency/dining-philosophers-async.md +#: src/concurrency/async-exercises/dining-philosophers.md msgid "" "```toml\n" "[package]\n" "name = \"dining-philosophers-async-dine\"\n" "version = \"0.1.0\"\n" -"edition = \"2021\"\n" +"edition = \"2024\"\n" "\n" "[dependencies]\n" "tokio = { version = \"1.26.0\", features = [\"sync\", \"time\", \"macros\", " @@ -19049,17 +21882,17 @@ msgid "" "```" msgstr "" -#: src/exercises/concurrency/dining-philosophers-async.md +#: src/concurrency/async-exercises/dining-philosophers.md msgid "" "Also note that this time you have to use the `Mutex` and the `mpsc` module " "from the `tokio` crate." msgstr "" -#: src/exercises/concurrency/dining-philosophers-async.md +#: src/concurrency/async-exercises/dining-philosophers.md msgid "Can you make your implementation single-threaded?" msgstr "" -#: src/exercises/concurrency/chat-app.md +#: src/concurrency/async-exercises/chat-app.md msgid "" "In this exercise, we want to use our new knowledge to implement a broadcast " "chat application. We have a chat server that the clients connect to and " @@ -19068,7 +21901,7 @@ msgid "" "that it receives to all the clients." msgstr "" -#: src/exercises/concurrency/chat-app.md +#: src/concurrency/async-exercises/chat-app.md msgid "" "For this, we use [a broadcast channel](https://docs.rs/tokio/latest/tokio/" "sync/broadcast/fn.channel.html) on the server, and [`tokio_websockets`]" @@ -19076,74 +21909,74 @@ msgid "" "and the server." msgstr "" -#: src/exercises/concurrency/chat-app.md +#: src/concurrency/async-exercises/chat-app.md msgid "Create a new Cargo project and add the following dependencies:" msgstr "" -#: src/exercises/concurrency/chat-app.md +#: src/concurrency/async-exercises/chat-app.md msgid "_Cargo.toml_:" msgstr "" -#: src/exercises/concurrency/chat-app.md +#: src/concurrency/async-exercises/chat-app.md msgid "" "```toml\n" "[package]\n" "name = \"chat-async\"\n" "version = \"0.1.0\"\n" -"edition = \"2021\"\n" +"edition = \"2024\"\n" "\n" "[dependencies]\n" -"futures-util = { version = \"0.3.30\", features = [\"sink\"] }\n" -"http = \"1.0.0\"\n" -"tokio = { version = \"1.36.0\", features = [\"full\"] }\n" -"tokio-websockets = { version = \"0.5.1\", features = [\"client\", " +"futures-util = { version = \"0.3.32\", features = [\"sink\"] }\n" +"http = \"1.4.0\"\n" +"tokio = { version = \"1.49.0\", features = [\"full\"] }\n" +"tokio-websockets = { version = \"0.13.1\", features = [\"client\", " "\"fastrand\", \"server\", \"sha1_smol\"] }\n" "```" msgstr "" -#: src/exercises/concurrency/chat-app.md +#: src/concurrency/async-exercises/chat-app.md msgid "The required APIs" msgstr "" -#: src/exercises/concurrency/chat-app.md +#: src/concurrency/async-exercises/chat-app.md msgid "" "You are going to need the following functions from `tokio` and " -"[`tokio_websockets`](https://docs.rs/tokio-websockets/). Spend a few minutes " -"to familiarize yourself with the API." +"[`tokio_websockets`](https://docs.rs/tokio-websockets/). Take time to " +"familiarize yourself with the API." msgstr "" -#: src/exercises/concurrency/chat-app.md +#: src/concurrency/async-exercises/chat-app.md msgid "" "[StreamExt::next()](https://docs.rs/futures-util/0.3.28/futures_util/stream/" "trait.StreamExt.html#method.next) implemented by `WebSocketStream`: for " "asynchronously reading messages from a Websocket Stream." msgstr "" -#: src/exercises/concurrency/chat-app.md +#: src/concurrency/async-exercises/chat-app.md msgid "" "[SinkExt::send()](https://docs.rs/futures-util/0.3.28/futures_util/sink/" "trait.SinkExt.html#method.send) implemented by `WebSocketStream`: for " "asynchronously sending messages on a Websocket Stream." msgstr "" -#: src/exercises/concurrency/chat-app.md +#: src/concurrency/async-exercises/chat-app.md msgid "" "[Lines::next_line()](https://docs.rs/tokio/latest/tokio/io/struct.Lines." "html#method.next_line): for asynchronously reading user messages from the " "standard input." msgstr "" -#: src/exercises/concurrency/chat-app.md +#: src/concurrency/async-exercises/chat-app.md msgid "" "[Sender::subscribe()](https://docs.rs/tokio/latest/tokio/sync/broadcast/" "struct.Sender.html#method.subscribe): for subscribing to a broadcast channel." msgstr "" -#: src/exercises/concurrency/chat-app.md +#: src/concurrency/async-exercises/chat-app.md msgid "Two binaries" msgstr "" -#: src/exercises/concurrency/chat-app.md +#: src/concurrency/async-exercises/chat-app.md msgid "" "Normally in a Cargo project, you can have only one binary, and one `src/main." "rs` file. In this project, we need two binaries. One for the client, and one " @@ -19154,81 +21987,80 @@ msgid "" "targets.html#binaries))." msgstr "" -#: src/exercises/concurrency/chat-app.md +#: src/concurrency/async-exercises/chat-app.md msgid "" "Copy the following server and client code into `src/bin/server.rs` and `src/" "bin/client.rs`, respectively. Your task is to complete these files as " "described below." msgstr "" -#: src/exercises/concurrency/chat-app.md -#: src/exercises/concurrency/solutions-afternoon.md +#: src/concurrency/async-exercises/chat-app.md +#: src/concurrency/async-exercises/solutions.md msgid "_src/bin/server.rs_:" msgstr "" -#: src/exercises/concurrency/chat-app.md -msgid "// TODO: For a hint, see the description of the task below." +#: src/concurrency/async-exercises/chat-app.md +msgid "// TODO: For a hint, see the description of the task below.\n" msgstr "" -#: src/exercises/concurrency/chat-app.md -#: src/exercises/concurrency/solutions-afternoon.md +#: src/concurrency/async-exercises/chat-app.md +#: src/concurrency/async-exercises/solutions.md msgid "\"127.0.0.1:2000\"" msgstr "" -#: src/exercises/concurrency/chat-app.md -#: src/exercises/concurrency/solutions-afternoon.md +#: src/concurrency/async-exercises/chat-app.md +#: src/concurrency/async-exercises/solutions.md msgid "\"listening on port 2000\"" msgstr "" -#: src/exercises/concurrency/chat-app.md -#: src/exercises/concurrency/solutions-afternoon.md +#: src/concurrency/async-exercises/chat-app.md +#: src/concurrency/async-exercises/solutions.md msgid "\"New connection from {addr:?}\"" msgstr "" -#: src/exercises/concurrency/chat-app.md -#: src/exercises/concurrency/solutions-afternoon.md +#: src/concurrency/async-exercises/chat-app.md +#: src/concurrency/async-exercises/solutions.md msgid "// Wrap the raw TCP stream into a websocket.\n" msgstr "" -#: src/exercises/concurrency/chat-app.md -#: src/exercises/concurrency/solutions-afternoon.md +#: src/concurrency/async-exercises/chat-app.md +#: src/concurrency/async-exercises/solutions.md msgid "_src/bin/client.rs_:" msgstr "" -#: src/exercises/concurrency/chat-app.md -#: src/exercises/concurrency/solutions-afternoon.md +#: src/concurrency/async-exercises/chat-app.md +#: src/concurrency/async-exercises/solutions.md msgid "\"ws://127.0.0.1:2000\"" msgstr "" -#: src/exercises/concurrency/chat-app.md -#, fuzzy +#: src/concurrency/async-exercises/chat-app.md msgid "Running the binaries" -msgstr "āϕ⧋āĻ°ā§āϏ āϚāĻžāϞāĻžāύ⧋" +msgstr "" -#: src/exercises/concurrency/chat-app.md +#: src/concurrency/async-exercises/chat-app.md msgid "Run the server with:" msgstr "" -#: src/exercises/concurrency/chat-app.md +#: src/concurrency/async-exercises/chat-app.md msgid "and the client with:" msgstr "" -#: src/exercises/concurrency/chat-app.md +#: src/concurrency/async-exercises/chat-app.md msgid "Implement the `handle_connection` function in `src/bin/server.rs`." msgstr "" -#: src/exercises/concurrency/chat-app.md +#: src/concurrency/async-exercises/chat-app.md msgid "" "Hint: Use `tokio::select!` for concurrently performing two tasks in a " "continuous loop. One task receives messages from the client and broadcasts " "them. The other sends messages received by the server to the client." msgstr "" -#: src/exercises/concurrency/chat-app.md +#: src/concurrency/async-exercises/chat-app.md msgid "Complete the main function in `src/bin/client.rs`." msgstr "" -#: src/exercises/concurrency/chat-app.md +#: src/concurrency/async-exercises/chat-app.md msgid "" "Hint: As before, use `tokio::select!` in a continuous loop for concurrently " "performing two tasks: (1) reading user messages from standard input and " @@ -19236,109 +22068,11842 @@ msgid "" "displaying them for the user." msgstr "" -#: src/exercises/concurrency/chat-app.md +#: src/concurrency/async-exercises/chat-app.md msgid "" "Optional: Once you are done, change the code to broadcast messages to all " "clients, but the sender of the message." msgstr "" -#: src/exercises/concurrency/solutions-afternoon.md -msgid "Concurrency Afternoon Exercise" -msgstr "" - -#: src/exercises/concurrency/solutions-afternoon.md -msgid "([back to exercise](dining-philosophers-async.md))" -msgstr "" - -#: src/exercises/concurrency/solutions-afternoon.md -msgid "// Keep trying until we have both forks\n" -msgstr "" - -#: src/exercises/concurrency/solutions-afternoon.md -msgid "// Pick up forks...\n" -msgstr "" - -#: src/exercises/concurrency/solutions-afternoon.md +#: src/concurrency/async-exercises/solutions.md msgid "" -"// If we didn't get the left fork, drop the right fork if we\n" -" // have it and let other tasks make progress.\n" +"// Keep trying until we have both chopsticks\n" +" // Pick up chopsticks...\n" msgstr "" -#: src/exercises/concurrency/solutions-afternoon.md -msgid "" -"// If we didn't get the right fork, drop the left fork and let\n" -" // other tasks make progress.\n" -msgstr "" - -#: src/exercises/concurrency/solutions-afternoon.md +#: src/concurrency/async-exercises/solutions.md msgid "// The locks are dropped here\n" msgstr "" -#: src/exercises/concurrency/solutions-afternoon.md -msgid "// Create forks\n" -msgstr "" - -#: src/exercises/concurrency/solutions-afternoon.md -msgid "// Create philosophers\n" -msgstr "" - -#: src/exercises/concurrency/solutions-afternoon.md +#: src/concurrency/async-exercises/solutions.md msgid "// tx is dropped here, so we don't need to explicitly drop it later\n" msgstr "" -#: src/exercises/concurrency/solutions-afternoon.md -msgid "// Make them think and eat\n" -msgstr "" - -#: src/exercises/concurrency/solutions-afternoon.md -msgid "// Output their thoughts\n" -msgstr "" - -#: src/exercises/concurrency/solutions-afternoon.md +#: src/concurrency/async-exercises/solutions.md msgid "\"Here is a thought: {thought}\"" msgstr "" -#: src/exercises/concurrency/solutions-afternoon.md -msgid "([back to exercise](chat-app.md))" -msgstr "" - -#: src/exercises/concurrency/solutions-afternoon.md +#: src/concurrency/async-exercises/solutions.md msgid "\"Welcome to chat! Type a message\"" msgstr "" -#: src/exercises/concurrency/solutions-afternoon.md +#: src/concurrency/async-exercises/solutions.md msgid "" "// A continuous loop for concurrently performing two tasks: (1) receiving\n" " // messages from `ws_stream` and broadcasting them, and (2) receiving\n" " // messages on `bcast_rx` and sending them to the client.\n" msgstr "" -#: src/exercises/concurrency/solutions-afternoon.md +#: src/concurrency/async-exercises/solutions.md msgid "\"From client {addr:?} {text:?}\"" msgstr "" -#: src/exercises/concurrency/solutions-afternoon.md +#: src/concurrency/async-exercises/solutions.md msgid "// Continuous loop for concurrently sending and receiving messages.\n" msgstr "" -#: src/exercises/concurrency/solutions-afternoon.md +#: src/concurrency/async-exercises/solutions.md msgid "\"From server: {}\"" msgstr "" +#: src/idiomatic/welcome.md +msgid "Welcome to Idiomatic Rust" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "" +"[Rust Fundamentals](../welcome-day-1.md) introduced Rust syntax and core " +"concepts. We now want to go one step further: how do you use Rust " +"_effectively_ in your projects? What does _idiomatic_ Rust look like?" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "" +"This course is opinionated: we will nudge you towards some patterns, and " +"away from others. Nonetheless, we do recognize that some projects may have " +"different needs. We always provide the necessary information to help you " +"make informed decisions within the context and constraints of your own " +"projects." +msgstr "" + +#: src/idiomatic/welcome.md +msgid "âš ī¸ This course is under **active development**." +msgstr "" + +#: src/idiomatic/welcome.md +msgid "" +"The material may change frequently and there might be errors that have not " +"yet been spotted. Nonetheless, we encourage you to browse through and " +"provide early feedback!" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "" +"Including 10 minute breaks, this session should take about 14 hours and 25 " +"minutes. It contains:" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "" +"The course will cover the topics listed below. Each topic may be covered in " +"one or more slides, depending on its complexity and relevance." +msgstr "" + +#: src/idiomatic/welcome.md +msgid "Target Audience" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "" +"Engineers with at least 2-3 years of coding experience in C, C++11 or newer, " +"Java 7 or newer, Python 2 or 3, Go or any other similar imperative " +"programming language. We have no expectation of experience with more modern " +"or feature-rich languages like Swift, Kotlin, C#, or TypeScript." +msgstr "" + +#: src/idiomatic/welcome.md +msgid "Foundations of API design" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "" +"Golden rule: prioritize clarity and readability at the callsite. People will " +"spend much more time reading the call sites than declarations of the " +"functions being called." +msgstr "" + +#: src/idiomatic/welcome.md +msgid "Make your API predictable" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "" +"Follow naming conventions (case conventions, prefer vocabulary precedented " +"in the standard library - e.g., methods should be called \"push\" not " +"\"push_back\", \"is_empty\" not \"empty\" etc.)" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "" +"Know the vocabulary types and traits in the standard library, and use them " +"in your APIs. If something feels like a basic type/algorithm, check in the " +"standard library first." +msgstr "" + +#: src/idiomatic/welcome.md +msgid "" +"Use well-established API design patterns that we will discuss later in this " +"class (e.g., newtype, owned/view type pairs, error handling)" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "" +"Write meaningful and effective doc comments (e.g., don't merely repeat the " +"method name with spaces instead of underscores, don't repeat the same " +"information just to fill out every markdown tag, provide usage examples)" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "Leveraging the type system" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "Short recap on enums, structs and type aliases" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "Newtype pattern and encapsulation: parse, don't validate" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "" +"Extension traits: avoid the newtype pattern when you want to provide " +"additional behaviour" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "" +"RAII, scope guards and drop bombs: using `Drop` to clean up resources, " +"trigger actions or enforce invariants" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "" +"\"Token\" types: force users to prove they've performed a specific action" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "" +"The typestate pattern: enforce correct state transitions at compile-time" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "" +"Using the borrow checker to enforce invariants that have nothing to do with " +"memory ownership" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "OwnedFd/BorrowedFd in the standard library" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "[Branded types](https://plv.mpi-sws.org/rustbelt/ghostcell/paper.pdf)" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "Don't fight the borrow checker" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "" +"\"Owned\" types and \"view\" types: `&str` and `String`, `Path` and " +"`PathBuf`, etc." +msgstr "" + +#: src/idiomatic/welcome.md +msgid "" +"Don't hide ownership requirements: avoid hidden `.clone()`, learn to love " +"`Cow`" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "Split types along ownership boundaries" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "Structure your ownership hierarchy like a tree" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "" +"Strategies to manage circular dependencies: reference counting, using " +"indexes instead of references" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "Interior mutability (Cell, RefCell)" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "Working with lifetime parameters on user-defined data types" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "Polymorphism in Rust" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "A quick refresher on traits and generic functions" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "Rust has no inheritance: what are the implications?" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "Using enums for polymorphism" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "Using traits for polymorphism" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "Using composition" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "How do I pick the most appropriate pattern?" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "Working with generics" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "Generic type parameter in a function or trait object as an argument?" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "Trait bounds don't have to refer to the generic parameter" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "" +"Type parameters in traits: should it be a generic parameter or an associated " +"type?" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "" +"Macros: a valuable tool to DRY up code when traits are not enough (or too " +"complex)" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "What is the purpose of errors? Recovery vs. reporting." +msgstr "" + +#: src/idiomatic/welcome.md +msgid "Result vs. Option" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "Designing good errors:" +msgstr "" + +#: src/idiomatic/welcome.md +msgid "Determine the error scope." +msgstr "" + +#: src/idiomatic/welcome.md +msgid "" +"Capture additional context as the error flows upwards, crossing scope " +"boundaries." +msgstr "" + +#: src/idiomatic/welcome.md +msgid "Leverage the `Error` trait to keep track of the full error chain." +msgstr "" + +#: src/idiomatic/welcome.md +msgid "Leverage `thiserror` to reduce boilerplate when defining error types." +msgstr "" + +#: src/idiomatic/welcome.md +msgid "" +"Distinguish fatal errors from recoverable errors using `Result, FatalError>`." +msgstr "" + +#: src/idiomatic/foundations-api-design.md +msgid "This segment should take about 3 hours and 30 minutes. It contains:" +msgstr "" + +#: src/idiomatic/foundations-api-design.md +msgid "1 hour and 25 minutes" +msgstr "" + +#: src/idiomatic/foundations-api-design.md +msgid "2 hours and 5 minutes" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments.md +msgid "/// API for the client // ❌ Lacks detail\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments.md +msgid "/// Function from A to B // ❌ Redundant\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments.md +msgid "/// Connects to the database. // ❌ Lacks detail\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments.md +msgid "" +"Doc comments are the most common form of documentation developers engage " +"with." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments.md +msgid "" +"Good doc comments provide information that the code, names, and types " +"cannot, without restating the obvious information." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/who-are-you-writing-for.md +msgid "Who are you writing for?" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/who-are-you-writing-for.md +msgid "Colleagues, collaborators, largely-silent API users, or just yourself?" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/who-are-you-writing-for.md +msgid "" +"// expert writes for experts\n" +"/// Canonicalizes the MIR for the borrow checker. \n" +"/// \n" +"/// This pass ensures that all borrows conform to the NLL-Polonius " +"constraints \n" +"/// before we proceed to MIR-to-LLVM-IR translation. \n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/who-are-you-writing-for.md +msgid "" +"// expert writes for newcomers\n" +"/// Prepares the Mid-level IR (MIR) for borrow checking. \n" +"/// \n" +"/// The borrow checker operates on a simplified, \"canonical\" form of the " +"MIR. \n" +"/// This function performs that transformation. It is a prerequisite for " +"the \n" +"/// final stages of code generation. \n" +"/// \n" +"/// For more about Rust's intermediate representations, see the \n" +"/// [rustc-dev-guide](https://rustc-dev-guide.rust-lang.org/mir/index." +"html). \n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/who-are-you-writing-for.md +msgid "" +"Background: The [curse of knowledge](https://en.wikipedia.org/wiki/" +"Curse_of_knowledge) is a cognitive bias where experts assume that others " +"have the same level of expertise and perspective." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/who-are-you-writing-for.md +msgid "" +"Motivation: Your reader does not have the same level of expertise and the " +"same perspective as you. Don't write for people like yourself, write for " +"others." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/who-are-you-writing-for.md +msgid "" +"Unintentionally writing for yourself can lead to people not understanding a " +"point you're trying to make or the concept you're trying to articulate." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/who-are-you-writing-for.md +msgid "" +"Imagine a version of you, or others you've known, struggling to find " +"practical information while going through documentation." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/who-are-you-writing-for.md +msgid "" +"Keep this idea of a person in mind when thinking about what areas of a " +"codebase need attention for doc comments." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/who-are-you-writing-for.md +msgid "" +"Also imagine a version of you, or others you've known, who is struggling to " +"find the important details in winding, extensive doc comments. Don't give " +"too much information." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/who-are-you-writing-for.md +msgid "" +"Always ask: Is this documentation making it difficult for the API user? Are " +"they able to quickly grasp what they need or find out where they could need " +"it?" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/who-are-you-writing-for.md +msgid "" +"Always consider: Experts also read API level documentation. Doc comments " +"might not be the right place to educate your audience about the basics of " +"your domain. In that case, signpost and name-drop. Divert people to long-" +"form documentation." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/library-vs-application-docs.md +msgid "Library vs application docs" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/library-vs-application-docs.md +msgid "" +"You might see elaborate documentation for fundamental APIs that repeats the " +"names and type signatures. Stable and highly reusable code can afford this " +"with a positive RoI." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/library-vs-application-docs.md +msgid "Library code:" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/library-vs-application-docs.md +msgid "has a high number of users," +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/library-vs-application-docs.md +msgid "solves a whole range of related problems," +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/library-vs-application-docs.md +msgid "often has stable APIs." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/library-vs-application-docs.md +msgid "Application code is the opposite:" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/library-vs-application-docs.md +msgid "few users," +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/library-vs-application-docs.md +msgid "solves a specific problem," +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/library-vs-application-docs.md +msgid "changes often." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/library-vs-application-docs.md +msgid "" +"You might have seen elaborate documentation that repeats code, looks at the " +"same API multiple times with many examples and case studies. Context is key: " +"who wrote it, for whom, and what material it is covering, and what resources " +"did they have." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/library-vs-application-docs.md +msgid "" +"Fundamental library code often has Elaborate documentation, for example, the " +"standard library, highly reusable frameworks like serde and tokio. Teams " +"responsible for this code often have appropriate resources to write and " +"maintain elaborate documentation." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/library-vs-application-docs.md +msgid "" +"Library code is often stable, so the community is going to extract a " +"significant benefit from elaborate documentation before it needs to be " +"reworked." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/library-vs-application-docs.md +msgid "" +"Application code has the opposite traits: it has few users, solves a " +"specific problem, and changes often. For application code elaborate " +"documentation quickly becomes outdated and misleading. It is also difficult " +"to extract a positive RoI from boilerplate docs even while they are up to " +"date, because there are only a few users." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/anatomy-of-a-doc-comment.md +msgid "The Anatomy of a Doc Comment" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/anatomy-of-a-doc-comment.md +msgid "A brief, one-sentence summary." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/anatomy-of-a-doc-comment.md +msgid "A more detailed explanation." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/anatomy-of-a-doc-comment.md +msgid "Special sections: code examples, panics, errors, safety preconditions." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/anatomy-of-a-doc-comment.md +msgid "" +"/// Parses a key-value pair from a string.\n" +"///\n" +"/// The input string must be in the format `key=value`. Everything before " +"the\n" +"/// first '=' is treated as the key, and everything after is the value.\n" +"///\n" +"/// # Examples\n" +"///\n" +"/// ```\n" +"/// use my_crate::parse_key_value;\n" +"/// let (key, value) = parse_key_value(\"lang=rust\").unwrap();\n" +"/// assert_eq!(key, \"lang\");\n" +"/// assert_eq!(value, \"rust\");\n" +"/// ```\n" +"///\n" +"/// # Panics\n" +"///\n" +"/// Panics if the input is empty.\n" +"///\n" +"/// # Errors\n" +"///\n" +"/// Returns a `ParseError::Malformed` if the string does not contain `=`.\n" +"///\n" +"/// # Safety\n" +"///\n" +"/// Triggers undefined behavior if...\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/anatomy-of-a-doc-comment.md +msgid "" +"Idiomatic Rust doc comments follow a conventional structure that makes them " +"easier for developers to read." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/anatomy-of-a-doc-comment.md +msgid "" +"The first line of a doc comment is a single-sentence summary of the " +"function. Keep it concise. `rustdoc` and other tools have a strong " +"expectation about that: it is used as a short summary in module-level " +"documentation and search results." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/anatomy-of-a-doc-comment.md +msgid "" +"Next, you can provide a long, multi-paragraph description of the \"why\" and " +"\"what\" of the function. Use Markdown." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/anatomy-of-a-doc-comment.md +msgid "" +"Finally, you can use top-level section headers to organize your content. Doc " +"comments commonly use `# Examples`, `# Panics`, `# Errors`, and `# Safety` " +"as section titles. The Rust community expects to see relevant aspects of " +"your API documented in these sections." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/anatomy-of-a-doc-comment.md +msgid "" +"Rust heavily focuses on safety and correctness. Documenting behavior of your " +"code in case of errors is critical for writing reliable software." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/anatomy-of-a-doc-comment.md +msgid "" +"`# Panics`: If your function may panic, you must document the specific " +"conditions when that might happen. Callers need to know what to avoid." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/anatomy-of-a-doc-comment.md +msgid "" +"`# Errors`: For functions returning a `Result`, this section explains what " +"kind of errors can occur and under what circumstances. Callers need this " +"information to write robust error handling logic." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/anatomy-of-a-doc-comment.md +msgid "" +"**Question:** Ask the class why documenting panics is so important in a " +"language that prefers returning `Result`." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/anatomy-of-a-doc-comment.md +msgid "" +"**Answer:** Panics are for unrecoverable, programming errors. A library " +"should not panic unless a contract is violated by the caller. Documenting " +"these contracts is essential." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/anatomy-of-a-doc-comment.md +msgid "" +"`# Safety` comments document safety preconditions on unsafe functions that " +"must be satisfied, or else undefined behavior might result. They are " +"discussed in detail in the Unsafe Rust deep dive." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/name-drop-signpost.md +msgid "Name-dropping keywords and signposting topics" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/name-drop-signpost.md +msgid "" +"/// A parsed representation of a MARC 21 record\n" +"/// [leader](//www.loc.gov/marc/bibliographic/bdleader.html). \n" +"/// A MARC leader contains metadata that dictates how to interpret the " +"rest \n" +"/// of the record.\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/name-drop-signpost.md +msgid "" +"/// Determines the schema and the set of valid subsequent data fields. \n" +" ///\n" +" /// Encoded in byte 6 of the leader. \n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/name-drop-signpost.md +msgid "" +"/// Indicates whether to parse relationship fields, such as a \"773 Host \n" +" /// Item Entry\" for an article within a larger work. \n" +" /// \n" +" /// Encoded in byte 7 of the leader. \n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/name-drop-signpost.md +msgid "// ... other fields\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/name-drop-signpost.md +msgid "" +"/// Parses the [leader of a MARC 21 record](https://www.loc.gov/marc/" +"bibliographic/bdleader.html). \n" +"/// \n" +"/// The leader is encoded as a fixed-length 24-byte field, containing " +"metadata \n" +"/// that determines the semantic interpretation of the rest of the " +"record. \n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/name-drop-signpost.md +msgid "" +"Motivation: Readers of documentation will not be closely reading most of " +"your doc comments like they would dialogue in a novel they love." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/name-drop-signpost.md +msgid "" +"Users will most likely be skimming and scan-reading to find the part of the " +"documentation that is relevant to whatever problem they're trying to solve " +"in the moment." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/name-drop-signpost.md +msgid "" +"Once a user has found a keyword or potential signpost that's relevant to " +"them they will begin to search for context surrounding what is being " +"documented." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/name-drop-signpost.md +msgid "" +"Ask the class: What do you look for in documentation? Focus on the moment-to-" +"moment searching for information here, not general values in documentation." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/name-drop-signpost.md +msgid "Name-drop keywords close to the beginning of a paragraph." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/name-drop-signpost.md +msgid "" +"This aids skimming and scanning, as the first few words of a paragraph stand " +"out the most." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/name-drop-signpost.md +msgid "" +"Skimming and scanning lets users quickly navigate a text, keeping keywords " +"as close to the beginning of a paragraph as possible lets a user determine " +"if they've found relevant information faster." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/name-drop-signpost.md +msgid "Signpost, but don't over-explain." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/name-drop-signpost.md +msgid "" +"Users will not necessarily have the same domain expertise as an API designer." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/name-drop-signpost.md +msgid "" +"If a tangential, specialist term or acronym is mentioned try to bring in " +"enough context such that a novice could quickly do more research." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/name-drop-signpost.md +msgid "" +"Signposting often happens organically, consider a networking library that " +"mentions various protocols. But when it doesn't happen organically, it can " +"be difficult to choose what to mention." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/name-drop-signpost.md +msgid "" +"Rule of thumb: API developers should be asking themselves \"if a novice ran " +"into what they are documenting, what sources would they look up and are " +"there any red herrings they might end up following\"?" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/name-drop-signpost.md +msgid "" +"Users should be given enough information to look up subjects on their own." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/name-drop-signpost.md +msgid "" +"What we've already covered, predictability of an API including the naming " +"conventions, is a form of signposting." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "Avoiding Redundancy" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "" +"Names and type signatures communicate a lot of information, don't repeat it " +"in comments!" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "" +"// Repeats name/type information. Can omit!\n" +"/// Parses an ipv4 from a str. Returns an option for failure modes.\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "// Repeats information obvious from the field name. Can omit!\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "/// The customer id.\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "" +"// Mentions the type name first thing, don't do this!\n" +"/// `ServerSynchronizer` is an orchestrator that sends local edits [...]\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "" +"// Better! Focuses on purpose.\n" +"/// Sends local edits [...]\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "" +"// Mentions the function name first thing, don't do this!\n" +"/// `sync_to_server` sends local edits [...]\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "" +"// Better! Focuses on function.\n" +"/// Sends local edits [...]\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "" +"Motivation: Documentation that merely repeats name/signature information " +"provides nothing new to the API user." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "" +"Additionally, signature information may change over time without the " +"documentation being updated accordingly!" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "This is an understandable pattern to fall into!" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "" +"Naive approach to \"always document your code,\" follows this advice " +"literally but does not follow the intent." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "" +"Some tools might enforce documentation coverage, this kind of documentation " +"is an easy fix." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "Be aware of the purpose of different modes of documentation:" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "" +"Library code will need to be documented in ways that understand the scope of " +"what it is used for and the breadth of people who are trying to use it." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "" +"Application code has a more narrow purpose, it can afford to be more simple " +"and direct." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "The name of an item is part of the documentation of that item." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "" +"Similarly, the signature of a function is part of the documentation of that " +"function." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "" +"Therefore: Some aspects of the item are already covered when you start " +"writing doc comments!" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "Do not repeat information for the sake of an itemized list." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "" +"Many areas of the standard library have minimal documentation because the " +"name and types do give enough information." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "" +"Rule of Thumb: What information is missing from a user's perspective? Other " +"than name, signature, and irrelevant details of the implementation." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "" +"Don't explain the basics of Rust or the standard library. Assume the reader " +"of doc comments has an intermediate understanding of the language itself. " +"Focus on documenting your API." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "" +"For example, if your function returns `Result`, you don't need to explain " +"how `Result` or the question mark operators work." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "" +"If there is a complex topic involved with the functions and types you're " +"documenting, signpost to a \"source of truth\" if one exists such as an " +"internal document, a paper, a blog post etc." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "" +"Collaborate with Students: Go through the methods in the slide and discuss " +"what might be relevant to an API user." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "" +"The `#![warn(missing_docs)]` lint can be helpful for enforcing the existence " +"of doc comments, but puts a large burden on developers that could lead to " +"leaning onto these patterns of writing low-quality comments." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/avoid-redundancy.md +msgid "" +"This kind of lint should only be enabled if the people maintaining a project " +"can afford to keep up with its demands, and usually only for library-style " +"crates rather than application code." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-isnt-docs.md +msgid "Names and Signatures are not full documentation" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-isnt-docs.md +msgid "" +"// bad\n" +"/// Returns a future that resolves when operation completes. \n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-isnt-docs.md +msgid "" +"// good\n" +"/// Sends local edits to the server, overwriting concurrent edits \n" +"/// if any happened. \n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-isnt-docs.md +msgid "" +"// bad\n" +"/// Returns an error if sending the email fails. \n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-isnt-docs.md +msgid "" +"// good\n" +"/// Queues the email for background delivery and returns immediately. \n" +"/// Returns an error immediately if the email is malformed. \n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-isnt-docs.md +msgid "" +"Motivation: API designers can over-commit to the idea that a function name " +"and signature is enough documentation." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-isnt-docs.md +msgid "It's better than nothing, but it's worse than good documentation." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-isnt-docs.md +msgid "" +"Again, names and types are _part_ of the documentation. They are not always " +"the full story!" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-isnt-docs.md +msgid "" +"Consider the behavior of functions that are not covered by the name, " +"parameter names, or signature of that function." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-isnt-docs.md +msgid "" +"In the example on the slide it is not obvious that `sync_to_server()` could " +"overwrite something (leading to a data loss), so document that." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-isnt-docs.md +msgid "" +"In the email example, it is not obvious that the function can return success " +"and still fail to deliver the email." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-isnt-docs.md +msgid "" +"Use comments to disambiguate. Nuanced behaviors, behaviors that users of an " +"API could trip up on, should be documented." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-isnt-docs.md +msgid "" +"For example, consider a remove() method on a business entity: There are many " +"ways to remove an entity!" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-isnt-docs.md +msgid "" +"Is it removing the entity from the database? From the parent collection in " +"memory (unlink vs erase)?" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-isnt-docs.md +msgid "" +"If it is removing the data in the database, is the data actually being " +"deleted, or merely marked as deleted, but still recoverable (soft vs hard " +"delete)?" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-why-not-how-where.md +msgid "Why and What, not How and Where" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-why-not-how-where.md +msgid "Avoid documenting irrelevant details that may frequently change." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-why-not-how-where.md +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/exercise.md +msgid "/// Sorts a slice. Implemented using recursive quicksort.\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-why-not-how-where.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/complete.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-01-types.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-02-types-implemented.md +#: src/idiomatic/polymorphism/from-oop-to-rust/problem-solving.md +msgid "/* ... */" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-why-not-how-where.md +msgid "" +"// bad\n" +"/// Saves a `User` record to the Postgres database. \n" +"/// \n" +"/// This function opens a new connection and begins a transaction. It " +"checks \n" +"/// if a user with the given ID exists with a `SELECT` query. If a user " +"is \n" +"/// not found, performs an `INSERT`. \n" +"/// \n" +"/// # Errors \n" +"/// \n" +"/// Returns an error if any database operation fails. \n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-why-not-how-where.md +msgid "" +"// good\n" +"/// Atomically saves a user record. \n" +"/// \n" +"/// # Errors \n" +"/// \n" +"/// Returns a `db::Error::DuplicateUsername` error if the user (keyed by \n" +"/// `user.username` field) already exists. \n" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-why-not-how-where.md +msgid "" +"Motivation: Users want to know the contract of the API (what is guaranteed " +"about this function), rather than implementation details." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-why-not-how-where.md +msgid "" +"Motivation: Doc comments that explain implementation details become outdated " +"faster than comments that explain the contract." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-why-not-how-where.md +msgid "" +"Internal information is likely irrelevant to a user. Imagine explaining in a " +"doc comment for a function that you're using for loops to solve a problem, " +"what is the point of this information?" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-why-not-how-where.md +msgid "" +"Consider the `sort_quickly` function above. Its documentation calls out that " +"it uses quicksort, but is this necessary?" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-why-not-how-where.md +msgid "" +"It could be that another sorting function is used in the future, if that " +"were the case then this comment would need to be updated too. This is a " +"point of failure in documentation." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-why-not-how-where.md +msgid "" +"It could be that the implementation is necessary to explain, but this is " +"likely due to whatever effects or invariants the user of that API needs to " +"be aware of instead." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-why-not-how-where.md +msgid "" +"Focus on those effects and invariants instead of instead of the " +"implementation details themselves." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-why-not-how-where.md +msgid "" +"Reiterate: Implementation details can and will change, so do not explain " +"these details." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-why-not-how-where.md +msgid "Don't talk about where something is used for the sake of it." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-why-not-how-where.md +msgid "" +"This is another instance where this information can become stale quickly." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/what-why-not-how-where.md +msgid "" +"Focus on what the function does (not how it is implemented) for a user " +"trying to reach this practical information as quickly as possible." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/exercise.md +msgid "Exercise: Dialog on Details" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/exercise.md +msgid "" +"Unnecessary details can sometimes be indicative of something that does need " +"documentation." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/exercise.md +msgid "" +"Consider the example here, we discussed in [what and why, not how and where]" +"(what-why-not-how-where.md) that internal details are unlikely relevant to " +"someone reading documentation." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/exercise.md +msgid "Here we're discussing a counterexample." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/exercise.md +msgid "Ask the class: Is this comment necessary for this function?" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/exercise.md +msgid "" +"Narrative: Playing the part of an intermediary between the class and the " +"author, such as a PM, manager, etc. tell the class that the author of this " +"function is pushing back." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/exercise.md +msgid "Ask the class: Why would an author of this kind of comment push back?" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/exercise.md +msgid "" +"If the class asks why the author is pushing back, do not give details yet." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/exercise.md +msgid "" +"Ask the class: Why would the caller need to know the sorting algorithm in " +"use?" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/exercise.md +msgid "" +"Narrative: \"Come back\" from a meeting with the original author, explain to " +"the class that this function is application code that is called on untrusted " +"data that [could be crafted maliciously to cause quadratic behavior during " +"sorting](https://www.cs.dartmouth.edu/~doug/mdmspe.pdf)." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/exercise.md +msgid "" +"Ask the class: Now we have more detail, how should we comment this function?" +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/exercise.md +msgid "" +"The point being implementation detail vs not depends a lot on what the " +"public contract is (e.g., can you supply untrusted data or not), and this " +"requires careful judgement." +msgstr "" + +#: src/idiomatic/foundations-api-design/meaningful-doc-comments/exercise.md +msgid "" +"Consider if a comment is explaining that a for-loop is used (unnecessary " +"detail) or if it is explaining that the algorithms used internally have " +"known exploits (documentation draws attention to the wrong thing)." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api.md +msgid "" +"Keep your APIs predictable through naming conventions and implementing " +"common traits." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api.md +msgid "/* What traits should this implement? */" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api.md +msgid "// What should this method be called?\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api.md +msgid "" +"A predictable API is one where a user's can make assumptions about a part of " +"the API based on surface-level details like names, types, and signatures." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api.md +msgid "" +"We'll be looking at common naming conventions in Rust, which allow users to " +"search for methods that fit their needs quickly and be able to understand " +"existing code quickly." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api.md +msgid "" +"We will also be looking at common traits that types implement, and when to " +"implement them for types you define." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions.md +msgid "Naming Conventions" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions.md +msgid "" +"A formal and consistently-applied naming convention lets developers treat " +"names like a domain-specific language and quickly understand the " +"functionality and use cases of a method." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions.md +msgid "" +"Rust's community developed naming conventions early, making them mostly " +"consistent in places like the standard library." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions.md +msgid "" +"Here we'll learn common components of Rust method names, giving examples " +"from the standard library and some context to go with them." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/new.md +msgid "`new`: Constructor functions" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/new.md +msgid "" +"Rust does not have a `new` keyword, instead `new` is a common prefix or " +"whole method name." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/new.md +msgid "// Creates an empty vec.\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/new.md +msgid "" +"There's no `new` keyword for Rust to initialize a new value, only functions " +"you call or values you directly populate." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/new.md +msgid "" +"`new` is conventional for the \"default\" constructor function for a type. " +"It holds no special syntactic meaning." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/new.md +msgid "This is sometimes a prefix, it sometimes takes arguments." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/get.md +msgid "`get`: Borrow an Element" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/get.md +msgid "Getting an element from a collection or container." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/get.md +msgid "Immutable by default, for the most part." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/get.md +msgid "" +"Should not panic. May return an option or result, depending on the framework." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/get.md +msgid "Not for fields!" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/get.md +msgid "" +"For private fields you don't want users to have direct, assign a method with " +"a more descriptive name (or the same name as the field) is preferred." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/push.md +msgid "`push`" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/push.md +msgid "Common on array-like structures." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/push.md +msgid "Takes `self` by mutable reference." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/is.md +msgid "`is_[condition]`: Boolean Check" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/is.md +msgid "Check a condition about a datatype." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/is.md +msgid "`is` prefix is preferred over methods with `not` in the name." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/is.md +msgid "" +"There are no instances of `is_not_` in standard library methods, just use `!" +"value.is_[condition]`." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/mut.md +msgid "`[method]_mut`: Mutable reference access" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/mut.md +msgid "Suffix for access-style methods." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/mut.md +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/by.md +msgid "// Simplified\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/mut.md +msgid "Suffix that signifies the method gives access to a mutable reference." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/mut.md +msgid "Requires mutable access to the value you're calling this method on." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-constructor.md +msgid "`with` as constructor" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-constructor.md +msgid "" +"`with` as a constructor sets one value among a type while using default " +"values for the rest." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-constructor.md +msgid "`with` as in \"`` with specific setting.\"" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-constructor.md +msgid "// Initializes memory for at least N elements, len is still 0.\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-constructor.md +msgid "" +"`with` can appear as a constructor prefix, most commonly when initializing " +"heap memory for container types." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-constructor.md +msgid "" +"In this case, it's distinct from `new` constructors because it specifies the " +"value for something that is not usually cared about by API users." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-constructor.md +msgid "Ask the class: Why not `from_capacity`?" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-constructor.md +msgid "" +"Answer: `Vec::with_capacity` as a method call scans well as creating a \"Vec " +"with capacity\". Consider how `Vec::new_capacity` or `Vec::from_capacity` " +"scan when written down, they do not communicate what's going on well." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-copy-setter.md +msgid "`with` as copy-and-set" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-copy-setter.md +msgid "" +"`with` appears when a value is being copied, but also changed in a specific " +"way." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-copy-setter.md +msgid "`with` as in \"like ``, but with something different.\"" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-copy-setter.md +msgid "" +"// Simplified. \"/home/me/mortgage.pdf\".with_extension(\"mov\") =>\n" +" // \"/home/me/mortgage.mov\"\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-copy-setter.md +msgid "" +"`with` can be used for methods that copy a value, but then change a specific " +"part of that value." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-copy-setter.md +msgid "" +"In the example here, `with_extension` copies the data of a `&Path` into a " +"new `PathBuf`, but changes the extension to something else." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-copy-setter.md +msgid "The original `Path` is unchanged." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-closure.md +msgid "`with`: Working with Closures" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-closure.md +msgid "`with` as in \"do X, but with this specific way of computing things.\"" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-closure.md +msgid "" +"// Simplified. If the resize is larger than the current vec size, use the\n" +" // closure to populate elements.\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-closure.md +msgid "// Create an infinite, lazy iterator using a closure.\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-closure.md +msgid "" +"`with` can appear as a suffix to communicate there is a specific function or " +"closure that can be used instead of a \"sensible default\" for a computation." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-closure.md +msgid "Similar to [`by`](./by.md)." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-word.md +msgid "`with` in normal use" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-word.md +msgid "Sometimes a `with` is just a `with`." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-word.md +msgid "`with` when used in common English contexts." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-word.md +msgid "// impl block for slices\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-word.md +msgid "" +"// A condition, but doesn't start with `is`, and uses `with` as a normal " +"word.\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-word.md +msgid "" +"Name fragments are not hard rules, they are guidance. Sometimes a method's " +"name will include words that break its pattern." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-word.md +msgid "" +"In this example with have `starts_with`, which is a boolean condition that " +"does not start with \"is\" and is suffixed by \"with\"." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-word.md +msgid "" +"If naming conventions were to be treated as hard rules, this would fail as a " +"case." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-word.md +msgid "" +"This is a good name for understanding what is going on at the callsite. We " +"end up writing `.starts_with()` which scans well for " +"authors and readers of code." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/with-word.md +msgid "" +"Remember: the point of naming conventions is predictability, and how " +"predictability is in service of callsite clarity and readability." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/try.md +msgid "`try_[method]`: Fallible methods with Specific Errors" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/try.md +msgid "Prefix for fallible methods that return a `Result`." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/try.md +msgid "" +"`TryFrom` is a `From`\\-like trait for types whose single-value constructors " +"might fail in some way." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/try.md +msgid "Ask: Why aren't `Vec::get` and other similar methods called `try_get`?" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/try.md +msgid "" +"Methods are named `get` if they return a reference to an existing value and " +"return an `Option` instead of `Result` because there is only one failure " +"mode. For example, only \"index out of bounds\" for `Vec::get`, and \"key " +"does not exist\" for `HashMap::get`." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/from.md +msgid "`from`" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/from.md +msgid "A constructor function, strongly implying \"type conversion\"." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/from.md +msgid "" +"These functions can take multiple arguments, but usually imply the user is " +"doing more of the work than a usual constructor would." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/from.md +msgid "" +"`new` is still preferred for most constructor-style functions, the " +"implication for `from` is transformation of one data type to another." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/from.md +msgid "" +"Ask: Without looking at the standard library documentation, what would the " +"argument type of `u32::from_be` be?" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/from.md +msgid "" +"Answer guidance: we already see `u32::from_le_bytes` on the slide, it takes " +"a slice of bytes. So from_le must be simpler, taking not bytes. Think about " +"the contrast between `u32` and `be`. The argument must be a big-endian `u32`!" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/from.md +msgid "Follow-up question: How about `str::from_utf8`?" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/from.md +msgid "" +"Answer guidance: `str` vs `utf8`. The argument can't be a `str` because " +"every `str` is valid UTF-8. So what is the simplest way to provide UTF-8 " +"data? A slice of bytes." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/from.md +msgid "Follow-up: Why not `str::from_utf8_bytes`?" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/from.md +msgid "" +"Answer: It could be in theory. However, the \"omit needless words\" " +"principle applies, the word \"bytes\" would merely repeat the obvious - " +"could a UTF-8 sequence ever be non-bytes?" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into.md +msgid "`into`" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into.md +msgid "Prefix for methods that convert `self` into another type." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into.md +msgid "Consumes `self`, returns an owned value." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into.md +msgid "" +"Not reinterpret cast! The data can be rearranged, reallocated, changed in " +"any way, including losing information." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into.md +msgid "corollary to `From`" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into.md +msgid "" +"`into_iter` consumes a collection (like a vec, or a btreeset, or a hashmap) " +"and produces an iterator over owned values, unlike `iter` and `iter_mut` " +"which produce iterators over reference values." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into.md +msgid "Ask the class: what will `Vec::into_raw_parts` do?" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into_inner.md +msgid "Aside: `into_inner`" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into_inner.md +msgid "" +"Special case of `into`: for exclusive pointer types or newtypes, extract the " +"internal value." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into_inner.md +msgid "" +"`into_inner` is a method usually found on newtypes: types whose main purpose " +"is to wrap around an existing type and be semantically distinct from other " +"uses of that inner type." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into_inner.md +msgid "" +"This kind of method is also found on types like `Cell`, which exclusively " +"own the internal data." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into_inner.md +msgid "" +"The purpose of this kind of method is to consume the \"wrapper\" type and " +"return the \"contained\" value." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into_inner.md +msgid "" +"When defining a type with exactly one field, consider if it makes sense to " +"implement an `into_inner` method that consumes `self` and returns the field " +"as an owned value." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/into_inner.md +msgid "" +"Don't write a method like this if more fields will be added in the future." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/by.md +msgid "`by`: custom comparator or projection" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/by.md +msgid "" +"Component for methods that take a custom projection or comparison function." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/by.md +msgid "" +"// Uses a predicate to determine what items end up in non-overlapping " +"chunks.\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/by.md +msgid "// Provided method of Iterator. Simplified.\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/by.md +msgid "" +"A projection function here being a function that, given a reference to a " +"value that exists in the data structure, will compute a value to perform the " +"principle computation with." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/by.md +msgid "" +"Methods like `sort_by_key` allow us to sort by _the hash function I've " +"passed to the method_ or sort by _this specific field of the data in the " +"slice_." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/by.md +msgid "" +"For example, if you have a slice of values of some data structure you might " +"want to sort them by a field of that data structure, or even a hash value of " +"that data." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/by.md +msgid "`sort_by` takes a comparator function directly." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/by.md +msgid "" +"Most often seen in methods that sort or otherwise manipulate a slice with a " +"custom sort or comparison function rather than by the `Ord` implementation " +"of the type itself." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/by.md +msgid "Sometimes the \"by\" preposition is simply a preposition." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/by.md +msgid "" +"\"by\", like some other name components, may end up in a method name for " +"normal linguistic reasons rather than holding specific naming convention " +"semantic weight." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/by.md +msgid "" +"[`Read::by_ref()`](https://doc.rust-lang.org/std/io/trait.Read.html#method." +"by_ref)" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/by.md +msgid "" +"[`Iterator::advance_by()`](https://doc.rust-lang.org/std/iter/trait.Iterator." +"html#method.advance_by) iterator method (nightly feature)" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/unchecked.md +msgid "`unchecked`: Unsafe" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/unchecked.md +msgid "`unchecked` distinguishes the unsafe function in a safe/unsafe pair." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/unchecked.md +msgid "Don't add \"unchecked\" to the name of every unsafe function." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/unchecked.md +msgid "// A checked version of the constructor, `None` on null.\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/unchecked.md +msgid "// Unchecked constructor, you can violate the non-null invariant!\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/unchecked.md +msgid "// Panics on OOB, old API design.\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/unchecked.md +msgid "// Newer method, returns `None` if mid > len\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/unchecked.md +msgid "" +"// Unchecked split function, splitting out of bounds is undefined behavior!\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/unchecked.md +msgid "" +"Please take the Unsafe Rust deep dive if you want to learn more about unsafe " +"code. Briefly, unsafe functions transfer the responsibility for memory " +"safety from the compiler to the programmer. If misused, they can trigger " +"undefined behavior." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/unchecked.md +msgid "" +"Rust does not overload functions on safety, so we use different names for " +"the functions in the pair. To make the names predictable for users, we use a " +"naming convention." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/unchecked.md +msgid "" +"The safe function gets the short name. We add \"unchecked\" to the name of " +"the unsafe function." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/unchecked.md +msgid "We don't add \"unchecked\" to the name of every unsafe function." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/unchecked.md +msgid "" +"In Rust we don't need a naming convention to highlight the danger of unsafe " +"code at the callsite: Rust already requires the caller to write an `unsafe {}" +"` block. This is different from other languages that don't have unsafe " +"blocks, for example, Swift naming convention is to add the word \"unsafe\" " +"to the type and function names." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/unchecked.md +msgid "" +"We only use this naming convention when we want to provide a function pair, " +"and therefore must use different names." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md +msgid "`to`: Non-consuming Conversion" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md +msgid "" +"Prefix to a function that takes a borrowed value and creates an owned value" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md +msgid "// &str is not consumed.\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md +msgid "// take an owned self because `u32` implements `Copy`\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md +msgid "" +"This is not a borrow checker escape hatch, or an instance of unsafe code. A " +"new value is created, the original data is left alone." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md +msgid "" +"Methods that start with \"to\" return a different type, and strongly imply a " +"non-trivial type conversion, or even a data transformation. For example, " +"`str::to_uppercase`." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md +msgid "" +"\"to\" methods most commonly take `&self`. However they can take `self` by " +"value if the type implements `Copy`: this also ensures that the conversion " +"method call does not consume `self`." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md +msgid "" +"If you simply want to define a method that takes `&self` and returns an " +"owned value of the same type, implement the `Clone` trait." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md +msgid "" +"Example: to_uppercase creates a version of a string with all uppercase " +"letters." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md +msgid "" +"If you want to define a method that consumes the source value, use the " +"\"into\" naming pattern." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md +msgid "" +"Also seen in functions that convert the endianness of primitives, or copy " +"and expose the value of a newtype." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md +msgid "" +"Ask the class: What's the difference between `to_owned` and `into_owned`?" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md +msgid "" +"Answer: `to_owned` appears on reference values like `&str`, whereas " +"`into_owned` appears on owned values that hold reference types, like `Cow` " +"(copy-on-write)." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/to.md +msgid "" +"Types like `Cow` can be owned while containing references that are borrowed, " +"so the owned value of `Cow` is consumed to create an owned value of the " +"reference type it was holding onto." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md +msgid "`as_` and `_ref`: reference conversions" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md +msgid "" +"`as` is a prefix for methods that convert references. `ref` is a suffix (but " +"prefer `as`.)" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md +msgid "`as` methods borrow out the primary piece of data contained in `&self`." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md +msgid "" +"Most commonly return references, but can also return a custom borrowing type " +"or an unsafe pointer." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md +msgid "// Very common on container types, see how it's also on Option.\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md +msgid "// Slices can be empty! So this is 0 or 1 elements.\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md +msgid "// Covered later.\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md +msgid "Method that returns a borrow of the primary piece of contained data." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md +msgid "" +"The borrowing relationship is most often straightforward: the return value " +"is a reference that borrows `self`." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md +msgid "Borrowing can also be subtle, and merely implied." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md +msgid "" +"The returned value could be a custom borrowing type, fore example, " +"`BorrowedFd` borrows `OwnedFd` through an explicit lifetime." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md +msgid "" +"We cover custom borrowing types later in this deep dive, [PhantomData: " +"OwnedFd & BorrowedFd](../../../leveraging-the-type-system/borrow-checker-" +"invariants/phantomdata-04-borrowedfd.md)." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md +msgid "" +"The returned value could borrow `self` only logically, for example, " +"`as_ptr()` methods return an unsafe pointer. The borrow checker does not " +"track borrowing for pointers." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md +msgid "" +"The type implementing an \"as\" method should contain one primary piece of " +"data that is being borrowed out." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md +msgid "" +"The \"as\" naming convention does not work if the data type is an aggregate " +"of many fields without an obvious primary one. Think about the call site:" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md +msgid "// OK\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md +msgid "// does not read right, don't use \"as_\"\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/as-and-ref.md +msgid "" +"If you want to have two getters that you need to distinguish, one that " +"returns first name by value, and another one that returns it by reference, " +"use `_ref` suffix:" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/raw_parts.md +msgid "`raw_parts`" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/raw_parts.md +msgid "Peeling back safe abstractions on heap data." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/raw_parts.md +msgid "// Note how this is an unsafe function\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/raw_parts.md +msgid "" +"`raw_parts` denotes methods that construct items from or decompose items " +"into underlying pointer data and its relevant layout information (capacity, " +"etc.)." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/raw_parts.md +msgid "" +"These kinds of methods can be marked as `unsafe` if constructing new values " +"as trust is placed on the user to avoid conditions that might lead to " +"undefined behavior." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/raw_parts.md +msgid "" +"Such a case might be passing a pointer of `sizeof T * 10` to `Vec::" +"from_raw_parts` but also passing `20` as the capacity argument, which would " +"lead to writing or accessing values 10 through 19 in the vector being " +"undefined behavior." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/exercise.md +msgid "What do these names imply they do?" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/exercise.md +msgid "What should we name these signatures?" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/exercise.md +msgid "// What are the types of these methods?\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/exercise.md +msgid "// ?\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/exercise.md +msgid "// What should we name methods with these types?\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/exercise.md +msgid "// details for InnerType do not matter.\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/exercise.md +msgid "" +"Go through the methods in the example with the class and discuss what the " +"types of the functions should be." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/exercise.md +msgid "" +"Go through the unnamed methods and brainstorm what names those methods " +"should have." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/exercise.md +msgid "Answers for missing types:" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/exercise.md +msgid "`Option::is_some(&self) -> bool`" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/exercise.md +msgid "`slice::get(&self /* &[T] */, usize) -> Option<&T>`" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/exercise.md +msgid "" +"`slice::get_unchecked_mut(&self /* &[T] */, usize) -> &T` (unsafe and " +"simplified)" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/exercise.md +msgid "`Option::as_ref(&self /* &Option */) -> Option<&T>`" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/exercise.md +msgid "`str::from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str` (unsafe)" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/exercise.md +msgid "" +"`Rc::get_mut(&mut self /* &mut Rc */) -> Option<&mut T>` (simplified)" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/exercise.md +msgid "" +"`Vec::dedup_by_key(&mut self /* &mut Vec */, key: impl " +"FnMut(&mut T) -> K)` (simplified)" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/exercise.md +msgid "Answers for missing names:" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/exercise.md +msgid "`fn from_string(String) -> Self`" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/exercise.md +msgid "" +"`fn inner(&self) -> Option<&InnerType>` or `as_ref`, depending on context" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/exercise.md +msgid "`fn with_string(self, String) -> Self`" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/naming-conventions/exercise.md +msgid "" +"`fn inner_mut(&mut self) -> Option<&mut InnerType>` or `as_ref_mut`, " +"depending on context" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits.md +msgid "Common Traits to Implement" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits.md +msgid "" +"Traits should be liberally implemented on types you author, but there are " +"caveats!" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits.md +msgid "" +"Remember, many traits have the ability to be _derived_: to have a compiler " +"plugin (macro) write the implementation for you!" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits.md +msgid "" +"Authors of ecosystem traits (like De/Serialize) have made derive " +"implementations for traits available to users, leading to very little " +"commitment needed on the developer side for implementing these kinds of " +"traits!" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/debug.md +msgid "\"Write to string\" trait, for debug purposes." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/debug.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialeq-eq.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialord-ord.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/hash.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/clone.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/copy.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/serde.md +msgid "Derivable: ✅" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/debug.md +msgid "When to implement: Almost always" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/debug.md +msgid "" +"// pub trait Debug {\n" +"// fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>;\n" +"// }\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/debug.md +msgid "\"PlainTextPassword\"" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/debug.md +msgid "\"hint\"" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/debug.md +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/semantic-confusion.md +msgid "\"password\"" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/debug.md +msgid "\"[omitted]\"" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/debug.md +msgid "\"{user:?}\"" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/debug.md +#: src/idiomatic/leveraging-the-type-system/token-types/permission-tokens.md +msgid "\"Password123\"" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/debug.md +msgid "\"Used it for years\"" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/debug.md +msgid "" +"Formatting for _debug information_ for programmers during , not appearance " +"or serialization." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/debug.md +msgid "" +"Allows for use of `{:?}` and `{#?}` interpolation in string formatting " +"macros." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/debug.md +msgid "" +"When to not derive/implement: If a struct holds sensitive data, investigate " +"if you should implement Debug for it." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/debug.md +msgid "" +"If Debug is needed, consider manually implementing Debug rather than " +"deriving it. Omit the sensitive data from the implementation." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialeq-eq.md +msgid "Partial equality & Total equality." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialeq-eq.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialord-ord.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/hash.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/serde.md +msgid "When to implement: Almost always." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialeq-eq.md +msgid "" +"// pub trait PartialEq\n" +"//{\n" +"// // Required method\n" +"// fn eq(&self, other: &Rhs) -> bool;\n" +"// \n" +"// // Provided method\n" +"// fn ne(&self, other: &Rhs) -> bool { ... }\n" +"// }\n" +"//\n" +"// pub trait Eq: PartialEq { }\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialeq-eq.md +msgid "\"alice\"" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialeq-eq.md +msgid "\"bob\"" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialeq-eq.md +msgid "A type can't implement `Eq` without implementing `PartialEq`." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialeq-eq.md +msgid "" +"Reminder: Partial means \"there are invalid members of this set for this " +"function.\"" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialeq-eq.md +msgid "" +"This doesn't mean that equality will panic, or that it returns a result, " +"just that there may be values that may not behave as you expect equality to " +"behave." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialeq-eq.md +msgid "" +"For example, with floating point values `NaN` is an outlier: `NaN == NaN` is " +"false, despite bitwise equality." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialeq-eq.md +msgid "" +"`PartialEq` exists to separate types like f32/f64 from types with Total " +"Equality." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialeq-eq.md +msgid "" +"You can implement `PartialEq` between different types, but this is mostly " +"useful for reference/smart pointer types." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialord-ord.md +msgid "Partial ordering & Total ordering." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialord-ord.md +msgid "" +"// pub trait PartialOrd: PartialEq\n" +"// {\n" +"// // Required method\n" +"// fn partial_cmp(&self, other: &Rhs) -> Option;\n" +"//\n" +"// /* Provided methods omitted */\n" +"// }\n" +"// pub trait Ord: Eq + PartialOrd {\n" +"// // Required method\n" +"// fn cmp(&self, other: &Self) -> Ordering;\n" +"//\n" +"// /* Provided methods omitted */\n" +"// }\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialord-ord.md +msgid "`Ord` gives access to `min`, `max`, and `clamp` methods." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialord-ord.md +msgid "When derived, compares things in the order they are defined." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialord-ord.md +msgid "" +"For enums this means each variant is considered \"greater than\" the last as " +"they are written." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialord-ord.md +msgid "" +"For structs this means fields are compared as they are written, so `id` " +"fields are compared before `name` fields in `Totally`." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialord-ord.md +msgid "Prerequisites: `PartialEq` for `PartialOrd`, `Eq` for `Ord`." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialord-ord.md +msgid "" +"To implement `Ord`, a type must also implement `PartialEq`, `Eq`, and " +"`PartialOrd`." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialord-ord.md +msgid "" +"Like with `PartialEq` and `Eq`, a type cannot implement `Ord` without " +"implementing `PartialOrd`." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialord-ord.md +msgid "" +"Like those equality traits, `PartialOrd` exists to separate types with non-" +"total ordering (particularly floating-point numbers) from types with total " +"ordering." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/partialord-ord.md +msgid "" +"Used for sorting/searching algorithms and maintaining the ordering of " +"`BTreeMap`/`BTreeSet` style data types." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/hash.md +msgid "Performing a hash on a type." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/hash.md +msgid "" +"// pub trait Hash {\n" +"// // Required method\n" +"// fn hash(&self, state: &mut H)\n" +"// where H: Hasher;\n" +"//\n" +"// // Provided method\n" +"// fn hash_slice(data: &[Self], state: &mut H)\n" +"// where H: Hasher,\n" +"// Self: Sized { ... }\n" +"// }\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/hash.md +msgid "Most commonly used with data structures like `HashMap`." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/clone.md +msgid "Deep-copy a type or duplicate a smart, shareable pointer." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/clone.md +msgid "When to implement: If duplicating doesn't break invariants." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/clone.md +msgid "" +"// pub trait Clone: Sized {\n" +"// // Required method\n" +"// fn clone(&self) -> Self;\n" +"// \n" +"// // Provided methods omitted\n" +"// }\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/clone.md +msgid "// Copies the reference-counted pointer, not the value.\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/clone.md +msgid "" +"\"Deep copy\" a value, or in the case of reference counting pointers like " +"`Rc`/`Arc` create a new instance of that pointer." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/clone.md +msgid "" +"When to not implement/derive: For types that, to maintain an invariant, the " +"value should not be duplicated. We'll touch on this later in Idiomatic Rust." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/copy.md +msgid "Like `Clone`, but indicates the type is can be bitwise copied." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/copy.md +msgid "When to implement: If possible, but with caveats." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/copy.md +msgid "" +"// Copy is just a marker trait with Clone as a supertrait.\n" +"// pub trait Copy: Clone { }\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/copy.md +msgid "" +"When not to implement/derive: If you do not want to implicitly create copies " +"when dereferencing values of a type, do not implement this trait." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/copy.md +msgid "" +"Copy enables implicit duplication, so be careful about what types you're " +"implementing this on." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/copy.md +msgid "" +"Ask the class: Can a type with heap data (`Vec`, `BTreeMap`, `Rc`, etc.) be " +"copy? Should it be?" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/copy.md +msgid "It both cannot and should not, this is a misuse of this trait." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/copy.md +msgid "" +"Bitwise copying on these types would mean types with heap data would no " +"longer have exclusive ownership of a pointer, breaking the invariants " +"usually upheld by Rust and its ecosystem." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/copy.md +msgid "" +"Multiple `Vec`s would point to the same data in memory. Adding and removing " +"data would only update individual `Vec`s length and capacity values. The " +"same for `BTreeMap`." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/copy.md +msgid "" +"Bitwise copying of `Rc`s would not update the reference counting value " +"within the pointers, meaning there could be two instances of a `Rc` value " +"that believe themselves to be the only `Rc` for that pointer. Once one of " +"them is destroyed, the reference count will become 0 on one of them and the " +"inner value dropped despite there being another `Rc` still alive." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/serde.md +msgid "Serialize/Deserialize style traits" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/serde.md +msgid "Crates like `serde` can implement serialization automatically." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/serde.md +msgid "" +"When not to implement: If a type contains sensitive data that should not be " +"erroneously saved to disk or sent over a network, consider not implementing " +"Serialize/Deserialize for that type." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/serde.md +msgid "" +"Shares security concerns with `Debug`, but given serialization is often used " +"in networking there can be higher stakes." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/from-into.md +msgid "From & Into" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/from-into.md +msgid "Conversion from one type to another." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/from-into.md +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/display.md +msgid "Derivable: ❌, without crates like `derive_more`." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/from-into.md +msgid "When to implement: As-needed and convenient." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/from-into.md +msgid "// From String\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/from-into.md +msgid "\"Hello, obvious!\"" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/from-into.md +msgid "// From &str\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/from-into.md +msgid "" +"// A From implementation implies an Into implementation, &str.into() ->\n" +" // ObviousImplementation\n" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/from-into.md +msgid "\"Hello, implementation!\"" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/from-into.md +msgid "" +"The two traits exist to express different areas you'll find conversion in " +"codebases." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/from-into.md +msgid "" +"`From` provides a constructor-style function, whereas into provides a method " +"on an existing value." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/from-into.md +msgid "" +"Prefer writing `From` implementations for a type you're authoring instead " +"of `Into`." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/from-into.md +msgid "" +"The `Into` trait is implemented for any type that implements `From` " +"automatically." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/from-into.md +msgid "" +"`Into` is preferred as a trait bound for arguments to functions for clarity " +"of intent for what the function can take." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/from-into.md +msgid "`T: Into` has clearer intent than `String: From`." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/try-from-into.md +msgid "TryFrom/TryInto" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/try-from-into.md +msgid "Fallible conversion from one type to another." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/try-from-into.md +msgid "Derivable: ❌" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/try-from-into.md +msgid "When to implement: As-needed." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/try-from-into.md +msgid "" +"Like `From`/`Into`, prefer implementing `TryFrom` for types rather than " +"`TryInto`." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/try-from-into.md +msgid "Implementations can specify what the error type of the `Result`." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/display.md +msgid "\"Write to string\" trait, prioritizing readability for an end user." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/display.md +msgid "" +"When to implement: As-needed, for errors and other types that an end-user " +"will see." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/display.md +msgid "\"HTTP Error code {code}\"" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/display.md +msgid "\"Whale attack detected – call Ishmael\"" +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/display.md +msgid "Prerequisite for the `Error` trait." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/display.md +msgid "" +"If implementing for an error type, focus on providing a descriptive error " +"for users and programmers other than you." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/display.md +msgid "" +"Same security considerations as Debug, consider the ways that sensitive data " +"could be exposed in UI or logs." +msgstr "" + +#: src/idiomatic/foundations-api-design/predictable-api/common-traits/display.md +msgid "" +"Types that implement `Display` automatically have `ToString` implemented for " +"them." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system.md +msgid "" +"Rust's type system is _expressive_: you can use types and traits to build " +"abstractions that make your code harder to misuse." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system.md +msgid "" +"In some cases, you can go as far as enforcing correctness at _compile-time_, " +"with no runtime overhead." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system.md +msgid "" +"Types and traits can model concepts and constraints from your business " +"domain. With careful design, you can improve the clarity and maintainability " +"of the entire codebase." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system.md +msgid "Additional items speaker may mention:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system.md +msgid "" +"Rust's type system borrows a lot of ideas from functional programming " +"languages." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system.md +msgid "" +"For example, Rust's enums are known as \"algebraic data types\" in languages " +"like Haskell and OCaml. You can take inspiration from learning material " +"geared towards functional languages when looking for guidance on how to " +"design with types. [\"Domain Modeling Made Functional\"](https://pragprog." +"com/titles/swdddf/domain-modeling-made-functional/) is a great resource on " +"the topic, with examples written in F#." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system.md +msgid "" +"Despite Rust's functional roots, not all functional design patterns can be " +"easily translated to Rust." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system.md +msgid "" +"For example, you must have a solid grasp on a broad selection of advanced " +"topics to design APIs that leverage higher-order functions and higher-kinded " +"types in Rust." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system.md +msgid "" +"Evaluate, on a case-by-case basis, whether a more imperative approach may be " +"easier to implement. Consider using in-place mutation, relying on Rust's " +"borrow-checker and type system to control what can be mutated, and where." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system.md +msgid "" +"The same caution should be applied to object-oriented design patterns. Rust " +"doesn't support inheritance, and object decomposition should take into " +"account the constraints introduced by the borrow checker." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system.md +msgid "" +"Mention that type-level programming can be often used to create \"zero-cost " +"abstractions\", although the label can be misleading: the impact on compile " +"times and code complexity may be significant." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system.md +msgid "This segment should take about 7 hours and 30 minutes. It contains:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system.md +msgid "1 hour and 50 minutes" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system.md +msgid "1 hour and 30 minutes" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system.md +msgid "1 hour and 35 minutes" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern.md +msgid "A _newtype_ is a wrapper around an existing type, often a primitive:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern.md +msgid "/// A unique user identifier, implemented as a newtype around `u64`.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern.md +msgid "" +"Unlike type aliases, newtypes aren't interchangeable with the wrapped type:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern.md +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/semantic-confusion.md +#: src/idiomatic/leveraging-the-type-system/extension-traits.md +msgid "// đŸ› ī¸âŒ\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern.md +msgid "" +"The Rust compiler won't let you use methods or operators defined on the " +"underlying type either:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern.md +msgid "" +"Students should have encountered the newtype pattern in the \"Fundamentals\" " +"course, when they learned about [tuple structs](../../user-defined-types/" +"tuple-structs.md)." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern.md +msgid "Run the example to show students the error message from the compiler." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern.md +msgid "" +"Modify the example to use a typealias instead of a newtype, such as `type " +"MessageId = u64`. The modified example should compile, thus highlighting the " +"differences between the two approaches." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern.md +msgid "" +"Stress that newtypes, out of the box, have no behaviour attached to them. " +"You need to be intentional about which methods and operators you are willing " +"to forward from the underlying type. In our `UserId` example, it is " +"reasonable to allow comparisons between `UserId`s, but it wouldn't make " +"sense to allow arithmetic operations like addition or subtraction." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/semantic-confusion.md +msgid "" +"When a function takes multiple arguments of the same type, call sites are " +"unclear:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/semantic-confusion.md +#: src/idiomatic/leveraging-the-type-system/raii.md +#: src/idiomatic/leveraging-the-type-system/raii/scope_guard.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/root.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/struct.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/property.md +msgid "// [...]\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/semantic-confusion.md +msgid "\"username\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/semantic-confusion.md +msgid "" +"// In another part of the codebase, we swap arguments by mistake.\n" +"// Bug (best case), security vulnerability (worst case)\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/semantic-confusion.md +msgid "The newtype pattern can prevent this class of errors at compile time:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/semantic-confusion.md +msgid "" +"Run both examples to show students the successful compilation for the " +"original example, and the compiler error returned by the modified example." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/semantic-confusion.md +msgid "" +"Stress the _semantic_ angle. The newtype pattern should be leveraged to use " +"distinct types for distinct concepts, thus ruling out this class of errors " +"entirely." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/semantic-confusion.md +msgid "" +"Nonetheless, note that there are legitimate scenarios where a function may " +"take multiple arguments of the same type. In those scenarios, if correctness " +"is of paramount importance, consider using a struct with named fields as " +"input:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/semantic-confusion.md +msgid "" +"// No need to check the definition of the `login` function to spot the " +"issue.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/semantic-confusion.md +msgid "" +"Users are forced, at the callsite, to assign values to each field, thus " +"increasing the likelihood of spotting bugs." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/parse-don-t-validate.md +msgid "The newtype pattern can be leveraged to enforce _invariants_." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/parse-don-t-validate.md +msgid "// Other validation checks...\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/parse-don-t-validate.md +msgid "" +"The newtype pattern, combined with Rust's module and visibility system, can " +"be used to _guarantee_ that instances of a given type satisfy a set of " +"invariants." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/parse-don-t-validate.md +msgid "" +"In the example above, the raw `String` stored inside the `Username` struct " +"can't be accessed directly from other modules or crates, since it's not " +"marked as `pub` or `pub(in ...)`. Consumers of the `Username` type are " +"forced to use the `new` method to create instances. In turn, `new` performs " +"validation, thus ensuring that all instances of `Username` satisfy those " +"checks." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/parse-don-t-validate.md +msgid "" +"The `as_str` method allows consumers to access the raw string representation " +"(e.g., to store it in a database). However, consumers can't modify the " +"underlying value since `&str`, the returned type, restricts them to read-" +"only access." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/parse-don-t-validate.md +msgid "Type-level invariants have second-order benefits." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/parse-don-t-validate.md +msgid "" +"The input is validated once, at the boundary, and the rest of the program " +"can rely on the invariants being upheld. We can avoid redundant validation " +"and \"defensive programming\" checks throughout the program, reducing noise " +"and improving performance." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/is-it-encapsulated.md +msgid "Is It Truly Encapsulated?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/is-it-encapsulated.md +msgid "" +"You must evaluate _the entire API surface_ exposed by a newtype to determine " +"if invariants are indeed bullet-proof. It is crucial to consider all " +"possible interactions, including trait implementations, that may allow users " +"to bypass validation checks." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/is-it-encapsulated.md +msgid "// Validation checks...\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/is-it-encapsulated.md +msgid "// â€ŧī¸\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/is-it-encapsulated.md +msgid "" +"`DerefMut` allows users to get a mutable reference to the wrapped value." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/is-it-encapsulated.md +msgid "" +"The mutable reference can be used to modify the underlying data in ways that " +"may violate the invariants enforced by `Username::new`!" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/is-it-encapsulated.md +msgid "" +"When auditing the API surface of a newtype, you can narrow down the review " +"scope to methods and traits that provide mutable access to the underlying " +"data." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/is-it-encapsulated.md +msgid "Remind students of privacy boundaries." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/newtype-pattern/is-it-encapsulated.md +msgid "" +"In particular, functions and methods defined in the same module of the " +"newtype can access its underlying data directly. If possible, move the " +"newtype definition to its own separate module to reduce the scope of the " +"audit." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii.md +msgid "RAII: `Drop` trait" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii.md +msgid "" +"RAII (**R**esource **A**cquisition **I**s **I**nitialization) ties the " +"lifetime of a resource to the lifetime of a value." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii.md +msgid "" +"[Rust uses RAII to manage memory](https://doc.rust-lang.org/rust-by-example/" +"scope/raii.html), and the `Drop` trait allows you to extend this to other " +"resources, such as file descriptors or locks." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii.md +msgid "b\"example\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii.md +msgid "\"example.txt\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii.md +msgid "\"content: {:?}\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii.md +msgid "" +"Easy to miss: `file.close()` is never called. Ask the class if they noticed." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii.md +msgid "" +"To release the file descriptor correctly, `file.close()` must be called " +"after the last use — and also in early-return paths in case of errors." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii.md +msgid "" +"Instead of relying on the user to call `close()`, we can implement the " +"`Drop` trait to release the resource automatically. This ties cleanup to the " +"lifetime of the `File` value." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii.md +msgid "// libc::close(...);\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii.md +msgid "\"file descriptor was closed\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii.md +msgid "" +"Note that `Drop::drop()` cannot return a `Result`. Any failures must be " +"handled internally or ignored. In the standard library, errors during FD " +"closure inside `Drop` are silently discarded. See the implementation: " +"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii.md +msgid "When is `Drop::drop` called?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii.md +msgid "" +"Normally, when the `file` variable in `main()` goes out of scope (either on " +"return or due to a panic), `drop()` is called automatically." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii.md +msgid "" +"If the file is moved into another function (as is this case with `File::" +"close()`), the value is dropped when that function returns — not in `main`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii.md +msgid "" +"In contrast, C++ runs destructors in the original scope even for moved-from " +"values." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii.md +msgid "" +"Demo: insert `panic!(\"oops\")` at the start of `read_to_end()` and run it. " +"`drop()` still runs during unwinding." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii.md +msgid "The `Drop` trait has another important limitation: it is not `async`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii.md +msgid "" +"This means you cannot `await` inside a destructor, which is often needed " +"when cleaning up asynchronous resources like sockets, database connections, " +"or tasks that must signal completion to another system." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii.md +msgid "" +"Learn more: " +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii.md +msgid "" +"There is an experimental `AsyncDrop` trait available on nightly: " +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "Drop can be skipped" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "There are cases where destructors will not run." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "\"OwnedFd::drop() called with raw fd: {:?}\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "\"TmpFile::drop() called with owned fd: {:?}\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "" +"// libc::unlink(\"/tmp/file\")\n" +" // panic!(\"TmpFile::drop() panics\");\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "\"TmpFile::close(): not implemented yet\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "// std::mem::forget(file);\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "// file.close();\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "" +"Drop is not guaranteed to always run. There is a number of cases when drop " +"is skipped: the program can crash or exit, the value with the drop " +"implementation can be leaked etc." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "" +"In the version that calls [`std::process::exit`](https://doc.rust-lang.org/" +"std/process/fn.exit.html), `TmpFile::drop()` is never run because `exit()` " +"terminates the process immediately without any opportunity for a `drop()` " +"method to be called." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "" +"You can prevent accidental use of `exit` by denying the [`clippy::exit`]" +"(https://rust-lang.github.io/rust-clippy/stable/index.html#exit) lint." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "" +"If you remove the `std::process::exit(0)` line, each `drop()` method in this " +"simple case will run in turn." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "" +"Try uncommenting the [`std::mem::forget`](https://doc.rust-lang.org/std/mem/" +"fn.forget.html) call. What do you think will happen?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "" +"`mem::forget()` takes ownership and \"forgets\" about the value `file` " +"without running its **destructor** `Drop::drop()`. The destructor of " +"`owned_fd` is still run." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "" +"Remove the `mem::forget()` call, then uncomment the `file.close()` call " +"below it. What do you expect now?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "" +"With the default `panic = \"unwind\"` setting, the stack still unwinds and " +"destructors run, even when the panic starts in `main`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "" +"With [`panic = \"abort\"`](https://doc.rust-lang.org/cargo/reference/" +"profiles.html#panic) no destructors are run." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "" +"As a last step, uncomment the `panic!` inside `TmpFile::drop()` and run it. " +"Ask the class: which destructors run before the abort?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "" +"After a double panic, Rust no longer guarantees that remaining destructors " +"will run:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "" +"Some cleanup that was already in progress may still complete (for example, " +"field destructors of the value currently being dropped)," +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "" +"but anything scheduled later in the unwind path might be skipped entirely." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "" +"This is why we say you cannot rely solely on `drop()` for critical external " +"cleanup, nor assume that a double panic aborts without running any further " +"destructors." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "" +"Some languages forbid or restrict exceptions in destructors. Rust allows " +"panicking in `Drop::drop`, but it is almost never a good idea, since it can " +"disrupt unwinding and lead to unpredictable cleanup. It is best avoided " +"unless there is a very specific need, such as in the case of a **drop bomb**." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "" +"Drop is suitable for cleaning up resources within the scope of a process, " +"but it is not the right tool for providing hard guarantees that something " +"happens outside of the process (e.g., on local disk, or in another service " +"in a distributed system)." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "" +"For example, deleting a temporary file in `drop()` is fine in a toy example, " +"but in a real program you would still need an external cleanup mechanism " +"such as a temp file reaper." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_skipped.md +msgid "" +"In contrast, we can rely on `drop()` to unlock a mutex, since it is a " +"process-local resource. If `drop()` is skipped and the mutex is left locked, " +"it has no lasting effects outside the process." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/mutex.md +msgid "Mutex and MutexGuard" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/mutex.md +msgid "" +"In earlier examples, RAII was used to manage concrete resources like file " +"descriptors. With a `Mutex`, the \"resource\" is mutable access to a value. " +"You access the value by calling `lock`, which then returns a `MutexGuard` " +"which will unlock the `Mutex` automatically when dropped." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/mutex.md +msgid "\"{guard:?}\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/mutex.md +msgid "" +"A `Mutex` controls exclusive access to a value. Unlike earlier RAII " +"examples, the resource here is logical: temporary exclusive access to the " +"data inside." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/mutex.md +msgid "" +"This right is represented by a `MutexGuard`. Only one guard for this mutex " +"can exist at a time. While it lives, it provides `&mut T` access." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/mutex.md +msgid "" +"Although `lock()` takes `&self`, it returns a `MutexGuard` with mutable " +"access. This works through _interior mutability_, where a type manages its " +"own borrowing rules internally to allow mutation through `&self`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/mutex.md +msgid "" +"`MutexGuard` implements `Deref` and `DerefMut`, making access ergonomic. You " +"lock the mutex and use the guard like a `&mut T`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/mutex.md +msgid "" +"The mutex is released by `MutexGuard::drop()`. You never call an explicit " +"unlock function." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_guards.md +msgid "" +"A **drop guard** in Rust is a temporary object that performs some kind of " +"cleanup when it goes out of scope. In the case of `Mutex`, the `lock` method " +"returns a `MutexGuard` that automatically unlocks the mutex on `drop`:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_guards.md +msgid "The example above shows a simplified `Mutex` and its associated guard." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_guards.md +msgid "" +"Even though it is not a production-ready implementation, it illustrates the " +"core idea:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_guards.md +msgid "the guard represents exclusive access," +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_guards.md +msgid "" +"and its `Drop` implementation releases the lock when it goes out of scope." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_guards.md +msgid "" +"This example shows a C++ style mutex that does not contain the data it " +"protects. While this is non-idiomatic in Rust, the goal here is only to " +"illustrate the core idea of a drop guard, not to demonstrate a proper Rust " +"mutex design." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_guards.md +msgid "For brevity, several features are omitted:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_guards.md +msgid "" +"A real `Mutex` stores the protected value inside the mutex. \n" +"This toy example omits the value entirely to focus only on the drop guard " +"mechanism." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_guards.md +msgid "" +"Ergonomic access via `Deref` and `DerefMut` on `MutexGuard` (letting the " +"guard behave like a `&T` or `&mut T`)." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_guards.md +msgid "" +"A fully blocking `.lock()` method and a non-blocking `try_lock` variant." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_guards.md +msgid "" +"You can explore the [`Mutex` implementation in Rust’s std library](https://" +"doc.rust-lang.org/std/sync/struct.Mutex.html) as an example of a production-" +"ready mutex. The [`Mutex` from the `parking_lot` crate](https://docs.rs/" +"parking_lot/latest/parking_lot/type.Mutex.html) is another worthwhile " +"reference." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md +msgid "Drop Bombs: Enforcing API Correctness" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md +msgid "" +"Use `Drop` to enforce invariants and detect incorrect API usage. A \"drop " +"bomb\" panics if a value is dropped without being explicitly finalized." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md +msgid "" +"This pattern is often used when the finalizing operation (like `commit()` or " +"`rollback()`) needs to return a `Result`, which cannot be done from `Drop`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb_forget.md +msgid "\"COMMIT\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb_forget.md +msgid "\"Transaction dropped without commit!\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb_forget.md +msgid "" +"// Use `tx` to build the transaction, then commit it.\n" +" // Comment out the call to `commit` to see the panic.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md +msgid "" +"In some systems, a value must be finalized by a specific API before it is " +"dropped." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md +msgid "For example, a `Transaction` might need to be committed or rolled back." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md +msgid "" +"A drop bomb ensures that a value like `Transaction` cannot be silently " +"dropped in an unfinished state. The destructor panics if the transaction has " +"not been explicitly finalized (for example, with `commit()`)." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md +msgid "" +"The finalizing operation (such as `commit()`) usually takes `self` by value. " +"This ensures that once the transaction is finalized, the original object can " +"no longer be used." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md +msgid "" +"A common reason to use this pattern is when cleanup cannot be done in " +"`Drop`, either because it is fallible or asynchronous." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md +msgid "" +"This pattern is appropriate even in public APIs. It can help users catch " +"bugs early when they forget to explicitly finalize a transactional object." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md +msgid "" +"If cleanup can safely happen in `Drop`, some APIs choose to panic only in " +"debug builds. Whether this is appropriate depends on the guarantees your API " +"must enforce." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md +msgid "" +"Panicking in release builds is reasonable when silent misuse would cause " +"major correctness or security problems." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md +msgid "" +"Question: Why do we need an `active` flag inside `Transaction`? Why can't " +"`drop()` panic unconditionally?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md +msgid "" +"Expected answer: `commit()` takes `self` by value and runs `drop()`, which " +"would panic." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md +#: src/idiomatic/leveraging-the-type-system/raii/drop_option.md +#: src/idiomatic/leveraging-the-type-system/extension-traits/method-resolution-conflicts.md +msgid "More to explore" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md +msgid "" +"Several related patterns help enforce correct teardown or prevent accidental " +"drops." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb.md +msgid "" +"The [`drop_bomb` crate](https://docs.rs/drop_bomb/latest/drop_bomb/): A " +"small utility that panics if dropped unless explicitly defused with `." +"defuse()`. Comes with a `DebugDropBomb` variant that only activates in debug " +"builds." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb_forget.md +msgid "Drop Bombs: using `std::mem::forget`" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb_forget.md +msgid "// Defuse the drop bomb by preventing Drop from ever running.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb_forget.md +msgid "// This is the \"drop bomb\"\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb_forget.md +msgid "" +"This example removes the flag from the previous slide and makes the drop " +"method panic unconditionally. To avoid that panic on a successful commit, " +"the commit method now takes ownership of the transaction and calls [`std::" +"mem::forget`](https://doc.rust-lang.org/std/mem/fn.forget.html), which " +"prevents the `Drop::drop()` method from running." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb_forget.md +msgid "" +"If the forgotten value owned heap allocated memory that would normally be " +"freed in its `drop()` implementation, one consequence is a memory leak. That " +"is not the case for the `Transaction` in the example above, since it does " +"not own any heap memory." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_bomb_forget.md +msgid "" +"We can avoid needing a runtime flag by using `mem::forget()` in a tactical " +"way. When the transaction commits successfully, we can defuse the drop bomb " +"by calling `std::mem::forget` on the value, which prevents its `Drop` " +"implementation from running." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/forget_and_drop.md +msgid "" +"Below are the signatures for the [`drop()`](https://doc.rust-lang.org/std/" +"mem/fn.drop.html) and [`forget()`](https://doc.rust-lang.org/std/mem/fn." +"forget.html) functions:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/forget_and_drop.md +msgid "// std::mem::forget\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/forget_and_drop.md +msgid "// std::mem::drop\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/forget_and_drop.md +msgid "Both `mem::forget()` and `mem::drop()` take ownership of the value `t`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/forget_and_drop.md +msgid "Despite having the same function signature, they have opposite effects:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/forget_and_drop.md +msgid "" +"`forget()` uses [`ManuallyDrop`](https://doc.rust-lang.org/std/mem/struct." +"ManuallyDrop.html) to prevent the destructor `Drop::drop()` from being " +"invoked." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/forget_and_drop.md +msgid "" +"This is useful for scenarios such as implementing a drop bomb or otherwise " +"opting out of destructor behavior." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/forget_and_drop.md +msgid "" +"Be careful though, since any resources the value exclusively owns such as " +"heap allocated memory or file handles will remain in an unreachable state." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/forget_and_drop.md +msgid "" +"`drop()` is a convenience function for disposing of a value. Because `t` is " +"moved into the function, it is automatically dropped which triggers its " +"`Drop::drop()` implementation before the parent function returns." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/scope_guard.md +msgid "Scope Guards" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/scope_guard.md +msgid "" +"A scope guard uses the `Drop` trait to run cleanup code automatically when a " +"scope exits, even during unwinding." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/scope_guard.md +msgid "\"download.tmp\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/scope_guard.md +msgid "\"cannot create temporary file\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/scope_guard.md +msgid "// Set up cleanup immediately after file creation\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/scope_guard.md +msgid "\"download failed, deleting: {:?}\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/scope_guard.md +msgid "\"partial data...\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/scope_guard.md +msgid "// Download succeeded, keep the file\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/scope_guard.md +msgid "\"Download '{path}' complete!\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/scope_guard.md +msgid "// Otherwise, the guard runs and deletes the file\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/scope_guard.md +msgid "" +"This example models a download workflow. We create a temporary file first, " +"then use a scope guard to ensure that the file is deleted if the download " +"fails." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/scope_guard.md +msgid "" +"The `scopeguard` crate allows you to conveniently define a single-use " +"`Drop`\\-based cleanup without defining a custom type with a custom `Drop` " +"implementation." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/scope_guard.md +msgid "" +"The guard is created directly after creating the file, so even if `writeln!" +"()` fails, the file will still be cleaned up. This ordering is essential for " +"correctness." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/scope_guard.md +msgid "" +"The `guard()` creates a `ScopeGuard` instance. It a user-defined value (in " +"this case, `path`) and the cleanup closure that later receives this value." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/scope_guard.md +msgid "" +"The guard's closure runs on scope exit unless it is _defused_ with " +"`ScopeGuard::into_inner` (removing the value so the guard does nothing on " +"drop). In the success path, we call `into_inner` so the guard will not " +"delete the file." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/scope_guard.md +msgid "A scope guard is similar to the `defer` feature in Go." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/scope_guard.md +msgid "" +"This pattern is ideal for \"cleanup on failure\" scenarios, where a cleanup " +"should run by default unless a success path is explicitly taken." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/scope_guard.md +msgid "" +"This pattern is also useful when you don't control the cleanup strategy of " +"the resource object. In this example, `File::drop()` closes the file but " +"does not delete it, and we can't change the standard library to delete the " +"file instead (nor should we, it is not a good idea anyway)." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/scope_guard.md +msgid "" +"The `scopeguard` crate also supports cleanup strategies via the [`Strategy`]" +"(https://docs.rs/scopeguard/latest/scopeguard/trait.Strategy.html) trait. " +"You can choose to run the guard on unwind only, or on success only, not just " +"always." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_option.md +msgid "Drop: Option" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_option.md +msgid "\"write '{data}' to file '{}'\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_option.md +msgid "\"automatically closing handle for file: {}\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_option.md +msgid "\"closed handle for file: {}\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_option.md +msgid "\"manually closed file: {}\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_option.md +msgid "" +"In this example we want to let the user call `close()` manually so that " +"errors from closing the file can be reported explicitly." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_option.md +msgid "" +"At the same time we still want RAII semantics: if the user forgets to call " +"`close()`, the handle must be cleaned up automatically in `Drop`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_option.md +msgid "" +"Wrapping the handle in an `Option` gives us both behaviors. `close()` " +"extracts the handle with `take()`, and `Drop` only runs cleanup if a handle " +"is still present." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_option.md +msgid "" +"Demo: remove the `.close()` call and run the code — `Drop` now prints the " +"automatic cleanup." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_option.md +msgid "" +"The main downside is ergonomics. `Option` forces us to handle both the " +"`Some` and `None` case even in places where, logically, `None` cannot occur. " +"Rust’s type system cannot express that relationship between `File` and its " +"`Handle`, so we handle both cases manually." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_option.md +msgid "" +"Instead of `Option` we could use [`ManuallyDrop`](https://doc.rust-lang.org/" +"std/mem/struct.ManuallyDrop.html), which suppresses automatic destruction by " +"preventing Rust from calling `Drop` for the value; you must handle teardown " +"yourself." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_option.md +msgid "" +"The [_scopeguard_ example](./scope_guard.md) on the previous slide shows how " +"`ManuallyDrop` can replace `Option` to avoid handling `None` in places where " +"the value should always exist." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/raii/drop_option.md +msgid "" +"In such designs we typically track the drop state with a separate flag next " +"to the `ManuallyDrop`, which lets us track whether the handle has " +"already been manually consumed." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits.md +msgid "" +"It may desirable to **extend** foreign types with new inherent methods. For " +"example, allow your code to check if a string is a palindrome using method-" +"calling syntax: `s.is_palindrome()`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits.md +msgid "It might feel natural to reach out for an `impl` block:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits.md +msgid "" +"The Rust compiler won't allow it, though. But you can use the **extension " +"trait pattern** to work around this limitation." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits.md +msgid "A Rust item (be it a trait or a type) is referred to as:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits.md +msgid "**foreign**, if it isn't defined in the current crate" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits.md +msgid "**local**, if it is defined in the current crate" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits.md +msgid "" +"The distinction has significant implications for [coherence and orphan rules]" +"(https://doc.rust-lang.org/stable/reference/items/implementations.html#r-" +"items.impl.trait.orphan-rule), as we'll get a chance to explore in this " +"section of the course." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits.md +msgid "Compile the example to show the compiler error that's emitted." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits.md +msgid "" +"Highlight how the compiler error message nudges you towards the extension " +"trait pattern." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits.md +msgid "" +"Explain how many type-system restrictions in Rust aim to prevent _ambiguity_." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits.md +msgid "" +"What would happen if you were allowed to define new inherent methods on " +"foreign types? Different crates in your dependency tree might end up " +"defining different methods on the same foreign type with the same name." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits.md +msgid "" +"As soon as there is room for ambiguity, there must be a way to disambiguate. " +"If disambiguation happens implicitly, it can lead to surprising or otherwise " +"unexpected behavior. If disambiguation happens explicitly, it can increase " +"the cognitive load on developers who are reading your code." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits.md +msgid "" +"Furthermore, every time a crate defines a new inherent method on a foreign " +"type, it may cause compilation errors in _your_ code, as you may be forced " +"to introduce explicit disambiguation." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits.md +msgid "" +"Rust has decided to avoid the issue altogether by forbidding the definition " +"of new inherent methods on foreign types." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits.md +msgid "" +"Other languages (e.g, Kotlin, C#, Swift) allow adding methods to existing " +"types, often called \"extension methods.\" This leads to different trade-" +"offs in terms of potential ambiguities and the need for global reasoning." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-foreign-types.md +msgid "" +"An **extension trait** is a local trait definition whose primary purpose is " +"to attach new methods to foreign types." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-foreign-types.md +msgid "// Bring the extension trait into scope...\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-foreign-types.md +msgid "// ...then invoke its methods as if they were inherent methods\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-foreign-types.md +#: src/idiomatic/leveraging-the-type-system/extension-traits/trait-method-conflicts.md +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "\"dad\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-foreign-types.md +msgid "\"grandma\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-foreign-types.md +msgid "" +"The `Ext` suffix is conventionally attached to the name of extension traits." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-foreign-types.md +msgid "" +"It communicates that the trait is primarily used for extension purposes, and " +"it is therefore not intended to be implemented outside the crate that " +"defines it." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-foreign-types.md +msgid "" +"Refer to the [\"Extension Trait\" RFC](https://rust-lang.github.io/rfcs/0445-" +"extension-trait-conventions.html) as the authoritative source for naming " +"conventions." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-foreign-types.md +msgid "" +"The extension trait implementation for a foreign type must be in the same " +"crate as the trait itself, otherwise you'll be blocked by Rust's [_orphan " +"rule_](https://github.com/rust-lang/rfcs/blob/master/text/2451-re-" +"rebalancing-coherence.md#what-is-coherence-and-why-do-we-care)." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-foreign-types.md +msgid "The extension trait must be in scope when its methods are invoked." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-foreign-types.md +msgid "" +"Comment out the `use` statement in the example to show the compiler error " +"that's emitted if you try to invoke an extension method without having the " +"corresponding extension trait in scope." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-foreign-types.md +msgid "" +"The example above uses an [_underscore import_](https://doc.rust-lang.org/" +"stable/reference/items/use-declarations.html#r-items.use.as-underscore) " +"(`use ext::StringExt as _`) to minimize the likelihood of a naming conflict " +"with other imported traits." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-foreign-types.md +msgid "" +"With an underscore import, the trait is considered to be in scope and you're " +"allowed to invoke its methods on types that implement the trait. Its " +"_symbol_, instead, is not directly accessible. This prevents you, for " +"example, from using that trait in a `where` clause." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-foreign-types.md +msgid "" +"Since extension traits aren't meant to be used in `where` clauses, they are " +"conventionally imported via an underscore import." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/method-resolution-conflicts.md +msgid "" +"What happens when you have a name conflict between an inherent method and an " +"extension method?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/method-resolution-conflicts.md +msgid "" +"// Which `count_ones` method is invoked?\n" +" // The one from `CountOnesExt`? Or the inherent one from `i32`?\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/method-resolution-conflicts.md +msgid "" +"A foreign type may, in a newer version, add a new inherent method with the " +"same name as our extension method." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/method-resolution-conflicts.md +msgid "" +"Ask: What will happen in the example above? Will there be a compiler error? " +"Will one of the two methods be given higher priority? Which one?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/method-resolution-conflicts.md +msgid "" +"Add a `panic!(\"Extension trait\");` in the body of `CountOnesExt::" +"count_ones` to clarify which method is being invoked." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/method-resolution-conflicts.md +msgid "" +"To prevent users of the Rust language from having to manually specify which " +"method to use in all cases, there is a priority ordering system for how " +"methods get \"picked\" first:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/method-resolution-conflicts.md +msgid "Immutable (`&self`) first" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/method-resolution-conflicts.md +msgid "" +"Inherent (method defined in the type's `impl` block) before Trait (method " +"added by a trait impl)." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/method-resolution-conflicts.md +msgid "Mutable (`&mut self`) Second" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/method-resolution-conflicts.md +msgid "Inherent before Trait." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/method-resolution-conflicts.md +msgid "" +"If every method with the same name has different mutability and was either " +"defined in as an inherent method or trait method, with no overlap, this " +"makes the job easy for the compiler." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/method-resolution-conflicts.md +msgid "" +"This does introduce some ambiguity for the user, who may be confused as to " +"why a method they're relying on is not producing expected behavior. Avoid " +"name conflicts instead of relying on this mechanism if you can." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/method-resolution-conflicts.md +msgid "" +"Demonstrate: Change the signature and implementation of `CountOnesExt::" +"count_ones` to `fn count_ones(&mut self) -> u32` and modify the invocation " +"accordingly:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/method-resolution-conflicts.md +msgid "" +"`CountOnesExt::count_ones` is invoked, rather than the inherent method, " +"since `&mut self` has a higher priority than `&self`, the one used by the " +"inherent method." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/method-resolution-conflicts.md +msgid "" +"If an immutable inherent method and a mutable trait method exist for the " +"same type, we can specify which one to use at the call site by using " +"`(&).count_ones()` to get the immutable (higher priority) method or " +"`(&mut ).count_ones()`" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/method-resolution-conflicts.md +msgid "" +"Point the students to the Rust reference for more information on [method " +"resolution](https://doc.rust-lang.org/stable/reference/expressions/method-" +"call-expr.html)." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/method-resolution-conflicts.md +msgid "" +"Avoid naming conflicts between extension trait methods and inherent methods. " +"Rust's method resolution algorithm is complex and may surprise users of your " +"code." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/method-resolution-conflicts.md +msgid "" +"The interaction between the priority search used by Rust's method resolution " +"algorithm and automatic `Deref`ing can be used to emulate [specialization]" +"(https://github.com/rust-lang/rust/issues/31844) on the stable toolchain, " +"primarily in the context of macro-generated code. Check out [\"Autoref " +"Specialization\"](https://github.com/dtolnay/case-studies/blob/master/" +"autoref-specialization/README.md) for the specific details." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/trait-method-conflicts.md +msgid "" +"What happens when you have a name conflict between two different trait " +"methods implemented for the same type?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/trait-method-conflicts.md +msgid "" +"// Which method is invoked?\n" +"// The one from `Ext1`? Or the one from `Ext2`?\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/trait-method-conflicts.md +msgid "" +"The trait you are extending may, in a newer version, add a new trait method " +"with the same name as your extension method. Or another extension trait for " +"the same type may define a method with a name that conflicts with your own " +"extension method." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/trait-method-conflicts.md +msgid "" +"Ask: what will happen in the example above? Will there be a compiler error? " +"Will one of the two methods be given higher priority? Which one?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/trait-method-conflicts.md +msgid "" +"The compiler rejects the code because it cannot determine which method to " +"invoke. Neither `Ext1` nor `Ext2` has a higher priority than the other." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/trait-method-conflicts.md +msgid "To resolve this conflict, you must specify which trait you want to use." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/trait-method-conflicts.md +msgid "" +"Demonstrate: call `Ext1::is_palindrome(\"dad\")` or `Ext2::" +"is_palindrome(\"dad\")` instead of `\"dad\".is_palindrome()`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/trait-method-conflicts.md +msgid "" +"For methods with more complex signatures, you may need to use a more " +"explicit [fully-qualified syntax](https://doc.rust-lang.org/reference/" +"expressions/call-expr.html#disambiguating-function-calls)." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/trait-method-conflicts.md +msgid "" +"Demonstrate: replace `\"dad\".is_palindrome()` with `::" +"is_palindrome(\"dad\")` or `::is_palindrome(\"dad\")`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "" +"As with types, it may be desirable to **extend foreign traits**. In " +"particular, to attach new methods to _all_ implementors of a given trait." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "\"'{}'\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "\"'dad'\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "\"'4'\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "\"'true'\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "" +"Highlight how we added new behavior to _multiple_ types at once. `.quoted()` " +"can be called on string slices, numbers, and booleans since they all " +"implement the `Display` trait." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "" +"This flavor of the extension trait pattern uses [_blanket implementations_]" +"(https://doc.rust-lang.org/stable/reference/glossary.html#blanket-" +"implementation)." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "" +"A blanket implementation implements a trait for all types `T` that satisfy " +"the trait bounds specified in the `impl` block. In this case, the only " +"requirement is that `T` implements the `Display` trait." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "" +"Draw the students' attention to the implementation of `DisplayExt::quoted`: " +"we can't make any assumptions about `T` other than that it implements " +"`Display`. All our logic must either use methods from `Display` or functions/" +"macros that don't require other traits." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "" +"For example, we can call `format!` with `T`, but can't call `." +"to_uppercase()` because it is not necessarily a `String`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "" +"We could introduce additional trait bounds on `T`, but it would restrict the " +"set of types that can leverage the extension trait." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "" +"Conventionally, the extension trait is named after the trait it extends, " +"followed by the `Ext` suffix. In the example above, `DisplayExt`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "" +"There are entire crates that extend standard library traits with new " +"functionality." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "" +"`itertools` crate provides the `Itertools` trait that extends `Iterator`. It " +"adds many iterator adapters, such as `interleave` and `unique`. It provides " +"new algorithmic building blocks for iterator pipelines built with method " +"chaining." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "" +"`futures` crate provides the `FutureExt` trait, which extends the `Future` " +"trait with new combinators and helper methods." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "" +"Extension traits can be used by libraries to distinguish between stable and " +"experimental methods." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "Stable methods are part of the trait definition." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "" +"Experimental methods are provided via an extension trait defined in a " +"different library, with a less restrictive stability policy. Some utility " +"methods are then \"promoted\" to the core trait definition once they have " +"been proven useful and their design has been refined." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "" +"Extension traits can be used to split a [dyn-incompatible trait](https://doc." +"rust-lang.org/reference/items/traits.html#r-items.traits.dyn-compatible) in " +"two:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "" +"A **dyn-compatible core**, restricted to the methods that satisfy dyn-" +"compatibility requirements." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "" +"An **extension trait**, containing the remaining methods that are not dyn-" +"compatible (e.g., methods with a generic parameter)." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/extending-other-traits.md +msgid "" +"Concrete types that implement the core trait will be able to invoke all " +"methods, thanks to the blanket impl for the extension trait. Trait objects " +"(`dyn CoreTrait`) will be able to invoke all methods on the core trait as " +"well as those on the extension trait that don't require `Self: Sized`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/should-i-define-an-extension-trait.md +msgid "" +"In what scenarios should you prefer an extension trait over a free function?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/should-i-define-an-extension-trait.md +msgid "// vs\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/should-i-define-an-extension-trait.md +msgid "The main advantage of extension traits is **ease of discovery**." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/should-i-define-an-extension-trait.md +msgid "" +"Extension methods can be easier to discover than free functions. Language " +"servers (e.g., `rust-analyzer`) will suggest them if you type `.` after an " +"instance of the foreign type." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/should-i-define-an-extension-trait.md +msgid "" +"However, a bespoke extension trait might be overkill for a single method. " +"Both approaches require an additional import, and the familiar method syntax " +"may not justify the boilerplate of a full trait definition." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/should-i-define-an-extension-trait.md +msgid "" +"**Discoverability:** Extension methods are easier to discover than free " +"functions. Language servers (e.g., `rust-analyzer`) will suggest them if you " +"type `.` after an instance of the foreign type." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/should-i-define-an-extension-trait.md +msgid "" +"**Method Chaining:** A major ergonomic win for extension traits is method " +"chaining. This is the foundation of the `Iterator` trait, allowing for " +"fluent calls like `data.iter().filter(...).map(...)`. Achieving this with " +"free functions would be far more cumbersome " +"(`map(filter(iter(data), ...), ...)`)." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/should-i-define-an-extension-trait.md +msgid "" +"**API Cohesion:** Extension traits help create a cohesive API. If you have " +"several related functions for a foreign type (e.g., `is_palindrome`, " +"`word_count`, `to_kebab_case`), grouping them in a single `StrExt` trait is " +"often cleaner than having multiple free functions for a user to import." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/extension-traits/should-i-define-an-extension-trait.md +msgid "" +"**Trade-offs:** Despite these advantages, a bespoke extension trait might be " +"overkill for a single, simple function. Both approaches require an " +"additional import, and the familiar method syntax may not justify the " +"boilerplate of a full trait definition." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern.md +msgid "Typestate Pattern: Problem" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern.md +msgid "" +"How can we ensure that only valid operations are allowed on a value based on " +"its current state?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-example.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/root.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/property.md +msgid "\"{name} {{\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-example.md +msgid "\" {key}={value};\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-example.md +msgid "\"}\\n\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-example.md +msgid "\"User\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-example.md +msgid "\"id\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-example.md +msgid "\"42\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-example.md +msgid "\"name\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern.md +msgid "// serializer.serialize_struct_end(); // ← Oops! Forgotten\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern.md +msgid "This `Serializer` is meant to write a structured value." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern.md +msgid "" +"However, in this example we forgot to call `serialize_struct_end()` before " +"`finish()`. As a result, the serialized output is incomplete or " +"syntactically incorrect." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern.md +msgid "" +"One approach to fix this would be to track internal state manually, and " +"return a `Result` from methods like `serialize_struct_field()` or `finish()` " +"if the current state is invalid." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern.md +msgid "But this has downsides:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern.md +msgid "" +"It is easy to get wrong as an implementer. Rust’s type system cannot help " +"enforce the correctness of our state transitions." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern.md +msgid "" +"It also adds unnecessary burden on the user, who must handle `Result` values " +"for operations that are misused in source code rather than at runtime." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern.md +msgid "" +"A better solution is to model the valid state transitions directly in the " +"type system." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern.md +msgid "" +"In the next slide, we will apply the **typestate pattern** to enforce " +"correct usage at compile time and make it impossible to call incompatible " +"methods or forget to do a required action." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-example.md +msgid "Typestate Pattern: Example" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-example.md +msgid "" +"The typestate pattern encodes part of a value’s runtime state into its type. " +"This allows us to prevent invalid or inapplicable operations at compile time." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-example.md +msgid "`Serializer` usage flowchart:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-example.md +msgid "" +"This example is inspired by Serde’s [`Serializer` trait](https://docs.rs/" +"serde/latest/serde/ser/trait.Serializer.html). Serde uses typestates " +"internally to ensure serialization follows a valid structure. For more, see: " +"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-example.md +msgid "" +"The key idea behind typestate is that state transitions happen by consuming " +"a value and producing a new one. At each step, only operations valid for " +"that state are available." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-example.md +msgid "In this example:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-example.md +msgid "" +"We begin with a `Serializer`, which only allows us to start serializing a " +"struct." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-example.md +msgid "" +"Once we call `.serialize_struct(...)`, ownership moves into a " +"`SerializeStruct` value. From that point on, we can only call methods " +"related to serializing struct fields." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-example.md +msgid "" +"The original `Serializer` is no longer accessible — preventing us from " +"mixing modes (such as starting another _struct_ mid-struct) or calling " +"`finish()` too early." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-example.md +msgid "" +"Only after calling `.finish_struct()` do we receive the `Serializer` back. " +"At that point, the output can be finalized or reused." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-example.md +msgid "" +"If we forget to call `finish_struct()` and drop the `SerializeStruct` early, " +"the `Serializer` is also dropped. This ensures incomplete output cannot leak " +"into the system." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-example.md +msgid "" +"By contrast, if we had implemented everything on `Serializer` directly — as " +"seen on the previous slide, nothing would stop someone from skipping " +"important steps or mixing serialization flows." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-advanced.md +msgid "" +"How do we manage increasingly complex configuration flows with many possible " +"states and transitions, while still preventing incompatible operations?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-advanced.md +msgid "/* [...] */" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-advanced.md +msgid "" +"// TODO, implement:\n" +" //\n" +" // fn serialize_struct(self, name: &str) -> SerializeStruct\n" +" // fn finish(self) -> String\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-advanced.md +msgid "" +"// TODO, implement:\n" +" //\n" +" // fn serialize_property(mut self, name: &str) -> " +"SerializeStructProperty\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-advanced.md +msgid "" +"// TODO,\n" +" // How should we finish this struct? This depends on where it appears:\n" +" // - At the root level: return `Serializer`\n" +" // - As a property inside another struct: return `SerializeStruct`\n" +" // - As a value inside a list: return `SerializeList`\n" +" //\n" +" // fn finish(self) -> ???\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-advanced.md +msgid "" +"// TODO, implement:\n" +" //\n" +" // fn serialize_string(self, value: &str) -> SerializeStruct\n" +" // fn serialize_struct(self, name: &str) -> SerializeStruct\n" +" // fn serialize_list(self) -> SerializeList\n" +" // fn finish(self) -> SerializeStruct\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-advanced.md +msgid "" +"// TODO, implement:\n" +" //\n" +" // fn serialize_string(mut self, value: &str) -> Self\n" +" // fn serialize_struct(mut self, value: &str) -> SerializeStruct\n" +" // fn serialize_list(mut self) -> SerializeList\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-advanced.md +msgid "" +"// TODO:\n" +" // Like `SerializeStruct::finish`, the return type depends on nesting.\n" +" //\n" +" // fn finish(mut self) -> ???\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-advanced.md +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics.md +msgid "Diagram of valid transitions:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-advanced.md +msgid "" +"Building on our previous serializer, we now want to support **nested " +"structures** and **lists**." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-advanced.md +msgid "" +"However, this introduces both **duplication** and **structural complexity**." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-advanced.md +msgid "" +"Even more critically, we now hit a **type system limitation**: we cannot " +"cleanly express what `finish()` should return without duplicating variants " +"for every nesting context (e.g. root, struct, list)." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-advanced.md +msgid "From the diagram of valid transitions, we can observe:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-advanced.md +msgid "The transitions are recursive" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-advanced.md +msgid "The return types depend on _where_ a substructure or list appears" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-advanced.md +msgid "Each context requires a return path to its parent" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-advanced.md +msgid "" +"With only concrete types, this becomes unmanageable. Our current approach " +"leads to an explosion of types and manual wiring." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-advanced.md +msgid "" +"In the next chapter, we’ll see how **generics** let us model recursive flows " +"with less boilerplate, while still enforcing valid operations at compile " +"time." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics.md +msgid "" +"By combining typestate modeling with generics, we can express a wider range " +"of valid states and transitions without duplicating logic. This approach is " +"especially useful when the number of states grows or when multiple states " +"share behavior but differ in structure." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics.md +msgid "" +"We now have all the tools needed to implement the methods for the " +"`Serializer` and its state type definitions. This ensures that our API only " +"permits valid transitions, as illustrated in the following diagram:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics.md +msgid "" +"By leveraging generics to track the parent context, we can construct " +"arbitrarily nested serializers that enforce valid transitions between " +"struct, list, and property states." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics.md +msgid "" +"This enables us to build a recursive structure while maintaining strict " +"control over which methods are accessible in each state." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics.md +msgid "" +"Methods common to all states can be defined for any `S` in `Serializer`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics.md +msgid "" +"Marker types (e.g., `List`) introduce no memory or runtime overhead, as " +"they contain no data other than a possible Zero-Sized Type. Their only role " +"is to enforce correct API usage through the type system." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/root.md +msgid "" +"Referring back to our original diagram of valid transitions, we can " +"visualize the beginning of our implementation as follows:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/root.md +msgid "" +"```bob\n" +" serialize\n" +" struct\n" +"+--------------------+ --------------> +----------------------------+\n" +"| \"Serializer\" | | \"Serializer>\" |\n" +"+--------------------+ <-------------- +----------------------------+\n" +" finish struct\n" +" |\n" +" |\n" +" |\n" +"finish |\n" +" V\n" +"\n" +" +--------+\n" +" | String |\n" +" +--------+\n" +"```" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/root.md +msgid "" +"At the \"root\" of our `Serializer`, the only construct allowed is a " +"`Struct`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/root.md +msgid "" +"The `Serializer` can only be finalized into a `String` from this root level." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/struct.md +msgid "\"{}{name}: \"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/struct.md +msgid "\"{}}}\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/struct.md +msgid "The diagram can now be expanded as follows:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/struct.md +msgid "" +"```bob\n" +" +------+\n" +" finish | |\n" +" serialize struct V |\n" +" struct\n" +"+--------------------+ --------------> +-------------------------+\n" +"| \"Serializer\" | | \"Serializer>\" |\n" +"+--------------------+ <-------------- +-------------------------+\n" +" finish struct\n" +" | serialize |\n" +" | property V\n" +" |\n" +"finish | +-----------------------------------+\n" +" V | \"Serializer>>\" " +"|\n" +" +-----------------------------------+\n" +" +--------+\n" +" | String |\n" +" +--------+\n" +"```" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/struct.md +msgid "A `Struct` can only contain a `Property`;" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/struct.md +msgid "" +"Finishing a `Struct` returns control back to its parent, which in our " +"previous slide was assumed the `Root`, but in reality however it can be also " +"something else such as `Struct` in case of nested \"structs\"." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/property.md +msgid "\"[\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/property.md +msgid "\"{value},\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/property.md +msgid "" +"With the addition of the Property state methods, our diagram is now nearly " +"complete:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/property.md +msgid "" +"```bob\n" +" +------+\n" +" finish | |\n" +" serialize struct V |\n" +" struct\n" +"+--------------------+ --------------> +-------------------------+\n" +"| \"Serializer\" | | \"Serializer>\" |\n" +"+--------------------+ <-------------- +-------------------------+ " +"<-----------+\n" +" finish " +"struct |\n" +" | serialize " +"| |\n" +" | property V " +"serialize |\n" +" | string " +"or |\n" +"finish | +---------------------------+ " +"struct |\n" +" V | \"Serializer>\" | " +"------------+\n" +" +---------------------------+\n" +" +--------+\n" +" | String | serialize |\n" +" +--------+ list V\n" +"\n" +" +-----------------------+\n" +" | \"Serializer>\" |\n" +" +-----------------------+\n" +"```" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/property.md +msgid "" +"A property can be defined as a `String`, `Struct`, or `List`, enabling " +"the representation of nested structures." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/property.md +msgid "" +"This concludes the step-by-step implementation. The full implementation, " +"including support for `List`, is shown in the next slide." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/complete.md +msgid "Serializer: complete implementation" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/complete.md +msgid "Looking back at our original desired flow:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/complete.md +msgid "We can now see this reflected directly in the types of our serializer:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/complete.md +msgid "" +"```bob\n" +" +------+\n" +" finish | |\n" +" serialize struct V |\n" +" struct\n" +"+--------------------+ --------------> +-------------------------+ " +"<---------------+\n" +"| \"Serializer\" | | \"Serializer>\" " +"| |\n" +"+--------------------+ <-------------- +-------------------------+ " +"<-----------+ |\n" +" finish " +"struct | |\n" +" | | serialize " +"| | |\n" +" | +----------+ property V " +"serialize | |\n" +" | | string " +"or | |\n" +"finish | | +---------------------------+ " +"struct | |\n" +" V | | \"Serializer>\" | " +"------------+ |\n" +" finish | +---------------------------" +"+ |\n" +" +--------+ struct " +"| |\n" +" | String | | serialize " +"| |\n" +" +--------+ | list " +"V |\n" +" | " +"finish |\n" +" | +-----------------------+ " +"list |\n" +" +-----> | \"Serializer>\" | " +"----------------+\n" +" +-----------------------+\n" +" serialize\n" +" | list or string ^\n" +" | or finish list |\n" +" +-----------------+\n" +"```" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/complete.md +msgid "" +"The code for the full implementation of the `Serializer` and all its states " +"can be found in [this Rust playground](https://play.rust-lang.org/?" +"version=stable&mode=debug&edition=2024&gist=c9cbb831cd05fe9db4ce42713c83ca16)." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/complete.md +msgid "This pattern isn't a silver bullet. It still allows issues like:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/complete.md +msgid "" +"Empty or invalid property names (which can be fixed using [the newtype " +"pattern](../../newtype-pattern.md))" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/complete.md +msgid "" +"Duplicate property names (which could be tracked in `Struct` and handled " +"via `Result`)" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/complete.md +msgid "" +"If validation failures occur, we can also change method signatures to return " +"a `Result`, allowing recovery:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/complete.md +msgid "" +"While this API is powerful, it’s not always ergonomic. Production " +"serializers typically favor simpler APIs and reserve the typestate pattern " +"for enforcing critical invariants." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/complete.md +msgid "" +"One excellent real-world example is [`rustls::ClientConfig`](https://docs.rs/" +"rustls/latest/rustls/client/struct.ClientConfig.html#method.builder), which " +"uses typestate with generics to guide the user through safe and correct " +"configuration steps." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "Using the Borrow checker to enforce Invariants" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "" +"The borrow checker, while added to enforce memory ownership, can model other " +"problems and prevent API misuse." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "" +"/// Doors can be open or closed, and you need the right key to lock or " +"unlock\n" +"/// one. Modelled with a Shared key and Owned door.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "\"Opened the door with key shape '{}'\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "\"Door wasn't opened! Your key only opens locks with shape '{}'\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "" +"We've seen the borrow checker prevent memory safety bugs (use-after-free, " +"data races)." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "" +"We've also used types to shape and restrict APIs already using [the " +"Typestate pattern](../leveraging-the-type-system/typestate-pattern.md)." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "Language features are often introduced for a specific purpose." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "" +"Over time, users may develop ways of using a feature in ways that were not " +"predicted when they were introduced." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "" +"Java 5 introduced Generics in 2004 with the [main stated purpose of enabling " +"type-safe collections](https://jcp.org/en/jsr/detail?id=14)." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "" +"Adoption was slow at first, but some new projects began designing their APIs " +"around generics from the beginning." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "" +"Since then, users and developers of the language expanded the use of " +"generics to other areas of type-safe API design:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "" +"Class information can be held onto via Java's `Class` or Guava's " +"`TypeToken`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "The Builder pattern can be implemented using Recursive Generics." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "" +"We aim to do something similar here: Even though the borrow checker was " +"introduced to prevent use-after-free and data races, we treat it as just " +"another API design tool." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "" +"It can be used to model program properties that have nothing to do with " +"preventing memory safety bugs." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "" +"To use the borrow checker as a problem solving tool, we will need to " +"\"forget\" that the original purpose of it is to prevent mutable aliasing in " +"the context of preventing use-after-frees and data races." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "" +"We should imagine working within situations where the rules are the same but " +"the meaning is slightly different." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "" +"This example uses ownership and borrowing are used to model the state of a " +"physical door." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "" +"`open_door` **consumes** a `LockedDoor` and returns a new `OpenDoor`. The " +"old `LockedDoor` value is no longer available." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "" +"If the wrong key is used, the door is left locked. It is returned as an " +"`Err` case of the `Result`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "" +"It is a compile-time error to try and use a door that has already been " +"opened." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "" +"Similarly, `lock_door` consumes an `OpenDoor`, preventing closing the door " +"twice at compile time." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "" +"The rules of the borrow checker exist to prevent memory safety bugs, but the " +"underlying logical system does not \"know\" what memory is." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "" +"All the borrow checker does is enforce a specific set of rules of how users " +"can order operations." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants.md +msgid "" +"This is just one case of piggy-backing onto the rules of the borrow checker " +"to design APIs to be harder or impossible to misuse." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md +msgid "// An internal data type to have something to hold onto.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md +msgid "// The \"outer\" data.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md +msgid "// let exclusive = exclusive_use(&mut value); // ❌🔨\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md +msgid "// let shared = shared_use(&value); // ❌🔨\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md +msgid "" +"This example re-frames the borrow checker rules away from references and " +"towards semantic meaning in non-memory-safety settings." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md +msgid "Nothing is being mutated, nothing is being sent across threads." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md +msgid "" +"In Rust's borrow checker we have access to three different ways of " +"\"taking\" a value:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md +msgid "" +"Owned value `T`. Value is dropped when the scope ends, unless it is not " +"returned to another scope." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md +msgid "" +"Shared Reference `&T`. Allows aliasing but prevents mutable access while " +"shared references are in use." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md +msgid "" +"Mutable Reference `&mut T`. Only one of these is allowed to exist for a " +"value at any one point, but can be used to create shared references." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md +msgid "" +"Ask: The two commented-out lines in the `demo` functions would cause " +"compilation errors, Why?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md +msgid "" +"`demo_exclusive`: Because the `shared` value is still aliased after the " +"`exclusive` reference is taken." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md +msgid "" +"`demo_denied`: Because `value` is consumed the line before the " +"`shared_again_again` reference is taken from `&value`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md +msgid "" +"Remember that every `&T` and `&mut T` has a lifetime, just one the user " +"doesn't have to annotate or think about most of the time." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/generalizing-ownership.md +msgid "" +"We rarely specify lifetimes because the Rust compiler allows us to _elide_ " +"them in most cases. See: [Lifetime Elision](../../../lifetimes/lifetime-" +"elision.md)" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +msgid "" +"Sometimes we want values that _can only be used once_. One critical example " +"of this is in cryptography: A \"Nonce.\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +msgid "/* specifics omitted */" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +msgid "/// A single-use number suitable for cryptographic purposes.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +msgid "/// A cryptographically sound random generator function.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +msgid "// chosen by a fair dice roll, https://xkcd.com/221/\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +msgid "/// Consume a nonce, but not the key or the data.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +msgid "" +"// The key and data can be re-used, copied, etc. but the nonce cannot.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +msgid "// encrypt(nonce, &key, &data_2); // đŸ› ī¸âŒ\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +msgid "Problem: How can we guarantee a value is used only once?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +msgid "" +"Motivation: A nonce is a piece of random, unique data used in cryptographic " +"protocols to prevent replay attacks." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +msgid "" +"Background: In practice people have ended up accidentally re-using nonces. " +"Most commonly, this causes the cryptographic protocol to completely break " +"down and stop fulfilling its function." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +msgid "" +"Depending on the specifics of nonce reuse and cryptography at hand, private " +"keys can also become computable by attackers." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +msgid "" +"Rust has an obvious tool for achieving the invariant \"Once you use this, " +"you can't use it again\": passing a value as an _owned argument_." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +msgid "" +"Highlight: the `encrypt` function takes `nonce` by value (an owned " +"argument), but `key` and `data` by reference." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +msgid "The technique for single-use values is as follows:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +msgid "" +"Keep constructors private, so a user can't construct values with the same " +"inner value twice." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +msgid "" +"Don't implement `Clone`/`Copy` traits or equivalent methods, so a user can't " +"duplicate data we want to keep unique." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +msgid "" +"Make the interior type opaque (like with the newtype pattern), so the user " +"cannot modify an existing value on their own." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +msgid "Ask: What are we missing from the newtype pattern in the slide's code?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +msgid "Expect: Module boundary." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +msgid "" +"Demonstrate: Without a module boundary a user can construct a nonce on their " +"own." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +msgid "Fix: Put `Key`, `Nonce`, and `new_nonce` behind a module." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/single-use-values.md +msgid "" +"Cryptography Nuance: A nonce might still be used twice if it was created " +"through pseudo-random process with no actual randomness. That can't be " +"prevented through this method. This API design prevents one nonce " +"duplication, but not all logic bugs." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "" +"We can use the mutual exclusion of `&T` and `&mut T` references to prevent " +"data from being used before it is ready." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "/* fields omitted */" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "// fake results\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "// Send the query over, but don't wait for results.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "// Finish executing the transaction and retrieve the results.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "// The transaction `tx` mutably borrows `db`.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "\"SELECT * FROM users\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "" +"// This won't compile because `db` is already mutably borrowed by `tx`.\n" +" // let results = db.results(); // ❌🔨\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "// The borrow of `db` ends when `tx` is consumed by `commit()`.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "// Now it is possible to borrow `db` again.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "" +"Motivation: In this database API queries are kicked off for asynchronous " +"execution and the results are only available once the whole transaction is " +"finished." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "" +"A user might think that queries are executed immediately, and try to read " +"results before they are made available. This API misuse could make the app " +"read incomplete or incorrect data." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "" +"While an obvious misunderstanding, situations such as this can happen in " +"practice." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "" +"Ask: Has anyone misunderstood an API by not reading the docs for proper use?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "" +"Expect: Examples of early-career or in-university mistakes and " +"misunderstandings." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "" +"As an API grows in size and user base, a smaller percentage of users has " +"deep knowledge of the system the API represents." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "" +"This example shows how we can use Aliasing XOR Mutability to prevent this " +"kind of misuse." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "" +"The code might read results before they are ready if the programmer assumes " +"that the queries execute immediately rather than kicked off for asynchronous " +"execution." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "" +"The constructor for the `Transaction` type takes a mutable reference to the " +"database connection, and stores it in the returned `Transaction` value." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "" +"The explicit lifetime here doesn't have to be intimidating, it just means " +"\"`Transaction` is outlived by the `DatabaseConnection` that was passed to " +"it\" in this case." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "" +"The reference is mutable to completely lock out the `DatabaseConnection` " +"from other usage, such as starting further transactions or reading the " +"results." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "" +"While a `Transaction` exists, we can't touch the `DatabaseConnection` " +"variable that was created from it." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "" +"Demonstrate: uncomment the `db.results()` line. Doing so will result in a " +"compile error, as `db` is already mutably borrowed." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "" +"Note: The query results not being public and placed behind a getter function " +"lets us enforce the invariant \"users can only look at query results if " +"there is no active transactions.\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/aliasing-xor-mutability.md +msgid "" +"If the query results were placed in a public struct field, this invariant " +"could be violated." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-01-types.md +msgid "PhantomData 1/4: De-duplicating Same Data & Semantics" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-01-types.md +msgid "" +"The newtype pattern can sometimes come up against the DRY principle, how do " +"we solve this?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-01-types.md +msgid "// And so on ...\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-01-types.md +msgid "" +"Problem: We want to use the newtype pattern to differentiate permissions, " +"but we're having to implement the same traits over and over again for the " +"same data." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-01-types.md +msgid "" +"Ask: Assume the details of each implementation here are the same between " +"types, what are ways we can avoid repeating ourselves?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-01-types.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "Expect:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-01-types.md +msgid "Make this an enum, not distinct data types." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-01-types.md +msgid "" +"Bundle the user ID with permission tokens like `struct Admin(u64, " +"UserPermission, ModeratorPermission, AdminPermission);`" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-01-types.md +msgid "Adding a type parameter which encodes permissions." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-01-types.md +msgid "Mentioning `PhantomData` ahead of schedule (it's in the title)." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-02-types-implemented.md +msgid "PhantomData 2/4: Type-level tagging" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-02-types-implemented.md +msgid "" +"Let's solve the problem from the previous slide by adding a type parameter." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-02-types-implemented.md +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "// use std::marker::PhantomData;\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-02-types-implemented.md +msgid "// Admins are users\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-02-types-implemented.md +msgid "" +"// impl Debug for UserTag {/* ... */}\n" +"// impl PartialEq for UserTag {/* ... */}\n" +"// impl Eq for UserTag {/* ... */}\n" +"// And so on ...\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-02-types-implemented.md +msgid "/* All functionality for users and above */" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-02-types-implemented.md +msgid "/* All functionality for only admins */" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-02-types-implemented.md +msgid "" +"Here we're using a type parameter and gating permissions behind \"tag\" " +"types that implement different permission traits." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-02-types-implemented.md +msgid "" +"Tag types, or marker types, are zero-sized types that have some semantic " +"meaning to users and API designers." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-02-types-implemented.md +msgid "" +"Ask: What issues does having it be an actual instance of that type pose?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-02-types-implemented.md +msgid "" +"Answer: If it's not a zero-sized type (like `()` or `struct MyTag;`), then " +"we're allocating more memory than we need to when all we care for is type " +"information that is only relevant at compile-time." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-02-types-implemented.md +msgid "Demonstrate: remove the `tag` value entirely, then compile!" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-02-types-implemented.md +msgid "This won't compile, as there's an unused (phantom) type parameter." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-02-types-implemented.md +msgid "This is where `PhantomData` comes in!" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-02-types-implemented.md +msgid "" +"Demonstrate: Uncomment the `PhantomData` import, and make `ChatId` the " +"following:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-02-types-implemented.md +msgid "" +"`PhantomData` is a zero-sized type with a type parameter. We can " +"construct values of it like other ZSTs with `let phantom: " +"PhantomData = PhantomData;` or with the `PhantomData::default()` " +"implementation." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-02-types-implemented.md +msgid "" +"Demonstrate: implement `From` for `ChatId`, emphasizing the " +"construction of `PhantomData`" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-02-types-implemented.md +msgid "// Or `PhantomData::default()`\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-02-types-implemented.md +msgid "" +"`PhantomData` can be used as part of the Typestate pattern to have data with " +"the same structure but different methods, e.g., have `TaggedData` " +"implement methods or trait implementations that `TaggedData` doesn't." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "PhantomData 3/4: Lifetimes for External Resources" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "" +"The invariants of external resources often match what we can do with " +"lifetime rules." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "" +"/// Direct FFI to a database library in C.\n" +"/// We got this API as is, we have no influence over it.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "// maximum 255 databases open at the same time\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "// ... etc.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "" +"Remember the transaction API from the [Aliasing XOR Mutability](./aliasing-" +"xor-mutability.md) example." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "" +"We held onto a mutable reference to the database connection within the " +"transaction type to lock out the database while a transaction is active." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "" +"In this example, we want to implement a `Transaction` API on top of an " +"external, non-Rust API." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "" +"We start by defining a `Transaction` type that holds onto `&mut " +"DatabaseConnection`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "" +"Ask: What are the limits of this implementation? Assume the `u8` is accurate " +"implementation-wise and enough information for us to use the external API." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "" +"Indirection takes up 7 bytes more than we need to on a 64-bit platform, as " +"well as costing a pointer dereference at runtime." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "" +"Problem: We want the transaction to borrow the database connection that " +"created it, but we don't want the `Transaction` object to store a real " +"reference." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "" +"Ask: What happens when we remove the mutable reference in `Transaction` " +"while keeping the lifetime parameter?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "Expect: Unused lifetime parameter!" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "" +"Like with the type tagging from the previous slides, we can bring in " +"`PhantomData` to capture this unused lifetime parameter for us." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "" +"The difference is that we will need to use the lifetime alongside another " +"type, but that other type does not matter too much." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "Demonstrate: change `Transaction` to the following:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "Update the `DatabaseConnection::new_transaction()` method:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "" +"This gives an owned database connection that is tied to the " +"`DatabaseConnection` that created it, but with less runtime memory footprint " +"that the store-a-reference version did." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "" +"Because `PhantomData` is a zero-sized type (like `()` or `struct " +"MyZeroSizedType;`), the size of `Transaction` is now the same as `u8`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "" +"The implementation that held onto a reference instead was as large as a " +"`usize`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "" +"This way of encoding relationships between types and values is very powerful " +"when combined with unsafe, as the ways one can manipulate lifetimes becomes " +"almost arbitrary. This is also dangerous, but when combined with tools like " +"external, mechanically-verified proofs we can safely encode cyclic/self-" +"referential types while encoding lifetime & safety expectations in the " +"relevant data types." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-03-lifetimes.md +msgid "" +"The [GhostCell (2021)](https://plv.mpi-sws.org/rustbelt/ghostcell/) paper " +"and its [relevant implementation](https://gitlab.mpi-sws.org/FP/ghostcell) " +"show this kind of work off. While the borrow checker is restrictive, there " +"are still ways to use escape hatches and then _show that the ways you used " +"those escape hatches are consistent and safe._" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-04-borrowedfd.md +msgid "PhantomData 4/4: OwnedFd & BorrowedFd" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-04-borrowedfd.md +msgid "`BorrowedFd` is a prime example of `PhantomData` in action." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-04-borrowedfd.md +msgid "" +"// Create a file with a raw syscall with write-only and create permissions.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-04-borrowedfd.md +msgid "\"c_str.txt\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-04-borrowedfd.md +msgid "" +"// Pass the ownership of an integer file descriptor to an `OwnedFd`.\n" +" // `OwnedFd::drop()` closes the file descriptor.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-04-borrowedfd.md +msgid "\"Could not open file with syscall!\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-04-borrowedfd.md +msgid "" +"// Create a `BorrowedFd` from an `OwnedFd`.\n" +" // `BorrowedFd::drop()` does not close the file because it doesn't own " +"it!\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-04-borrowedfd.md +msgid "// std::mem::drop(owned_fd); // ❌🔨\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-04-borrowedfd.md +msgid "// owned_fd will be dropped here, and the file will be closed.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-04-borrowedfd.md +msgid "A file descriptor represents a specific process's access to a file." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-04-borrowedfd.md +msgid "" +"Reminder: Device and OS-specific features are exposed as if they were files " +"on unix-style systems." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-04-borrowedfd.md +msgid "" +"[`OwnedFd`](https://rust-lang.github.io/rfcs/3128-io-safety.html#ownedfd-and-" +"borrowedfdfd) is an owned wrapper type for a file descriptor. It _owns_ the " +"file descriptor, and closes it when dropped." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-04-borrowedfd.md +msgid "" +"Note: We have our own implementation of it here, draw attention to the " +"explicit `Drop` implementation." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-04-borrowedfd.md +msgid "" +"`BorrowedFd` is its borrowed counterpart, it does not need to close the file " +"when it is dropped." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-04-borrowedfd.md +msgid "Note: We have not explicitly implemented `Drop` for `BorrowedFd`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-04-borrowedfd.md +msgid "" +"`BorrowedFd` uses a lifetime captured with a `PhantomData` to enforce the " +"invariant \"if this file descriptor exists, the OS file descriptor is still " +"open even though it is not responsible for closing that file descriptor.\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-04-borrowedfd.md +msgid "" +"The lifetime parameter of `BorrowedFd` demands that there exists another " +"value in your program that lasts as long as that specific `BorrowedFd` or " +"outlives it (in this case an `OwnedFd`)." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-04-borrowedfd.md +msgid "" +"Demonstrate: Uncomment the `std::mem::drop(owned_fd)` line and try to " +"compile to show that `borrowed_fd` relies on the lifetime of `owned_fd`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-04-borrowedfd.md +msgid "" +"This has been encoded by the API designers to mean _that other value is what " +"keeps the access to the file open_." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/borrow-checker-invariants/phantomdata-04-borrowedfd.md +msgid "" +"Because Rust's borrow checker enforces this relationship where one value " +"must last at least as long as another, users of this API do not need to " +"worry about handling this correct file descriptor aliasing and closing logic " +"themselves." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types.md +msgid "" +"Types with private constructors can be used to act as proof of invariants." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types.md +msgid "// A public type with private fields behind a module boundary.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types.md +msgid "\"We have a token, so we can make assumptions.\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types.md +msgid "// We have a token, so we can do this work.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types.md +msgid "// We could not get a token, so we can't call `protected_work`.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types.md +msgid "" +"Motivation: We want to be able to restrict user's access to functionality " +"until they've performed a specific task." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types.md +msgid "" +"We can do this by defining a type the API consumer cannot construct on their " +"own, through the privacy rules of structs and modules." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types.md +msgid "" +"[Newtypes](./newtype-pattern.md) use the privacy rules in a similar way, to " +"restrict construction unless a value is guaranteed to hold up an invariant " +"at runtime." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types.md +msgid "Ask: What is the purpose of the `proof: ()` field here?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types.md +msgid "" +"Without `proof: ()`, `Token` would have no private fields and users would be " +"able to construct values of `Token` arbitrarily." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types.md +msgid "" +"Demonstrate: Try to construct the token manually in `main` and show the " +"compilation error. Demonstrate: Remove the `proof` field from `Token` to " +"show how users would be able to construct `Token` if it had no private " +"fields." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types.md +msgid "" +"By putting the `Token` type behind a module boundary (`token`), users " +"outside that module can't construct the value on their own as they don't " +"have permission to access the `proof` field." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types.md +msgid "" +"The API developer gets to define methods and functions that produce these " +"tokens. The user does not." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types.md +msgid "" +"The token becomes a proof that one has met the API developer's conditions of " +"access for those tokens." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types.md +msgid "" +"Ask: How might an API developer accidentally introduce ways to circumvent " +"this?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types.md +msgid "" +"Expect answers like \"serialization implementations\", other parser/\"from " +"string\" implementations, or an implementation of `Default`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/permission-tokens.md +msgid "Token types work well as a proof of checked permission." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/permission-tokens.md +msgid "" +"// We don't have to check that we have permissions, because\n" +"// the AdminToken argument is equivalent to such a check.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/permission-tokens.md +msgid "\"CoolUser\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/permission-tokens.md +msgid "\"Incorrect password! Could not prove privileges.\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/permission-tokens.md +msgid "" +"This example shows modelling gaining administrator privileges for a chat " +"client with a password and giving a user a moderator rank once those " +"privileges are gained. The `AdminToken` type acts as \"proof of correct user " +"privileges.\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/permission-tokens.md +msgid "" +"The user asked for a password in-code and if we get the password correct, we " +"get a `AdminToken` to perform administrator actions within a specific " +"environment (here, a chat client)." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/permission-tokens.md +msgid "" +"Once the permissions are gained, we can call the `add_moderator` function." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/permission-tokens.md +msgid "" +"We can't call that function without the token type, so by being able to call " +"it at all all we can assume we have permissions." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/permission-tokens.md +msgid "" +"Demonstrate: Try to construct the `AdminToken` in `main` again to reiterate " +"that the foundation of useful tokens is preventing their arbitrary " +"construction." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/mutex-guard.md +msgid "" +"Sometimes, a token type needs additional data. A mutex guard is an example " +"of a token that represents permission + data." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/mutex-guard.md +msgid "// The acquired MutexGuard is proof of exclusive access.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/mutex-guard.md +msgid "" +"Mutexes enforce mutual exclusion of read/write access to a value. We've " +"covered Mutexes earlier in this course already (See: RAII/Mutex), but here " +"we're looking at `MutexGuard` specifically." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/mutex-guard.md +msgid "" +"`MutexGuard` is a value generated by a `Mutex` that proves you have read/" +"write access at that point in time." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/mutex-guard.md +msgid "" +"`MutexGuard` also holds onto a reference to the `Mutex` that generated it, " +"with `Deref` and `DerefMut` implementations that give access to the data of " +"`Mutex` while the underlying `Mutex` keeps that data private from the user." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/mutex-guard.md +msgid "" +"If `mutex.lock()` does not return a `MutexGuard`, you don't have permission " +"to change the value within the mutex." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/mutex-guard.md +msgid "" +"Not only do you have no permission, but you have no means to access the " +"mutex data unless you gain a `MutexGuard`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/mutex-guard.md +msgid "" +"This contrasts with C++, where mutexes and lock guards do not control access " +"to the data itself, acting only as a flag that a user must remember to check " +"every time they read or manipulate data." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/mutex-guard.md +msgid "" +"Demonstrate: make the `mutex` variable mutable then try to dereference it to " +"change its value. Show how there's no deref implementation for it, and no " +"other way to get to the data held by it other than getting a mutex guard." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-01-motivation.md +msgid "Variable-Specific Tokens (Branding 1/4)" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-01-motivation.md +msgid "What if we want to tie a token to a specific variable?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-01-motivation.md +msgid "// Works fine!\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-01-motivation.md +msgid "" +"// let data_2 = Bytes { bytes: vec![0, 1] };\n" +" // data_2.get_proven(&token_1); // Panics! Can we prevent this?\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-01-motivation.md +msgid "" +"What if we want to tie a token to a _specific variable_ in our code? Can we " +"do this in Rust's type system?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-01-motivation.md +msgid "" +"Motivation: We want to have a Token Type that represents a known, valid " +"index into a byte array." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-01-motivation.md +msgid "" +"Once we have these proven indexes we would be able to avoid bounds checks " +"entirely, as the tokens would act as the _proof of an existing index_." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-01-motivation.md +msgid "" +"Since the index is known to be valid, `get_proven()` can skip the bounds " +"check." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-01-motivation.md +msgid "" +"In this example there's nothing stopping the proven index of one array being " +"used on a different array. If an index is out of bounds in this case, it is " +"undefined behavior." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-01-motivation.md +msgid "Demonstrate: Uncomment the `data_2.get_proven(&token_1);` line." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-01-motivation.md +msgid "" +"The code here panics! We want to prevent this \"crossover\" of token types " +"for indexes at compile time." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-01-motivation.md +msgid "Ask: How might we try to do this?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-01-motivation.md +msgid "" +"Expect students to not reach a good implementation from this, but be willing " +"to experiment and follow through on suggestions." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-01-motivation.md +msgid "Ask: What are the alternatives, why are they not good enough?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-01-motivation.md +msgid "" +"Expect runtime checking of index bounds, especially as both `Vec::get` and " +"`Bytes::get_index` already uses runtime checking." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-01-motivation.md +msgid "" +"Runtime bounds checking does not prevent the erroneous crossover in the " +"first place, it only guarantees a panic." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-01-motivation.md +msgid "" +"The kind of token-association we will be doing here is called Branding. This " +"is an advanced technique that expands applicability of token types to more " +"API designs." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-01-motivation.md +msgid "" +"[`GhostCell`](https://plv.mpi-sws.org/rustbelt/ghostcell/paper.pdf) is a " +"prominent user of this, later slides will touch on it." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "`PhantomData` and Lifetime Subtyping (Branding 2/4)" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "Idea:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "Use a lifetime as a unique brand for each token." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"Make lifetimes sufficiently distinct so that they don't implicitly convert " +"into each other." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "// The main focus\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "// We want this to NOT compile\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "In Rust, lifetimes can have subtyping relations between one another." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"This kind of relation allows the compiler to determine if one lifetime " +"outlives another." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"Determining if a lifetime outlives another also allows us to say _the " +"shortest common lifetime is the one that ends first_." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"This is useful in many cases, as it means two different lifetimes can be " +"treated as if they were the same in the regions they do overlap." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"This is usually what we want. But here we want to use lifetimes as a way to " +"distinguish values so we say that a token only applies to a single variable " +"without having to create a newtype for every single variable we declare." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"**Goal**: We want two lifetimes that the Rust compiler cannot determine if " +"one outlives the other." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"We are using `try_coerce_lifetimes` as a compile-time check to see if the " +"lifetimes have a common shorter lifetime (AKA being subtyped)." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"Note: This slide compiles, by the end of this slide it should only compile " +"when `subtyped_lifetimes` is commented out." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "There are two important parts of this code:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "The `impl for<'a>` bound on the closure passed to `lifetime_separator`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "The way lifetimes are used in the parameter for `PhantomData`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "`for<'a>` bound on a Closure" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"We are using `for<'a>` as a way of introducing a lifetime generic parameter " +"to a function type and asking that the body of the function to work for all " +"possible lifetimes." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"What this also does is remove some ability of the compiler to make " +"assumptions about that specific lifetime for the function argument, as it " +"must meet Rust's borrow checking rules regardless of the \"real\" lifetime " +"its arguments are going to have. The caller is substituting in actual " +"lifetime, the function itself cannot." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"This is analogous to a forall (âą¯) quantifier in mathematics, or the way we " +"introduce `` as type variables, but only for lifetimes in trait bounds." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"When we write a function generic over a type `T`, we can't determine that " +"type from within the function itself. Even if we call a function `fn foo(first: T, second: U)` with two arguments of the same type, the body of " +"this function cannot determine if `T` and `U` are the same type." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"This also prevents _the API consumer_ from defining a lifetime themselves, " +"which would allow them to circumvent the restrictions we want to impose." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "PhantomData and Lifetime Variance" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"We already know `PhantomData`, which can introduce a formal no-op usage of " +"an otherwise unused type or a lifetime parameter." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "Ask: What can we do with `PhantomData`?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"Expect mentions of the Typestate pattern, tying together the lifetimes of " +"owned values." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "Ask: In other languages, what is subtyping?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"Expect mentions of inheritance, being able to use a value of type `B` when a " +"asked for a value of type `A` because `B` is a \"subtype\" of `A`." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "Rust does have Subtyping! But only for lifetimes." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"Ask: If one lifetime is a subtype of another lifetime, what might that mean?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"A lifetime is a \"subtype\" of another lifetime when it _outlives_ that " +"other lifetime." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"The way that lifetimes used by `PhantomData` behave depends not only on " +"where the lifetime \"comes from\" but on how the reference is defined too." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"The reason this compiles is that the [**Variance**](https://doc.rust-lang." +"org/stable/reference/subtyping.html#r-subtyping.variance) of the lifetime " +"inside of `InvariantLifetime` is too lenient." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"Note: Do not expect to get students to understand variance entirely here, " +"just treat it as a kind of ladder of restrictiveness on the ability of " +"lifetimes to establish subtyping relations." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"Ask: How can we make it more restrictive? How do we make a reference type " +"more restrictive in Rust?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"Expect or demonstrate: Making it `&'id mut ()` instead. This will not be " +"enough!" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"We need to use a [**Variance**](https://doc.rust-lang.org/stable/reference/" +"subtyping.html#r-subtyping.variance) on lifetimes where subtyping cannot be " +"inferred except on _identical lifetimes_. That is, the only subtype of `'a` " +"the compiler can know is `'a` itself." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"Note: Again, do not try to get the whole class to understand variance. Treat " +"it as a ladder of restrictiveness for now." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"Demonstrate: Move from `&'id ()` (covariant in lifetime and type), `&'id mut " +"()` (covariant in lifetime, invariant in type), `*mut &'id mut ()` " +"(invariant in lifetime and type), and finally `*mut &'id ()` (invariant in " +"lifetime but not type)." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"Those last two should not compile, which means we've finally found " +"candidates for how to bind lifetimes to `PhantomData` so they can't be " +"compared to one another in this context." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"Reason: `*mut` means [mutable raw pointer](https://doc.rust-lang.org/" +"reference/types/pointer.html#r-type.pointer.raw). Rust has mutable pointers! " +"But you cannot reason about them in safe Rust. Making this a mutable raw " +"pointer to a reference that has a lifetime complicates the compiler's " +"ability subtype because it cannot reason about mutable raw pointers within " +"the borrow checker." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"Wrap up: We've introduced ways to stop the compiler from deciding that " +"lifetimes are \"similar enough\" by choosing a Variance for a lifetime in " +"`PhantomData` that is restrictive enough to prevent this slide from " +"compiling." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"That is, we can now create variables that can exist in the same scope as " +"each other, but whose types are automatically made different from one " +"another per-variable without much boilerplate." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-02-phantomdata.md +msgid "" +"The `for<'a>` quantifier is not just for function types. It is a [**Higher-" +"ranked trait bound**](https://doc.rust-lang.org/reference/subtyping.html?" +"search=Hiher#r-subtype.higher-ranked)." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-03-impl.md +msgid "Implementing Branded Types (Branding 3/4)" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-03-impl.md +msgid "" +"Constructing branded types is different to how we construct non-branded " +"types." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-03-impl.md +#: src/idiomatic/leveraging-the-type-system/token-types/branded-04-in-action.md +msgid "// The data we want to modify in this context.\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-03-impl.md +#: src/idiomatic/leveraging-the-type-system/token-types/branded-04-in-action.md +msgid "// The function that uniquely brands the lifetime of a `Bytes`\n" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-03-impl.md +msgid "" +"Motivation: We want to have \"proven indexes\" for a type, and we don't want " +"those indexes to be usable by different variables of the same type. We also " +"don't want those indexes to escape a scope." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-03-impl.md +msgid "Our Branded Type will be `Bytes`: a byte array." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-03-impl.md +msgid "Our Branded Token will be `ProvenIndex`: an index known to be in range." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-03-impl.md +msgid "There are several notable parts to this implementation:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-03-impl.md +msgid "" +"`new` does not return a `Bytes`, instead asking for \"starting data\" and a " +"use-once Closure that is passed a `Bytes` when it is called." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-03-impl.md +msgid "That `new` function has a `for<'a>` on its trait bound." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-03-impl.md +msgid "" +"We have both a getter for an index and a getter for a values with a proven " +"index." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-03-impl.md +msgid "Ask: Why does `new` not return a `Bytes`?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-03-impl.md +msgid "" +"Answer: Because we need `Bytes` to have a unique lifetime controlled by the " +"API." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-03-impl.md +msgid "" +"Ask: So what if `new()` returned `Bytes`, what is the specific harm that it " +"would cause?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-03-impl.md +msgid "Answer: Think about the signature of that hypothetical `new()` method:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-03-impl.md +msgid "`fn new<'a>() -> Bytes<'a> { ... }`" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-03-impl.md +msgid "" +"This would allow the API user to choose what the lifetime `'a` is, removing " +"our ability to guarantee that the lifetimes between different instances of " +"`Bytes` are unique and unable to be subtyped to one another." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-03-impl.md +msgid "Ask: Why do we need both a `get_index` and a `get_proven`?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-03-impl.md +msgid "" +"Expect \"Because we can't know if an index is occupied at compile time\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-03-impl.md +msgid "Ask: Then what's the point of the proven indexes?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-03-impl.md +msgid "" +"Answer: Avoiding bounds checking while keeping knowledge of what indexes are " +"occupied specific to individual variables, unable to erroneously be used on " +"the wrong one." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-03-impl.md +msgid "" +"Note: The focus is not on only on avoiding overuse of bounds checks, but " +"also on preventing that \"cross over\" of indexes." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-04-in-action.md +msgid "Branded Types in Action (Branding 4/4)" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-04-in-action.md +msgid "" +"// bytes_2.get_proven(&index_1); // ❌🔨\n" +" \"Computations done!\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-04-in-action.md +msgid "\"{result}\"" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-04-in-action.md +msgid "" +"We now have the implementation ready, we can now write a program where token " +"types that are proofs of existing indexes cannot be shared between variables." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-04-in-action.md +msgid "" +"Demonstration: Uncomment the `bytes_2.get_proven(&index_1);` line and show " +"that it does not compile when we use indexes from different variables." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-04-in-action.md +msgid "" +"Ask: What operations can we perform that we can guarantee would produce a " +"proven index?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-04-in-action.md +msgid "Expect a \"push\" implementation, suggested demo:" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-04-in-action.md +msgid "" +"Ask: Can we make this not just about a byte array, but as a general wrapper " +"on `Vec`?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-04-in-action.md +msgid "Trivial: Yes!" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-04-in-action.md +msgid "Maybe demonstrate: Generalising `Bytes<'id>` into `BrandedVec<'id, T>`" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-04-in-action.md +msgid "Ask: What other areas could we use something like this?" +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-04-in-action.md +msgid "" +"The resulting token API is **highly restrictive**, but the things that it " +"makes possible to prove as safe within the Rust type system are meaningful." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-04-in-action.md +msgid "" +"[GhostCell](https://plv.mpi-sws.org/rustbelt/ghostcell/paper.pdf), a " +"structure that allows for safe cyclic data structures in Rust (among other " +"previously difficult to represent data structures), uses this kind of token " +"type to make sure cells can't \"escape\" a context where we know where " +"operations similar to those shown in these examples are safe." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-04-in-action.md +msgid "" +"This \"Branded Types\" sequence of slides is based off their `BrandedVec` " +"implementation in the paper, which covers many of the implementation details " +"of this use case in more depth as a gentle introduction to how `GhostCell` " +"itself is implemented and used in practice." +msgstr "" + +#: src/idiomatic/leveraging-the-type-system/token-types/branded-04-in-action.md +msgid "" +"GhostCell also uses formal checks outside of Rust's type system to prove " +"that the things it allows within this kind of context (lifetime branding) " +"are safe." +msgstr "" + +#: src/idiomatic/polymorphism.md +msgid "" +"Rust has plenty of mechanisms for writing and using polymorphic code, but " +"they're somewhat different from other popular languages!" +msgstr "" + +#: src/idiomatic/polymorphism.md +msgid "" +"This chapter will cover the details of Rust's polymorphism and how it's " +"similar, or different to, other languages." +msgstr "" + +#: src/idiomatic/polymorphism/refresher.md +msgid "Basic features of Rust's generics and polymorphism." +msgstr "" + +#: src/idiomatic/polymorphism/refresher.md +msgid "" +"In this section we'll be going through the core concepts of Rust's approach " +"to polymorphism, the things you'll run into the most in day-to-day usage." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/traits.md +msgid "Traits, Protocols, Interfaces" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/traits.md +msgid "\"Email to {}: {}\"" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/traits.md +msgid "\"Chat message sent to {:?}: {}\"" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/traits.md +msgid "" +"Rust's concept of polymorphism and generics is heavily built around traits." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/traits.md +msgid "Traits are requirements on a type in a generic context." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/traits.md +msgid "Requirements function much like a compile-time checked duck typing." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/traits.md +msgid "" +"Duck typing is a concept from the practice of dynamic, untyped languages " +"like Python, \"if it walks like a duck and quacks like a duck, it's a duck.\"" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/traits.md +msgid "" +"That is, types with the methods and fields expected by a function are all " +"valid inputs for that function. If a type implements methods, it is that " +"type in a duck-typing context." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/traits.md +msgid "" +"Traits behave like a static duck typing mechanism, in that we specify " +"behavior rather than type. But we get the compile-time checks on if that " +"behavior does really exist." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/traits.md +msgid "" +"Alternatively: Traits are like collections of propositions, and implementing " +"a trait for a type is a proof that the type can be used wherever the trait " +"is asked for." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/traits.md +msgid "" +"Traits have required methods, implementing those methods is the proof that a " +"type has the required behavior." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/traits.md +msgid "reference:" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/traits.md +msgid "https://doc.rust-lang.org/reference/items/traits.html" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/trait-bounds.md +msgid "Trait Bounds on Generics" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/trait-bounds.md +msgid "\"Item: {}\"" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/trait-bounds.md +#: src/unsafe-deep-dive/initialization/maybeuninit/write-vs-assignment.md +msgid "\"Hello, Rust!\"" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/trait-bounds.md +msgid "// Works with integers\n" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/trait-bounds.md +msgid "// Works with strings\n" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/trait-bounds.md +msgid "" +"Traits are most commonly used as bounds on generic type parameters for a " +"function or method." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/trait-bounds.md +msgid "" +"Without a trait bound on a generic type parameter, we don't have access to " +"any behavior to write functions and methods with." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/trait-bounds.md +msgid "" +"Trait bounds allow us to specify the minimum viable behavior of a type for " +"it to work in generic code." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/trait-bounds.md +#: src/idiomatic/polymorphism/refresher/default-impls.md +#: src/idiomatic/polymorphism/refresher/supertraits.md +#: src/idiomatic/polymorphism/refresher/blanket-impls.md +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +#: src/idiomatic/polymorphism/refresher/sized.md +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-compatible.md +msgid "ref:" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/trait-bounds.md +msgid "https://doc.rust-lang.org/reference/trait-bounds.html" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/deriving-traits.md +msgid "" +"Many traits, protocols, interfaces, have trivial implementations that would " +"be easy to mechanically write." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/deriving-traits.md +msgid "" +"Definitions of types (their syntax trees) can be fed to procedural macros " +"(compiler plugins) to automatically generate implementations of traits." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/deriving-traits.md +msgid "" +"These macros have to be authored by someone, the compiler cannot figure out " +"everything by itself." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/deriving-traits.md +msgid "" +"Many traits have a naive, obvious implementation. Mostly implementations " +"that depend on all fields or variants already implementing the trait." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/deriving-traits.md +msgid "" +"`PartialEq`/`Eq` can be derived on types whose fields / variants all " +"implement those traits fairly easily: line up the fields / variants, if any " +"of them don't match then the equality check returns false." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/deriving-traits.md +msgid "" +"Derives let us avoid boilerplate mechanically and predictably, the authors " +"of a derive implementation likely authored the trait the derive was " +"implemented with the proper semantics of a trait in mind." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/deriving-traits.md +msgid "" +"Ask the class: Have the students had to deal with a codebase where most of " +"the code was trivial boilerplate?" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/deriving-traits.md +msgid "This is similar to Haskell's `deriving` system." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/deriving-traits.md +msgid "references:" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/deriving-traits.md +msgid "" +"https://doc.rust-lang.org/reference/attributes/derive.html#r-attributes." +"derive" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/default-impls.md +msgid "Default Method Implementations" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/default-impls.md +msgid "// Required Method\n" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/default-impls.md +msgid "// Default implementation\n" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/default-impls.md +msgid "" +"Traits often have methods that are implemented for you already, once you " +"implement the required methods." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/default-impls.md +msgid "" +"A trait method has a default implementation if the function body is present. " +"This implementation can be written in terms of other methods available, such " +"as other methods in the trait or methods of a supertrait." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/default-impls.md +msgid "" +"Often you'll see methods that provide the broad functionality that is " +"necessary to implement (like `Ord`'s `compare`) with default implementations " +"for functions that can be implemented in terms of those methods (like " +"`Ord`'s `max`/`min`/`clamp`)." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/default-impls.md +msgid "" +"Default methods can be overridden by derive macros, as derive macros produce " +"arbitrary ASTs in the implementation." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/default-impls.md +msgid "" +"https://doc.rust-lang.org/reference/items/traits.html#r-items.traits." +"associated-item-decls" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/supertraits.md +msgid "Supertraits / Trait Dependencies" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/supertraits.md +msgid "Traits can be extended by new traits." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/supertraits.md +msgid "/* methods common to all animals */" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/supertraits.md +msgid "/* methods only for mammals */" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/supertraits.md +msgid "// From stdlib\n" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/supertraits.md +msgid "/* methods for Ord */" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/supertraits.md +msgid "" +"When authoring a trait, you can specify traits that a type must also. These " +"are called _supertraits_." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/supertraits.md +msgid "" +"For the example above, any type that implements `Mammal` must also implement " +"`Animal`." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/supertraits.md +msgid "" +"These hierarchies of traits let us design systems around the behavior of " +"complex real-world taxonomies (like fauna, machine hardware, operating " +"system specifics, etc)." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/supertraits.md +msgid "This is distinct from object inheritance! But it looks similar." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/supertraits.md +msgid "" +"Object inheritance allows for overrides and brings in the behavior of the " +"inherited types by default." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/supertraits.md +msgid "" +"A trait having a supertrait doesn't mean that trait can override method " +"implementations as default implementations." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/supertraits.md +msgid "" +"https://doc.rust-lang.org/reference/items/traits.html?highlight=supertrait#r-" +"items.traits.supertraits" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/blanket-impls.md +msgid "Blanket Trait Implementations" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/blanket-impls.md +msgid "" +"When a trait is local, we can implement it for as many types as we like. How " +"far can we take this?" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/blanket-impls.md +msgid "" +"// A blanket implementation! If something implements Display, it implements\n" +"// PrettyPrint.\n" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/blanket-impls.md +msgid "\"{self}\"" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/blanket-impls.md +msgid "" +"The subject of a trait implementation at the definition site of a trait can " +"be anything, including `T` with no bounds." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/blanket-impls.md +msgid "" +"We can't do anything with a `T` we don't know nothing about, so this is " +"uncommon." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/blanket-impls.md +msgid "" +"Conditional blanket implementations are much more useful and you are more " +"likely to see and author them." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/blanket-impls.md +msgid "" +"These implementations will have a bound on the trait, like `impl ToString for T {...}`" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/blanket-impls.md +msgid "" +"In the example above we have a blanket implementation for all types that " +"implement Display, the implementation has one piece of information available " +"to it from the trait bounds: it implements `Display::fmt`." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/blanket-impls.md +msgid "" +"This is enough to write an implementation for pretty printing to console." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/blanket-impls.md +msgid "" +"Do be careful with these kinds of implementations, as it may end up " +"preventing users downstream from implementing a more meaningful." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/blanket-impls.md +msgid "" +"The above isn't written for `Debug` as that would mean almost all types end " +"up implementing `PrettyPrint`, and `Debug` is not semantically similar to " +"`Display`: It's meant for debug output instead of something more human-" +"readable." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/blanket-impls.md +msgid "" +"https://doc.rust-lang.org/reference/glossary.html#blanket-implementation" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/conditional-methods.md +msgid "Conditional Method Implementations" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/conditional-methods.md +msgid "// No trait bounds on the type definition.\n" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/conditional-methods.md +msgid "// Instead bounds are put on the implementations for the type.\n" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/conditional-methods.md +msgid "// alternatively\n" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/conditional-methods.md +msgid "// Specifies the trait bound in a where expression\n" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/conditional-methods.md +msgid "" +"When authoring a type with generic parameters, we can write implementations " +"for that type that depend on what the parameters are or what traits they " +"implement." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/conditional-methods.md +msgid "These methods are only available when the type meets those conditions." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/conditional-methods.md +msgid "" +"For things like ordered sets, where you'd want the inner type to always be " +"`Ord`, this is the preferred way of putting a trait bound on a parameter of " +"a type." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/conditional-methods.md +msgid "" +"We don't put the definition on the type itself as this would cause " +"downstream issues for everywhere the type is mentioned with a generic " +"parameter." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/conditional-methods.md +msgid "" +"We can maintain invariants just fine with conditional method implementations." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +msgid "" +"What prevents users from writing arbitrary trait implementations for any " +"type?" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +msgid "// Crate `postgresql-bindings`\n" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +msgid "/* details */" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +msgid "// Crate `database-traits`, depends on `postgresql-bindings`\n" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +#: src/idiomatic/polymorphism/from-oop-to-rust/sealed-traits.md +msgid "/* methods */" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +msgid "// ✅, `DbConnection` is local.\n" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +msgid "// Crate `mycoolnewdb` depends on `database-traits`\n" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +msgid "// ✅, `MyCoolNewDbConn` is local.\n" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +msgid "" +"// Neither `PostgresqlConn` or `DbConnection` are local to `mycoolnewdb`.\n" +"// This would lead to two implementations of `DbConnection` for " +"PostgresqlConn!\n" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +msgid "// ❌🔨\n" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +msgid "" +"Rust traits should never be able to be implemented twice in its ecosystem. " +"Two implementations of the same trait for the same type is a conflict with " +"no solution." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +msgid "" +"We can prevent this within a crate by detecting if there are multiple " +"definitions and disallowing it, but what about between crates in the entire " +"Rust ecosystem?" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +msgid "" +"Types are either _local_ to a crate, they are defined there, or they're not." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +msgid "" +"In the example's \"crates\", `PostgresqlConn` is local to `postgresql-" +"bindings`, `MyCoolNewDbConn` is local to `mycoolnewdb`." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +msgid "" +"Traits are also either _local_ to a crate, they are defined there, or " +"they're not." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +msgid "" +"Again in the example, the `DbConnection` trait is local to `database-traits`." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +msgid "If something is local, you can write trait implementations for it." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +msgid "" +"If the trait is local, you can write implementations of that trait for any " +"type." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +msgid "" +"If the type is local, you can write any trait implementations for that type." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +msgid "Outside of these boundaries, trait implementations cannot be written." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +msgid "" +"This keeps implementations \"coherent\": Only one implementation of a trait " +"for a type can exist across crates." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/orphan-rule.md +msgid "" +"https://doc.rust-lang.org/stable/reference/items/implementations.html#r-" +"items.impl.trait.orphan-rule" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/sized.md +msgid "Statically Sized and Dynamically Sized Types" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/sized.md +msgid "/* : Sized */" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/sized.md +msgid "" +"Motivation: Being able to specify between types whose size are known and " +"compile time and types whose size are known at runtime is useful for" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/sized.md +msgid "" +"The Sized trait is automatically implemented by types with a known size at " +"compile-time." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/sized.md +msgid "" +"This trait is also automatically added to any type parameter that doesn't " +"opt-out of being sized." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/sized.md +msgid "Most types implement `Sized`: they have a compile-time known size." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/sized.md +msgid "" +"Types like `[T]`, `str` and `dyn Trait` are all dynamically sized types. " +"Their size is stored as part of the reference to the value of that type." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/sized.md +msgid "Type parameters automatically implement `Sized` unless specified." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/sized.md +msgid "" +"https://doc.rust-lang.org/stable/reference/dynamically-sized-types.html#r-" +"dynamic-sized" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/monomorphization.md +msgid "// instance one, &Vec -> ()\n" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/monomorphization.md +msgid "// instance two, &Vec -> ()\n" +msgstr "" + +#: src/idiomatic/polymorphism/refresher/monomorphization.md +msgid "" +"Each instance of a function or type with generics gets transformed into a " +"unique, concrete version of that function at compile time. Generics do not " +"exist at runtime, only specific types." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/monomorphization.md +msgid "" +"This comes with a strong baseline performance and capacity for optimization, " +"but at a cost of binary size and compile time." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/monomorphization.md +msgid "" +"There are plenty of ways to trim binary size and compilation times, but " +"we're not covering them here." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/monomorphization.md +msgid "" +"Pay for what you use: Binary size increase of monomorphization is only " +"incurred for instances of a type or functions on a type used in the final " +"program or dynamic library." +msgstr "" + +#: src/idiomatic/polymorphism/refresher/monomorphization.md +msgid "" +"When to care: Monomorphization impacts compile times and binary size. In " +"circumstances like WebAssembly in-browser or embedded systems development, " +"you may want to be mindful about designing with generics in mind." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust.md +msgid "From OOP to Rust: Composition, Not Inheritance" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust.md +msgid "" +"Inheritance is key to OOP's success as a paradigm. Decades of successful " +"software engineering has been done with Inheritance as a core part of " +"business logic." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust.md +msgid "So why did Rust avoid inheritance?" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust.md +msgid "" +"How do we move from inheritance-based problem solving to Rust's approach?" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust.md +msgid "How do you represent heterogeneous collections in Rust?" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust.md +msgid "" +"In this section we'll be looking at how to move from thinking about " +"polymorphic problem solving with types in OOP languages like java, C++ etc. " +"to Rust's trait-based approach to Polymorphism." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust.md +msgid "" +"There will be differences, but there are also plenty of areas in common – " +"especially with modern standards of OOP development. Remember to keep an " +"open mind." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/inheritance.md +msgid "Inheritance in OOP languages" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/inheritance.md +msgid "// Base class\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/inheritance.md +msgid "// Inheriting class\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/inheritance.md +msgid "// Create a Car object\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/inheritance.md +msgid "// Inherited method\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/inheritance.md +msgid "// Car's own method\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/inheritance.md +msgid "" +"This should be a short reminder for students about what inheritance is in " +"other languages." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/inheritance.md +msgid "" +"Inheritance is a mechanism where a \"child\" type gains the fields and " +"methods of the \"parent\" types it is inheriting from." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/inheritance.md +msgid "Methods are able to be overridden as-needed by the inheriting type." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/inheritance.md +msgid "Can call methods of inherited-from classes with `super`." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/why-no-inheritance.md +msgid "// methods\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/why-no-inheritance.md +msgid "// 🔨❌, Rust does not have inheritance!\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/why-no-inheritance.md +msgid "// Inherited \"id\" field\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/why-no-inheritance.md +msgid "" +"// methods, but also includes Id's methods, or maybe overrides to\n" +" // those methods.\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/why-no-inheritance.md +msgid "// ✅\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/why-no-inheritance.md +msgid "// All of data's methods that aren't from traits.\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/why-no-inheritance.md +msgid "// Implementations for traits in separate impl blocks.\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/why-no-inheritance.md +msgid "Inheritance comes with a number of downsides." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/why-no-inheritance.md +msgid "Heterogeneous by default:" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/why-no-inheritance.md +msgid "" +"Class inheritance implicitly allows types of different classes to be used " +"interchangeably, without being able to specify a concrete type or if a type " +"is identical to another." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/why-no-inheritance.md +msgid "" +"For operations like equality, comparison this allows for comparison and " +"equality that throws and error or otherwise panics." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/why-no-inheritance.md +msgid "" +"Multiple sources of truth for what makes up a data structure and how it " +"behaves:" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/why-no-inheritance.md +msgid "A type's fields are obscured by the inheritance hierarchy." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/why-no-inheritance.md +msgid "" +"A type's methods could be overriding a parent type or be overridden by a " +"child type, it's hard to tell what the behavior of a type is in complex " +"codebases maintained by multiple parties." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/why-no-inheritance.md +msgid "Dynamic dispatch as default adds overhead from vtable lookups:" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/why-no-inheritance.md +msgid "" +"For dynamic dispatch to work, there needs to be somewhere to store " +"information on what methods to call and other pieces of runtime-known pieces " +"of information on the type." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/why-no-inheritance.md +msgid "" +"This store is the `vtable` for a value. Method calls will require more " +"dereferences than calling a method for a type that is known at compile time." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/switch-perspective.md +msgid "// Data\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/switch-perspective.md +msgid "// Concrete behavior\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/switch-perspective.md +msgid "// Abstract behavior\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/switch-perspective.md +msgid "// Instanced behavior\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/switch-perspective.md +msgid "" +"From Rust's perspective, one where Inheritance was never there, introducing " +"inheritance would look like muddying the water between types and traits." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/switch-perspective.md +msgid "A type is a concrete piece of data and its associated behavior." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/switch-perspective.md +msgid "A trait is abstract behavior that must be implemented by a type." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/switch-perspective.md +msgid "" +"A class is a combination of data, behavior, and overrides to that behavior." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/switch-perspective.md +msgid "" +"Coming from Rust, an inheritable class looks like a type that is also a " +"trait." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/switch-perspective.md +msgid "This is not an upside, as we can no longer reason about concrete types." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/switch-perspective.md +msgid "" +"Without being able to separate the two, it becomes difficult to reason about " +"generic behavior vs concrete specifics, because in OOP these two concepts " +"are tied up in each other." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/switch-perspective.md +msgid "" +"The convenience of flat field access and DRY in type definitions is not " +"worth the loss in specificity between writing code that delineates between " +"behavior and data." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/supertraits.md +msgid "\"Inheritance\" in Rust: Supertraits" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/supertraits.md +msgid "" +"In Rust, traits can depend on other traits. We're already familiar with " +"Traits being able to have Supertraits." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/supertraits.md +msgid "This looks superficially similar to inheritance." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/supertraits.md +msgid "" +"This is a mechanism like inheritance, but separates the data from the " +"behavior." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/supertraits.md +msgid "Keeps behavior in a state where it's easy to reason about." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/supertraits.md +msgid "Makes what we aim to achieve with \"multiple inheritance\" easier too:" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/supertraits.md +msgid "" +"We only care about what behavior a type is capable of at the point where we " +"clarify we want that behavior (when bounding a generic by traits)." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/supertraits.md +msgid "" +"By specifying multiple traits on a generic, we know that the type has the " +"methods of all those traits." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/supertraits.md +msgid "" +"Does not involve inheritance of fields. A trait doesn't expose fields, only " +"methods and associated types / constants." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/composition.md +msgid "" +"Rather than mixins or inheritance, we compose types by creating fields of " +"different types." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/composition.md +msgid "" +"This has downsides, largely in ergonomics of field access, but gives " +"developers a lot of control and clarity over what a type does and it has " +"access to." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/composition.md +msgid "" +"When deriving traits, make sure all the field types of a struct or variant " +"types of an enum implement that trait. Derive macros often assume all types " +"that compose a new type implement that trait already." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-trait.md +msgid "`dyn Trait` for Dynamic Dispatch in Rust" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-trait.md +msgid "\"Hello dyn!\"" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-trait.md +msgid "" +"Dynamic Dispatch is a tool in Object Oriented Programming that is often used " +"in places where one needs to care more about the behavior of a type than " +"what the type is." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-trait.md +msgid "" +"In OOP languages, dynamic dispatch is often an _implicit_ process and not " +"something you can opt out of." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-trait.md +msgid "In Rust, we use `dyn Trait`: an opt-in form of dynamic dispatch." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-trait.md +msgid "" +"For any trait that is _dyn compatible_ we can coerce a reference to a value " +"of that trait into a `dyn Trait` value." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-trait.md +msgid "" +"We call these _trait objects_. Their type is not known at compile time, but " +"their behavior is: what is implemented by the trait itself." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-trait.md +msgid "" +"When you _need_ OOP-style heterogeneous data structures, you can reach for " +"`Box`, but try to keep it homogeneous and generic-based first!" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-compatible.md +msgid "Dyn-compatible traits" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-compatible.md +msgid "// dyn compatible\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-compatible.md +msgid "// dyn compatible, but you can't use this method when it's dyn\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-compatible.md +msgid "// no longer dyn compatible\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-compatible.md +msgid "" +"Not all traits are able to be invoked as trait objects. A trait that can be " +"invoked is referred to as a _dyn compatible_ trait." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-compatible.md +msgid "This was previously called _object safe traits_ or _object safety_." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-compatible.md +msgid "" +"Dynamic dispatch offloads a lot of compile-time type information into " +"runtime vtable information." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-compatible.md +msgid "" +"If a concept is incompatible with what we can meaningfully store in a " +"vtable, either the trait stops being dyn compatible or those methods are " +"excluded from being able to be used in a dyn context." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-compatible.md +msgid "" +"A trait is dyn-compatible when all its supertraits are dyn-compatible and " +"when it has no associated constants/types, and no methods that depend on " +"generics." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-compatible.md +msgid "" +"You'll most frequently run into dyn incompatible traits when they have " +"associated types/constants or return values of `Self` (i.e. the Clone trait " +"is not dyn compatible.)" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-compatible.md +msgid "" +"This is because the associated data would have to be stored in vtables, " +"taking up extra memory." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-compatible.md +msgid "" +"For methods like `clone`, this disqualifies dyn compatibility because the " +"output type depends on the concrete type of `self`." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-compatible.md +msgid "" +"https://doc.rust-lang.org/1.91.1/reference/items/traits.html#r-items.traits." +"dyn-compatible" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-vs-generics.md +msgid "Generic Function Parameters vs dyn Trait" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-vs-generics.md +msgid "" +"We have two means of writing polymorphic functions, how do they compare?" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-vs-generics.md +msgid "// Monomorphized to a unique function for i32 inputs.\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-vs-generics.md +msgid "// One per\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-vs-generics.md +msgid "We can write polymorphic functions over generics or over trait objects." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-vs-generics.md +msgid "" +"When writing functions with generic parameters, for each unique type that " +"substitutes a parameter a new version of that function is generated." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-vs-generics.md +msgid "" +"We went over this in monomorphization: in exchange for binary size, we gain " +"a greater capacity for optimization." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-vs-generics.md +msgid "" +"When writing functions that take a trait object, only one version of that " +"function will exist in the final binary (not counting inlining.)" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/dyn-vs-generics.md +msgid "" +"Generic parameters are zero-cost other than binary size. Types must be " +"homogenous (all instances of T can only be the same type)." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/limits.md +msgid "// 4 bytes, owned value\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/limits.md +msgid "// 8 bytes, reference\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/limits.md +msgid "// 16 bytes, wide pointer\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/limits.md +msgid "Trait objects are a limited way of solving problems." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/limits.md +msgid "" +"If you want to downcast to a concrete type from a trait object, you will " +"need to specify that the trait in question has Any as a supertrait or that " +"the trait object is over the main trait and `Any`." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/limits.md +msgid "Even then, you will still need to cast a `dyn MyTrait` to `dyn Any`" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/limits.md +msgid "" +"Trait objects have overhead in memory, they are \"wide pointers\" that need " +"to hold not just the pointer to the data itself but another pointer for the " +"vtable." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/limits.md +msgid "" +"Trait objects, being dynamically sized types, can only be used practically " +"via reference or pointer types." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/limits.md +msgid "" +"There is a baseline overhead of dereferencing the value and relevant trait " +"methods when using trait objects." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/heterogeneous.md +msgid "Heterogeneous data with `dyn trait`" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/heterogeneous.md +msgid "\"Îģ\"" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/heterogeneous.md +msgid "\"Woah\"" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/heterogeneous.md +msgid "// We know \"item\" implements Display, but we know nothing else!\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/heterogeneous.md +msgid "\"Display output: {}\"" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/heterogeneous.md +msgid "" +"`dyn Trait`, being a dynamic dispatch tool, lets us store heterogeneous data " +"in collections." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/heterogeneous.md +msgid "" +"In this example, we're storing types that all implement `std::fmt::Display` " +"and printing all items in that collection to screen." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/any-trait.md +msgid "Any Trait and Downcasting" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/any-trait.md +msgid "" +"The `Any` trait allows us to downcast values back from dyn values into " +"concrete values." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/any-trait.md +msgid "" +"This is an auto trait: like Send/Sync/Sized, it is automatically implemented " +"for any type that meets specific criteria." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/any-trait.md +msgid "" +"The criteria for Any is that a type is `'static`. That is, the type does not " +"contain any non-`'static` lifetimes within it." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/any-trait.md +msgid "" +"Any offers two related behaviors: downcasting, and runtime checking of types " +"being the same." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/any-trait.md +msgid "" +"In the example above, we see the ability to downcast from `Any` into " +"`ThisImplementsAny` automatically." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/any-trait.md +msgid "" +"We also see `Any::is` being used to check to see what type the value is." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/any-trait.md +msgid "" +"`Any` does not implement reflection for a type, this is all you can do with " +"`Any`." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/pitfalls.md +msgid "" +"Coming from an OOP background, it's understandable to reach for this dynamic " +"dispatch tool as early as possible." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/pitfalls.md +msgid "" +"This is not the preferred way of doing things, trait objects put us in a " +"situation where we're exchanging knowledge of a type that both the developer " +"and compiler has for flexibility." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/pitfalls.md +msgid "" +"The above example takes things to the absurd: If adding numbers were tied up " +"in the dynamic dispatch process, it would be difficult to do anything at all." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/pitfalls.md +msgid "" +"But dynamic dispatch is often hidden in a lot of programming languages: " +"here's it is more explicit." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/pitfalls.md +msgid "" +"In the `i32` implementation of `AddDyn`, first we need to attempt to " +"downcast the `rhs` argument to the same type as `i32`, silently failing if " +"this isn't the case." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/pitfalls.md +msgid "" +"Then we need to allocate the new value on the heap, because if we're keeping " +"this in the world of dynamic dispatch then we need to do this." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/pitfalls.md +msgid "" +"Once we've added two values together, if we want to view them we must " +"downcast them again into a \"real\" type we can print out given the trait " +"bounds tied up in the operation so far." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/pitfalls.md +msgid "" +"Ask the class: Why can't we just add Display bounds in `main` to be able to " +"print things as-is?" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/pitfalls.md +msgid "" +"Answer: Because add_dyn returns only a `dyn AddDyn`, we lose information " +"about what the type implements between the argument type and return type. " +"Even if the inputs implement `Display`, the return type does not." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/dynamic-dispatch/pitfalls.md +msgid "This leads to less performant code which is harder to understand" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/sealed-traits.md +msgid "Sealed traits for Polymorphism users cannot extend" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/sealed-traits.md +msgid "" +"// crate can access the \"sealed\" module and its trait, but projects that\n" +"// depend on it cannot.\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/sealed-traits.md +msgid "//...\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/sealed-traits.md +msgid "" +"Motivation: We want trait-driven code in a crate, but we don't want projects " +"that depend on this crate to be able to implement a trait." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/sealed-traits.md +msgid "Why?" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/sealed-traits.md +msgid "" +"The trait could be considered unstable for downstream-implementations at " +"this point in time." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/sealed-traits.md +msgid "" +"Alternatively: Domain is high-risk for naive implementations of a trait " +"(such as cryptography)." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/sealed-traits.md +msgid "" +"The mechanism we use to do this is restricting access to a supertrait, " +"preventing downstream users from being able to implement that trait for " +"their types." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/sealed-traits.md +msgid "Why not just use enums?" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/sealed-traits.md +msgid "Enums expose implementation details – \"this works for these types\"." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/sealed-traits.md +msgid "Users need to use variant constructors of an enum to use the API." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/sealed-traits.md +msgid "" +"Users can use the enum as a type in their own code, and when the enum " +"changes users need to update their code to match those changes." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/sealed-traits.md +msgid "" +"Enums require branching on variants, whereas sealed traits lets the compile " +"specify monomorphized functions for each type." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/sealing-with-enums.md +msgid "" +"Motivation: API is designed around a specific list of types that are valid " +"for it, users of the API are not expected to extend it." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/sealing-with-enums.md +msgid "" +"Enums in Rust are _algebraic data types_, we can define different structures " +"for each variant." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/sealing-with-enums.md +msgid "" +"For some domains, this might be enough polymorphism for the problem. " +"Experiment and see what works, what solutions seem to make more sense." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/sealing-with-enums.md +msgid "" +"By having the user-facing part of the API refer to an enum, users know what " +"types are valid inputs and can construct those types using the available " +"methods to do so." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/sealing-with-enums.md +msgid "" +"If the types that make up the enum have invariants that the API internally " +"upholds, and the only way users can construct those types is through " +"constructors that build and maintain those invariants, then you can be sure " +"that inputs to a generic method uphold their invariants." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/sealing-with-enums.md +msgid "" +"If the types that make up the enum instead are types the user can freely " +"construct, then sanitisation and interpretation may need to be taken into " +"consideration." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/sticking-with-traits.md +msgid "// Crate A\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/sticking-with-traits.md +msgid "// Crate B, depends on A\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/sticking-with-traits.md +msgid "" +"We've already covered normal traits at length, but compared to enums and " +"sealed traits they allow users to extend an API by implementing the behavior " +"that API asks of them." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/sticking-with-traits.md +msgid "" +"This ability for users to extend is powerful for a number of domains, from " +"serialization to abstract representations of hardware and type safe linear " +"algebra." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/sticking-with-traits.md +msgid "" +"If a trait is exposed publicly in a crate, a user depending on that crate " +"can implement that trait for types they define." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/problem-solving.md +msgid "// Problem: implementing a GUI API\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/problem-solving.md +msgid "// Question: What's the minimum useful behavior for a drawing API?\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/problem-solving.md +msgid "\"arc of radius \"" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/problem-solving.md +msgid "// Question: What's a good API for users?\n" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/problem-solving.md +msgid "" +"You're already adept at breaking down problems, but you're likely used to " +"reaching for OOP-style methods." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/problem-solving.md +msgid "" +"This isn't a drastic change, it just requires re-ordering the way you " +"approach things." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/problem-solving.md +msgid "Try to solve the problem with either Generics & Traits or Enums first." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/problem-solving.md +msgid "" +"Does the problem require a specific set of types? An enum may be the " +"cleanest way of solving this problem." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/problem-solving.md +msgid "" +"Does the problem really care about the specifics of the types involved, or " +"can behavior be focused on?" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/problem-solving.md +msgid "" +"Organize your problem solving around finding a minimum viable amount of " +"knowledge to implement something." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/problem-solving.md +msgid "Does a trait already exist for this use case? If so, use it!" +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/problem-solving.md +msgid "" +"If you really do need heterogeneous collections, use them! They exist in " +"Rust as a tool for a reason." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/problem-solving.md +msgid "" +"Be aware of the XY problem: a problem may seem most easily addressable by " +"one solution, but it might not tackle the root cause and could lead to new " +"difficult problems popping up in the future." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/problem-solving.md +msgid "" +"That is, be certain that dynamic dispatch with trait objects is what you " +"need before you commit to using them." +msgstr "" + +#: src/idiomatic/polymorphism/from-oop-to-rust/problem-solving.md +msgid "" +"Be certain that traits are what you need before you commit to using them." +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "IMPORTANT: THIS MODULE IS IN AN EARLY STAGE OF DEVELOPMENT" +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "" +"Please do not consider this module of Comprehensive Rust to be complete. " +"With that in mind, your feedback, comments, and especially your concerns, " +"are very welcome." +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "" +"To comment on this module's development, please use the [GitHub issue " +"tracker](https://github.com/google/comprehensive-rust/issues)." +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "Welcome to the Unsafe Rust Deep Dive" +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "" +"This deep dive aims to enable you to work productively with Unsafe Rust." +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "We’ll work on three areas:" +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "establishing a mental model of Unsafe Rust" +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "practicing reading & writing Unsafe Rust" +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "practicing code review for Unsafe Rust" +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "" +"The goal of this class is to teach you enough Unsafe Rust for you to be able " +"to review easy cases yourself, and distinguish difficult cases that need to " +"be reviewed by more experienced Unsafe Rust engineers." +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "Establishing a mental model of Unsafe Rust" +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "what the `unsafe` keyword means" +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "a shared vocabulary for talking about safety" +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "a mental model of how memory works" +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "common patterns" +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "expectations for code that uses `unsafe`" +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "Practicing working with unsafe" +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "reading and writing both code and documentation" +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "using unsafe APIs" +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "designing and implementing them" +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "Reviewing code" +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "the confidence to self-review easy cases" +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "the knowledge to detect difficult cases" +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "" +"“We'll be using a spiral model of teaching. This means that we revisit the " +"same topic multiple times with increasing depth.”" +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "" +"A round of introductions is useful, particularly if the class participants " +"don't know each other well. Ask everyone to introduce themselves, noting " +"down any particular goals for the class." +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "Who are you?" +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "What are you working on?" +msgstr "" + +#: src/unsafe-deep-dive/welcome.md +msgid "What are your goals for this class?" +msgstr "" + +#: src/unsafe-deep-dive/setup.md +msgid "Setting Up" +msgstr "" + +#: src/unsafe-deep-dive/setup.md +msgid "Local Rust installation" +msgstr "" + +#: src/unsafe-deep-dive/setup.md +msgid "" +"You should have a Rust compiler installed that supports the 2024 edition of " +"the language, which is any version of rustc higher than 1.84." +msgstr "" + +#: src/unsafe-deep-dive/setup.md +msgid "(Optional) Create a local instance of the course" +msgstr "" + +#: src/unsafe-deep-dive/setup.md +msgid "" +"```console\n" +"$ git clone --depth=1 https://github.com/google/comprehensive-rust.git\n" +"Cloning into 'comprehensive-rust'...\n" +"...\n" +"$ cd comprehensive-rust\n" +"$ cargo install-tools\n" +"...\n" +"$ cargo serve # then open http://127.0.0.1:3000/ in a browser\n" +"```" +msgstr "" + +#: src/unsafe-deep-dive/setup.md +msgid "" +"Ask everyone to confirm that everyone is able to execute `rustc` with a " +"version newer than 1.87." +msgstr "" + +#: src/unsafe-deep-dive/setup.md +msgid "" +"For those people who do not, tell them that we'll resolve that in the break." +msgstr "" + +#: src/unsafe-deep-dive/introduction.md +msgid "" +"We'll start our course by creating a shared understanding of what Unsafe " +"Rust is and what the `unsafe` keyword does." +msgstr "" + +#: src/unsafe-deep-dive/introduction.md src/unsafe-deep-dive/pinning.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer.md +msgid "Outline" +msgstr "" + +#: src/unsafe-deep-dive/introduction.md +msgid "25 minutes" +msgstr "" + +#: src/unsafe-deep-dive/introduction/definition.md +msgid "“Unsafe Rust is a superset of Safe Rust.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/definition.md +msgid "" +"“Unsafe Rust adds extra capabilities, such as allowing you to dereference " +"raw pointers and call functions that can break Rust’s safety guarantees if " +"called incorrectly.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/definition.md +msgid "“These extra capabilities are referred to as _unsafe operations_.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/definition.md +msgid "" +"“Unsafe operations provide the foundation that the Rust standard library is " +"built on. For example, without the ability to dereference a raw pointer, it " +"would be impossible to implement `Vec` or `Box`.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/definition.md +msgid "" +"“The compiler will still assist you while writing Unsafe Rust. Borrow " +"checking and type safety still apply. Unsafe operations have their own " +"rules, which we’ll learn about in this class.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/definition.md +msgid "" +"The unsafe operations from the [Rust Reference](https://doc.rust-lang.org/" +"reference/unsafety.html) (Avoid spending too much time):" +msgstr "" + +#: src/unsafe-deep-dive/introduction/definition.md +msgid "" +"The following language level features cannot be used in the safe subset of " +"Rust:" +msgstr "" + +#: src/unsafe-deep-dive/introduction/definition.md +msgid "Dereferencing a raw pointer." +msgstr "" + +#: src/unsafe-deep-dive/introduction/definition.md +msgid "Reading or writing a mutable or unsafe external static variable." +msgstr "" + +#: src/unsafe-deep-dive/introduction/definition.md +msgid "Accessing a field of a union, other than to assign to it." +msgstr "" + +#: src/unsafe-deep-dive/introduction/definition.md +msgid "Calling an `unsafe` function." +msgstr "" + +#: src/unsafe-deep-dive/introduction/definition.md +msgid "" +"Calling a safe function marked with a `` from a function " +"that does not have a `` attribute enabling the same features." +msgstr "" + +#: src/unsafe-deep-dive/introduction/definition.md +msgid "Implementing an unsafe trait." +msgstr "" + +#: src/unsafe-deep-dive/introduction/definition.md +msgid "Declaring an extern block." +msgstr "" + +#: src/unsafe-deep-dive/introduction/definition.md +msgid "Applying an unsafe attribute to an item." +msgstr "" + +#: src/unsafe-deep-dive/introduction/purpose.md +msgid "Why the unsafe keyword exists" +msgstr "" + +#: src/unsafe-deep-dive/introduction/purpose.md +msgid "Rust ensures safety" +msgstr "" + +#: src/unsafe-deep-dive/introduction/purpose.md +msgid "But there are limits to what the compiler can do" +msgstr "" + +#: src/unsafe-deep-dive/introduction/purpose.md +msgid "" +"The unsafe keyword allows programmers to assume responsibility for Rust’s " +"rules" +msgstr "" + +#: src/unsafe-deep-dive/introduction/purpose.md +msgid "“A fundamental goal of Rust is to ensure memory safety.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/purpose.md +msgid "" +"“But, there are limits. Some safety considerations cannot be expressed in a " +"programming language. Even if they could be, there are limits to what the " +"Rust compiler can control.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/purpose.md +msgid "" +"“The `unsafe` keyword shifts the burden of upholding Rust’s rules from the " +"compiler to the programmer.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/purpose.md +msgid "" +"“When you see the `unsafe` keyword, you are seeing responsibility shift from " +"the compiler to the programmer." +msgstr "" + +#: src/unsafe-deep-dive/introduction/two-roles.md +msgid "The unsafe keyword has two roles" +msgstr "" + +#: src/unsafe-deep-dive/introduction/two-roles.md +msgid "_Creating_ APIs with safety considerations" +msgstr "" + +#: src/unsafe-deep-dive/introduction/two-roles.md +msgid "unsafe functions: `unsafe fn get_unchecked(&self) { ... }`" +msgstr "" + +#: src/unsafe-deep-dive/introduction/two-roles.md +msgid "unsafe traits: `unsafe trait Send {}`" +msgstr "" + +#: src/unsafe-deep-dive/introduction/two-roles.md +msgid "_Using_ APIs with safety considerations" +msgstr "" + +#: src/unsafe-deep-dive/introduction/two-roles.md +msgid "invoking built-in unsafe operators: `unsafe { *ptr }`" +msgstr "" + +#: src/unsafe-deep-dive/introduction/two-roles.md +msgid "calling unsafe functions: `unsafe { x.get_unchecked() }`" +msgstr "" + +#: src/unsafe-deep-dive/introduction/two-roles.md +msgid "implementing unsafe traits: `unsafe impl Send for Counter {}`" +msgstr "" + +#: src/unsafe-deep-dive/introduction/two-roles.md +msgid "Two roles:" +msgstr "" + +#: src/unsafe-deep-dive/introduction/two-roles.md +msgid "" +"**Creating** APIs with safety considerations and defining what needs to be " +"considered" +msgstr "" + +#: src/unsafe-deep-dive/introduction/two-roles.md +msgid "" +"**Using** APIs with safety considerations and confirming that the " +"consideration has been made" +msgstr "" + +#: src/unsafe-deep-dive/introduction/two-roles.md +msgid "Creating APIs with safety considerations" +msgstr "" + +#: src/unsafe-deep-dive/introduction/two-roles.md +msgid "" +"“First, the unsafe keyword enables you to create APIs that can break Rust’s " +"safety guarantees. Specifically, you need to use the unsafe keyword when " +"defining unsafe functions and unsafe traits." +msgstr "" + +#: src/unsafe-deep-dive/introduction/two-roles.md +msgid "" +"“When used in this role, you’re informing users of your API that they need " +"to be careful.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/two-roles.md +msgid "" +"“The creator of the API should communicate what care needs to be taken. " +"Unsafe APIs are not complete without documentation about safety " +"requirements. Callers need to know that they have satisfied any " +"requirements, and that’s impossible if they’re not written down.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/two-roles.md +msgid "Using APIs with safety considerations" +msgstr "" + +#: src/unsafe-deep-dive/introduction/two-roles.md +msgid "" +"“The unsafe keyword adopts its other role, using APIs, when it is used " +"nearby to a curly brace." +msgstr "" + +#: src/unsafe-deep-dive/introduction/two-roles.md +msgid "" +"“When used in this role, the unsafe keyword means that the author has been " +"careful. They have verified that the code is safe and is providing an " +"assurance to others.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/two-roles.md +msgid "" +"“Unsafe blocks are most common. They allow you to invoke unsafe functions " +"that have been defined using the first role." +msgstr "" + +#: src/unsafe-deep-dive/introduction/two-roles.md +msgid "" +"“Unsafe blocks also allow you to perform operations which the compiler knows " +"are unsafe, such as dereferencing a raw pointer.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/two-roles.md +msgid "" +"“You might also see the unsafe keyword being used to implement unsafe traits." +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up.md +msgid "Warm-up examples" +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up.md +msgid "Examples to demonstrate:" +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up.md +msgid "using an [unsafe block](warm-up/unsafe-block.md) (`unsafe { ... }`)" +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up.md +msgid "defining an [unsafe function](warm-up/unsafe-fn.md) (`unsafe fn`)" +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up.md +msgid "" +"[implementing](warm-up/unsafe-impl.md) an unsafe trait (`unsafe impl { ... }" +"`)" +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up.md +msgid "defining an [unsafe trait](warm-up/unsafe-trait.md) (`unsafe trait`)" +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-block.md +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-fn.md +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-impl.md +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-trait.md +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/sometimes-necessary.md +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/sometimes-useful.md +#: src/unsafe-deep-dive/introduction/may_overflow.md +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +#: src/unsafe-deep-dive/safety-preconditions/getter.md +#: src/unsafe-deep-dive/safety-preconditions/determining.md +#: src/unsafe-deep-dive/safety-preconditions/references.md +#: src/unsafe-deep-dive/safety-preconditions/ascii.md +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory.md +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/safe.md +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/encapsulated-unsafe.md +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/documented-safety-preconditions.md +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/crying-wolf.md +#: src/unsafe-deep-dive/initialization/maybeuninit.md +#: src/unsafe-deep-dive/initialization/maybeuninit/arrays.md +#: src/unsafe-deep-dive/initialization/maybeuninit/zeroed-method.md +#: src/unsafe-deep-dive/initialization/maybeuninit/write-vs-assignment.md +#: src/unsafe-deep-dive/initialization/how-to-initialize-memory.md +#: src/unsafe-deep-dive/initialization/partial-initialization.md +#: src/unsafe-deep-dive/pinning/what-a-move-is.md +#: src/unsafe-deep-dive/pinning/definition-of-pin.md +#: src/unsafe-deep-dive/pinning/phantompinned.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust-raw-pointers.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust-offset.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust-pin.md +#: src/unsafe-deep-dive/pinning/pin-and-drop.md +#: src/unsafe-deep-dive/pinning/drop-and-not-unpin-worked-example.md +#: src/unsafe-deep-dive/ffi/language-differences/representations.md +#: src/unsafe-deep-dive/ffi/language-differences/semantics.md +#: src/unsafe-deep-dive/ffi/abs.md src/unsafe-deep-dive/ffi/rand.md +#: src/unsafe-deep-dive/ffi/c-library-example.md +#: src/unsafe-deep-dive/ffi/cpp-library-example.md +msgid "// Copyright 2026 Google LLC\n" +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-block.md +msgid "" +"Walk through the code. Confirm that the audience is familiar with the " +"dereference operator." +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-block.md +msgid "Attempt to compile the code, trigger the compiler error." +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-block.md +msgid "Add the unsafe block:" +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-block.md +msgid "" +"Prompt audience for a code review. Guide learners towards adding a safety " +"comment." +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-block.md +msgid "Add the safety comment:" +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-block.md +msgid "// SAFETY: `i` must be within 0..numbers.len()\n" +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-block.md +#: src/unsafe-deep-dive/safety-preconditions/references.md +#: src/unsafe-deep-dive/ffi/c-library-example.md +#: src/unsafe-deep-dive/ffi/cpp-library-example.md +msgid "_Suggested Solution_" +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-fn.md +msgid "" +"/// Convert a nullable pointer to a reference.\n" +"///\n" +"/// Returns `None` when `p` is null, otherwise wraps `val` in `Some`.\n" +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-fn.md +msgid "// SAFETY: `ptr` is non-null\n" +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-fn.md +msgid "" +"“This looks as though it’s safe code, however it actually requires an unsafe " +"block.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-fn.md +msgid "Highlight the dereference operation, i.e. `*p` within the unsafe block." +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-fn.md +msgid "" +"“Callers must ensure that the `ptr` is null, or that it may be converted to " +"a reference." +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-fn.md +msgid "" +"“It may be counter-intuitive, but many pointers cannot be converted to " +"references." +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-fn.md +msgid "" +"“Among other issues, a pointer could be created that points to some " +"arbitrary bits rather than a valid value. That’s not something that Rust " +"allows and something that this function needs to protect itself against." +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-fn.md +msgid "" +"“So we, as API designers, have two paths. We can either try to assume " +"responsibility for guarding against invalid inputs, or we can shift that " +"responsibility to the caller with the unsafe keyword.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-fn.md +msgid "" +"“The first path is a difficult one. We’re accepting a generic type T, which " +"is all possible types that implement Sized. That’s a lot of types!" +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-fn.md +msgid "“Therefore, the second path makes more sense." +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-fn.md +msgid "_Extra content (time permitting)_" +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-fn.md +msgid "" +"“By the way, if you’re interested in the details of pointers and what the " +"rules of converting them to references are, the standard library has a lot " +"of useful documentation. You should also look into the source code of many " +"of the methods on std::pointer." +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-fn.md +msgid "" +"“For example, the `ptr_to_ref` function on this slide actually exists in the " +"standard library as the `as_mut` method on pointers.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-fn.md +msgid "" +"Open the documentation for [std::pointer.as_mut](https://doc.rust-lang.org/" +"std/primitive.pointer.html#method.as_mut) and highlight the Safety section." +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-impl.md +msgid "" +"“Before we take a look at the code, we should double check that everyone " +"knows what a trait is. Is anyone able to explain traits for the rest of the " +"class?" +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-impl.md +msgid "" +"“Traits are often described as a way to create shared behavior. Thinking " +"about traits as shared behavior focuses on the syntax of methods and their " +"signatures." +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-impl.md +msgid "" +"“There’s also a deeper way to think of traits: as sets of requirements. This " +"emphasizes the shared semantics of the implementing types." +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-impl.md +msgid "“Can anyone explain what the `Send` and `Sync` traits are?" +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-impl.md +msgid "If no" +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-impl.md +msgid "" +"“Send and Sync relate to concurrency. There are many details, but broadly " +"speaking, Send types can be shared between threads by value. Sync types must " +"be shared by reference." +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-impl.md +msgid "" +"There are many rules to follow to ensure that it’s safe to share data across " +"thread boundaries. Those rules cannot be checked by the compiler, and " +"therefore the code author must take responsibility for upholding them." +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-impl.md +msgid "" +"Arc implements Send and Sync, therefore it’s safe for our clock to as well." +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-impl.md +msgid "" +"It may be useful to point out that the word _atomic_ has the meaning of " +"“indivisible” or “whole” from Ancient Greek, rather than the contemporary " +"English sense of “tiny particle”." +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-trait.md +msgid "/// Indicates that the type uses 32 bits of memory.\n" +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-trait.md +msgid "“Now let’s define our own unsafe trait.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-trait.md +msgid "Add the unsafe keyword and compile the code." +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-trait.md +msgid "" +"“If the requirements of the trait are semantic, then your trait may not need " +"any methods at all. The documentation is essential, however.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/warm-up/unsafe-trait.md +msgid "" +"“Traits without methods are called marker traits. When implementing them for " +"types, you are adding information to the type system. You have now given the " +"compiler the ability to talk about types that meet the requirements " +"described in the documentation.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust.md +msgid "Characteristics of unsafe" +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust.md +msgid "[Dangerous](characteristics-of-unsafe-rust/dangerous.md)" +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust.md +msgid "" +"[Sometimes necessary](characteristics-of-unsafe-rust/sometimes-necessary.md)" +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust.md +msgid "[Sometimes useful](characteristics-of-unsafe-rust/sometimes-useful.md)" +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/dangerous.md +msgid "Unsafe is dangerous" +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/dangerous.md +msgid "" +"“Use-after-free (UAF), integer overflows, and out of bounds (OOB) reads/" +"writes comprise 90% of vulnerabilities with OOB being the most common.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/dangerous.md +msgid "" +"\\--- **Jeff Vander Stoep and Chong Zang**, Google. \"[Queue the Hardening " +"Enhancements](https://security.googleblog.com/2019/05/queue-hardening-" +"enhancements.html)\"" +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/dangerous.md +msgid "" +"“The software industry has gathered lots of evidence that unsafe code is " +"difficult to write correctly and creates very serious problems.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/dangerous.md +msgid "" +"“The issues in this list are eliminated by Rust. The unsafe keyword lets " +"them back into your source code.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/dangerous.md +msgid "“Be careful.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/sometimes-necessary.md +msgid "Unsafe is sometimes necessary" +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/sometimes-necessary.md +msgid "" +"The Rust compiler can only enforce its rules for code that it has compiled." +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/sometimes-necessary.md +msgid "\"{pid}\"" +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/sometimes-necessary.md +msgid "“There are some activities that _require_ unsafe." +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/sometimes-necessary.md +msgid "" +"“The Rust compiler cannot verify that external functions comply with Rust's " +"memory guarantees. Therefore, invoking external functions requires an unsafe " +"block.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/sometimes-necessary.md +msgid "Optional:" +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/sometimes-necessary.md +msgid "" +"“Working with the external environment often involves sharing memory. The " +"interface that computers provide is a memory address (a pointer).”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/sometimes-necessary.md +msgid "" +"“Here's an example that asks the Linux kernel to write to memory that we " +"control:" +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/sometimes-necessary.md +msgid "\"{buf:?}\"" +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/sometimes-necessary.md +msgid "" +"“This FFI call reaches into the operating system to fill our buffer (`buf`). " +"As well as calling an external function, we must mark the boundary as " +"`unsafe` because the compiler cannot verify how the OS touches that memory.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/sometimes-useful.md +msgid "Unsafe is sometimes useful" +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/sometimes-useful.md +msgid "Your code can go faster!" +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/sometimes-useful.md +msgid "Code using `unsafe` _might_ be faster." +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/sometimes-useful.md +msgid "" +"`fast_sum()` skips bounds checks. However, benchmarking is necessary to " +"validate performance claims. For cases like this, Rust's iterators can " +"usually elide bounds checks anyway." +msgstr "" + +#: src/unsafe-deep-dive/introduction/characteristics-of-unsafe-rust/sometimes-useful.md +msgid "" +"Optional: [show identical generated assembly](https://rust.godbolt.org/z/" +"d48v1Y5aj) for the two functions." +msgstr "" + +#: src/unsafe-deep-dive/introduction/responsibility-shift.md +msgid "Unsafe keyword shifts responsibility" +msgstr "" + +#: src/unsafe-deep-dive/introduction/responsibility-shift.md +msgid "Is Memory Safe?" +msgstr "" + +#: src/unsafe-deep-dive/introduction/responsibility-shift.md +msgid "Responsibility for Memory Safety" +msgstr "" + +#: src/unsafe-deep-dive/introduction/responsibility-shift.md +msgid "Compiler" +msgstr "" + +#: src/unsafe-deep-dive/introduction/responsibility-shift.md +msgid "Programmer" +msgstr "" + +#: src/unsafe-deep-dive/introduction/responsibility-shift.md +msgid "Who has responsibility for memory safety?" +msgstr "" + +#: src/unsafe-deep-dive/introduction/responsibility-shift.md +msgid "Safe Rust → compiler" +msgstr "" + +#: src/unsafe-deep-dive/introduction/responsibility-shift.md +msgid "Unsafe Rust → programmer" +msgstr "" + +#: src/unsafe-deep-dive/introduction/responsibility-shift.md +msgid "" +"“While writing safe Rust, you cannot create memory safety problems. The " +"compiler will ensure that a program with mistakes will not build.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/responsibility-shift.md +msgid "" +"“The `unsafe` keyword shifts responsibility for maintaining memory safety " +"from the compiler to programmers. It signals that there are preconditions " +"that must be satisfied." +msgstr "" + +#: src/unsafe-deep-dive/introduction/responsibility-shift.md +msgid "" +"“To uphold that responsibility, programmers must ensure that they've " +"understood what the preconditions are and that their code will always " +"satisfy them." +msgstr "" + +#: src/unsafe-deep-dive/introduction/responsibility-shift.md +msgid "" +"“Throughout this course, we'll use the term _safety preconditions_ to " +"describe this situation.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/impact-on-workflow.md +msgid "Impact on workflow" +msgstr "" + +#: src/unsafe-deep-dive/introduction/impact-on-workflow.md +msgid "While writing code" +msgstr "" + +#: src/unsafe-deep-dive/introduction/impact-on-workflow.md +msgid "" +"Verify that you understand the preconditions of any `unsafe` functions/traits" +msgstr "" + +#: src/unsafe-deep-dive/introduction/impact-on-workflow.md +msgid "Check that the preconditions are satisfied" +msgstr "" + +#: src/unsafe-deep-dive/introduction/impact-on-workflow.md +msgid "Document your reasoning in safety comments" +msgstr "" + +#: src/unsafe-deep-dive/introduction/impact-on-workflow.md +msgid "Enhanced code review" +msgstr "" + +#: src/unsafe-deep-dive/introduction/impact-on-workflow.md +msgid "Self-review → peer reviewer → unsafe Rust expert (when needed)" +msgstr "" + +#: src/unsafe-deep-dive/introduction/impact-on-workflow.md +msgid "Escalate to a person who is comfortable with your code and reasoning" +msgstr "" + +#: src/unsafe-deep-dive/introduction/impact-on-workflow.md +msgid "" +"“The unsafe keyword places more responsibility on the programmer; therefore " +"it requires a stronger development workflow." +msgstr "" + +#: src/unsafe-deep-dive/introduction/impact-on-workflow.md +msgid "" +"“This class assumes a specific software development workflow where code " +"review is mandatory, and where the author and primary reviewer have access " +"to an unsafe Rust expert.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/impact-on-workflow.md +msgid "" +"“The author and primary reviewer will verify simple unsafe Rust code " +"themselves, and punt to an unsafe expert when necessary.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/impact-on-workflow.md +msgid "" +"“There are only a few unsafe Rust experts, and they are very busy, so we " +"need to optimally use their time.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/may_overflow.md +msgid "Example: may_overflow function" +msgstr "" + +#: src/unsafe-deep-dive/introduction/may_overflow.md +msgid "/// Adds 2^31 - 1 to negative numbers.\n" +msgstr "" + +#: src/unsafe-deep-dive/introduction/may_overflow.md +msgid "\"{x}\"" +msgstr "" + +#: src/unsafe-deep-dive/introduction/may_overflow.md +msgid "" +"“The `unsafe` keyword may have a subtly different meaning than what some " +"people assume.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/may_overflow.md +msgid "" +"“The code author believes that the code is correct. In principle, the code " +"is safe.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/may_overflow.md +msgid "" +"“In this toy example, the `may_overflow` function is only intended to be " +"called with negative numbers." +msgstr "" + +#: src/unsafe-deep-dive/introduction/may_overflow.md +msgid "" +"Ask learners if they can explain why `may_overflow` requires the unsafe " +"keyword." +msgstr "" + +#: src/unsafe-deep-dive/introduction/may_overflow.md +msgid "" +"“In case you’re unsure what the problem is, let’s pause briefly to explain. " +"An `i32` only has 31 bits available for positive numbers. When an operation " +"produces a result that requires more than 31 bits, then the program is put " +"into an invalid state. And it’s not just a numerical problem. Compilers " +"optimize code on the basis that invalid states are impossible. This causes " +"code paths to be deleted, producing erratic runtime behavior while also " +"introducing security vulnerabilities." +msgstr "" + +#: src/unsafe-deep-dive/introduction/may_overflow.md +msgid "" +"Compile and run the code, producing a panic. Then run the example in the " +"playground to run under `--release` mode to trigger UB." +msgstr "" + +#: src/unsafe-deep-dive/introduction/may_overflow.md +msgid "" +"“This code can be used correctly, however, improper usage is highly " +"dangerous.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/may_overflow.md +msgid "" +"“And it's impossible for the compiler to verify that the usage is correct.”" +msgstr "" + +#: src/unsafe-deep-dive/introduction/may_overflow.md +msgid "" +"This is what we mean when we say that the `unsafe` keyword marks the " +"location where responsibility for memory safety shifts from the compiler to " +"the programmer." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions.md +msgid "" +"Safety preconditions are conditions on an action that must be satisfied " +"before that action will be safe." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions.md +#: src/unsafe-deep-dive/safety-preconditions/getter.md +msgid "" +"“Safety preconditions are conditions on code that must be satisfied to " +"maintain Rust's safety guarantees" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions.md +#: src/unsafe-deep-dive/safety-preconditions/getter.md +msgid "" +"“You're likely to see a strong affinity between safety preconditions and the " +"rules of Safe Rust.”" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions.md +msgid "Q: Can you list any?" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions.md +msgid "(Fuller list in the next slide)" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +msgid "Common safety preconditions" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +msgid "Aliasing and Mutability" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +msgid "Alignment" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +msgid "Array access is in-bound" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +msgid "Pointer provenance" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +msgid "Validity" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +msgid "Memory" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +msgid "" +"Avoid spending too much time explaining every precondition: we will be " +"working through the details during the course. The intent is to show that " +"there are several." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +msgid "" +"\"An incomplete list, but these are a few of the major safety preconditions " +"to get us thinking.\"" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +msgid "" +"Validity. Values must be valid values of the type that they represent. " +"Rust's references may not be null. Creating one with `unsafe` causes the." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +msgid "Alignment. References to values must be well-aligned, which means th" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +msgid "" +"Aliasing. All Rust code must uphold Rust's borrowing rules. If you are " +"manually creating mutable references (`&mut T`) from pointers, then you may " +"only create one" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +msgid "" +"Initialization. All instances of Rust types must be fully initialized. To " +"create a value from raw memory, we need to make sure that we've written" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +msgid "" +"Pointer provenance. The origin of a pointer is important. Casting a `usize` " +"to a raw pointer is no longer allowed." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +msgid "Lifetimes. References must not outlive their referent." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +msgid "Some conditions are even more subtle than they first seem." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +msgid "" +"Consider \"in-bounds array access\". Reading from the memory location, i.e. " +"dereferencing, is not required to break the program. Creating an out-of-" +"bounds reference already breaks the compiler's assumptions, leading to " +"erratic behavior." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +msgid "" +"Rust tells LLVM to use its `getelementptr inbounds` assumption. That " +"assumption will cause later optimization passes within the compiler to " +"misbehave (because out-of-bounds memory access cannot occur)." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +msgid "" +"Optional: open [the playground](https://play.rust-lang.org/?" +"version=stable&mode=release&edition=2024&gist=4116c4de01c863cac918f193448210b1), " +"which shows the code below. Explain that this is essentially a C function " +"written in Rust syntax that gets items from an array. Generate the LLVM IR " +"with the **Show LLVM IR** button. Highlight `getelementptr inbounds i32, ptr " +"%array, i64 %offset`." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +msgid "Expected output (the line to highlight starts with \\`%\\_3):" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/common-preconditions.md +msgid "" +"Bounds: You correctly noted that creating an out-of-bounds pointer (beyond " +"the \"one-past-the-end\" rule) is UB, even without dereferencing, due to " +"LLVM's inbounds assumptions." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/getter.md +msgid "/// Return the element at `index` from `arr`\n" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/getter.md +msgid "Ask: “What are the safety preconditions of `get`?”" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/getter.md +msgid "" +"The pointer `arr` is non-null, well-aligned and refers to an array of `i32`" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/getter.md +msgid "`index` is in-bounds" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/getter.md +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "Add safety comments:" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/getter.md +msgid "" +"/// Return the element at `index` from `arr`\n" +"///\n" +"/// # Safety\n" +"///\n" +"/// - `arr` is non-null, correctly aligned and points to a valid `i32`\n" +"/// - `index` is in-bounds for the array\n" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/getter.md +msgid "// SAFETY: Caller guarantees that index is inbounds\n" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/getter.md +msgid "" +"Optional: Add runtime checks can be added in debug builds to provide some " +"extra robustness." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/determining.md +msgid "Determining Preconditions" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/determining.md +msgid "Where do you find the safety preconditions?" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/determining.md +msgid "" +"Attempt to compile the program to trigger the compiler error " +"(\"error\\[E0133\\]: call to unsafe function ...\")." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/determining.md +msgid "" +"Ask: “Where would you look if you wanted to know the preconditions for a " +"function? Here we need to understand when it's safe to convert from a null " +"pointer to a mutable reference.”" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/determining.md +msgid "Locations to look:" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/determining.md +msgid "A function's API documentation, especially its safety section" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/determining.md +msgid "The source code and its internal safety comments" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/determining.md +msgid "Module documentation" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/determining.md +msgid "Rust Reference" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/determining.md +msgid "" +"Consult [the documentation](https://doc.rust-lang.org/std/primitive.pointer." +"html#method.as_mut) for the `as_mut` method." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/determining.md +msgid "Highlight Safety section." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/determining.md +msgid "**Safety**" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/determining.md +msgid "" +"When calling this method, you have to ensure that either the pointer is null " +"or the pointer is convertible to a reference." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/determining.md +msgid "" +"Click the \"convertible to a reference\" hyperlink to the \"Pointer to " +"reference conversion\"" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/determining.md +msgid "" +"Track down the rules for converting a pointer to a reference, i.e., whether " +"it is \"dereferenceable\"." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/determining.md +msgid "" +"Consider the implications of this excerpt (Rust 1.90.0) \"You must enforce " +"Rust’s aliasing rules. The exact aliasing rules are not decided yet, ...\"" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "Example: References" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "Confirm understanding of the syntax" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "" +"`Box` type is a reference to an integer on the heap that is owned by " +"the box." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "" +"`*mut i32` type is a so-called raw pointer to an integer that the compiler " +"does not know the ownership of. Programmers need to ensure the rules are " +"enforced without assistance from the compiler." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "" +"Note: raw pointers do not provide ownership info to Rust. A pointer can be " +"semantically owning the data, or semantically borrowing, but that " +"information only exists in the programmer's mind." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "`&mut *boxed as *mut _` expression:" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "`*boxed` is ..." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "`&mut *boxed` is ..." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "finally, `as *mut i32` casts the reference to a pointer." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "" +"References, such as `&mut i32`, \"borrow\" their referent. This is Rust's " +"ownership system." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "Confirm understanding of ownership" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "Step through code:" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "" +"(Line 3) Creates raw pointer to the `123` by dereferencing the box, creating " +"a new reference and casting the new reference as a pointer." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "(Line 4) Creates raw pointer with a NULL value" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "(Line 7) Converts the raw pointer to an Option with `.as_mut()`" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "Highlight that pointers are nullable in Rust (unlike references)." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "Compile to reveal the error messages." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "Discuss" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "(Line 6) `println!(\"{:?}\", *a);`" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "Prefix star dereferences a raw pointer." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "" +"It is an explicit operation. Whereas regular references have implicit " +"dereferencing most of the time thanks to the Deref trait. This is referred " +"to as \"auto-deref\"." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "Dereferencing a raw pointer is an unsafe operation." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "Requires an unsafe block." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "(Line 7) `println!(\"{:?}\", b.as_mut());`" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "`as_mut()` is an unsafe function." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "Calling an unsafe function requires an unsafe block." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "" +"Demonstrate: Fix the code (add unsafe blocks) and compile again to show the " +"working program." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "" +"Demonstrate: Replace `as *mut i32` with `as *mut _`, show that it compiles." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "" +"We can partially omit the target type in the cast. The Rust compiler knows " +"that the source of the cast is a `&mut i32`. This reference type can only be " +"converted to one pointer type, `*mut i32`." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "" +"We said that the unsafe code marks the responsibility shift from the " +"compiler to the programmer." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "" +"How do we convey that we thought about our unusual responsibilities while " +"writing unsafe code? Safety comments." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "Safety comments explain why unsafe code is correct." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "Without a safety comment, unsafe code is not safe." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "Discuss: Whether to use one large unsafe block or two smaller ones:" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "Possibility of using a single unsafe block rather than multiple." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "Using more allows safety comments as specific as possible." +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "" +"// SAFETY: `a` is a non-null pointer to i32, it is initialized and still\n" +" // allocated.\n" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/references.md +msgid "" +"// SAFETY: `b` is a null pointer, which `as_mut()` converts to `None`.\n" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/defining.md +msgid "User-defined types are entitled to have their own safety preconditions" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/defining.md +msgid "" +"Include documentation so that they can later be determined and satisfied" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/ascii.md +msgid "/// Text that is guaranteed to be encoded within 7-bit ASCII.\n" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/ascii.md +msgid "" +"/// Creates a new `Ascii` from a byte slice without checking for ASCII\n" +" /// validity.\n" +" ///\n" +" /// # Safety\n" +" ///\n" +" /// Providing non-ASCII bytes results in undefined behavior.\n" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/ascii.md +msgid "" +"\"The `Ascii` type is a minimal wrapper around a byte slice. Internally, " +"they share the same representation. However, `Ascii` requires that the high " +"bit must not be used.\"" +msgstr "" + +#: src/unsafe-deep-dive/safety-preconditions/ascii.md +msgid "" +"Optional: Extend the example to mention that it's possible to use " +"`debug_assert!` to test the preconditions during tests without impacting " +"release builds." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game.md +msgid "" +"“We've seen many examples of code that has problems in the class, but we " +"lack consistent terminology." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game.md +msgid "" +"“The goal of the next section is to introduce some terms that describe many " +"of the concepts that we have been thinking about." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game.md +msgid "undefined behavior" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game.md +msgid "sound" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game.md +msgid "unsound" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game.md +msgid "" +"“Given that many safety preconditions are semantic rather than syntactic, " +"it's important to use a shared vocabulary. That way we can agree on " +"semantics." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game.md +msgid "" +"“The overarching goal is to develop a mental framework of what soundness is " +"and ensure that Rust code that contains unsafe remains sound.”" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/rust-is-sound.md +msgid "Soundness is fundamental to Rust" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/rust-is-sound.md +msgid "Soundness ≈ impossible to cause memory safety problems" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/rust-is-sound.md +msgid "Sound functions have common “shapes”" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/rust-is-sound.md +msgid "“A fundamental principle of Rust code is that it is sound." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/rust-is-sound.md +msgid "" +"“We’ll create a formal definition of the term soundness shortly. In the " +"meantime, think of sound code as code that cannot trigger memory safety " +"problems." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/rust-is-sound.md +msgid "“Sound code is made up of _sound functions_ and _sound operations_." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/rust-is-sound.md +msgid "" +"“A sound function is a function where none of its possible inputs could " +"provoke soundness problems." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/rust-is-sound.md +msgid "Sound functions have common shapes." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/rust-is-sound.md +msgid "Those shapes are what we’ll look at now." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/rust-is-sound.md +msgid "" +"“We’ll start with one that’s implemented in Safe Rust, and then see what " +"could happen when we introduce `unsafe` to different parts." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory.md +msgid "Copying memory - Introduction" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory.md +msgid "/// Reads bytes from `source` and writes them to `dest`\n" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory.md +msgid "“Here is our initial function prototype.”" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory.md +msgid "" +"“`copy` accepts two slices as arguments. `dest` (destination) is mutable, " +"whereas `source` is not.”" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory.md +msgid "“Let's see the shapes of sound Rust code.”" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/safe.md +msgid "“The implementation only uses safe Rust." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/safe.md +msgid "What can we learn from this?" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/safe.md +msgid "" +"“It is impossible for `copy` to trigger memory safety issues when " +"implemented in Safe Rust. This is true for all possible input arguments.”" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/safe.md +msgid "" +"“For example, by using Rust’s iterators, we can ensure that we’ll never " +"trigger errors relating to handling pointers directly, such as needing null " +"pointer or bounds checks.”" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/safe.md +msgid "Ask: “Can you think of any others?”" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/safe.md +msgid "No aliasing issues" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/safe.md +msgid "Dangling pointers are impossible" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/safe.md +msgid "Alignment will be correct" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/safe.md +msgid "Cannot accidentally read from uninitialized memory" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/safe.md +msgid "" +"“We can say that the `copy` function is _sound_ because Rust ensures that " +"all of the safety preconditions are satisfied.”" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/safe.md +msgid "" +"“From the point of view of the programmer, as this function is implemented " +"in safe Rust, we can think of it as having no safety preconditions.”" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/safe.md +msgid "" +"“This does not mean that `copy` will always do what the caller might want. " +"If there is insufficient space available in the `dest` slice, then data will " +"not be copied across.”" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/encapsulated-unsafe.md +msgid "// SAFETY: `i` must be in-bounds as it was produced by source.len()\n" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/encapsulated-unsafe.md +msgid "// SAFETY: `i` must be in-bounds as it was produced by dest.len()\n" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/encapsulated-unsafe.md +msgid "" +"“Here we have a safe function that encapsulates unsafe blocks that are used " +"internally." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/encapsulated-unsafe.md +msgid "" +"“This implementation avoids iterators. Instead, the implementor is accessing " +"memory manually.”" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/encapsulated-unsafe.md +msgid "“Is this correct?” “Are there any problems?”" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/encapsulated-unsafe.md +msgid "" +"“Who has responsibility for ensuring that correctness? The author of the " +"function." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/encapsulated-unsafe.md +msgid "" +"“A Safe Rust function that contains unsafe blocks remains sound if it’s " +"impossible for an input to cause memory safety issues." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +msgid "" +"The functionality of copying bytes from one place to the next remains the " +"same." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +msgid "" +"“However, we need to manually create a slice. To do that, we first need to " +"find the end of the data." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +msgid "" +"“As we’re working with text, we’ll use the C convention of a null-terminated " +"string." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +msgid "Compile the code. See that the output remains the same." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +msgid "" +"“An unsound function can still work correctly for some inputs. Just because " +"your tests pass, does not mean that you have a sound function.”" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +msgid "“Can anyone spot any issues?”" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +msgid "Readability: difficult to quickly scan code" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +msgid "`source` pointer might be null" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +msgid "" +"`source` pointer might be dangling, i.e. point to freed or uninitialized " +"memory" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +msgid "`source` might not be null-terminated" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +msgid "" +"“Assume that we cannot change the function signature, what improvements " +"could we make to the code to address these issues?”" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +msgid "" +"Null pointer: Add null check with early return (`if source.is_null() " +"{ return; }`)" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +msgid "" +"Readability: Use a well-tested library rather than implementing “find first " +"null byte” ourselves" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +msgid "" +"“Some safety requirements are impossible to defensively check for, however, " +"i.e.:”" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +msgid "dangling pointer" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +msgid "no null termination byte" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +msgid "“How can we make this function sound?”" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +msgid "Either" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +msgid "" +"Change the type of the `source` input argument to something that has a known " +"length, i.e. use a slice like the previous example." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +msgid "Or" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +msgid "Mark the function as unsafe" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/exposed-unsafe.md +msgid "Document the safety preconditions" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/documented-safety-preconditions.md +msgid "" +"/// ...\n" +"///\n" +"/// # Safety\n" +"///\n" +"/// This function can easily trigger undefined behavior. Ensure that:\n" +"///\n" +"/// - `source` pointer is non-null and non-dangling\n" +"/// - `source` data ends with a null byte within its memory allocation\n" +"/// - `source` data is not freed (its lifetime invariants are preserved)\n" +"/// - `source` data contains fewer than `isize::MAX` bytes\n" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/documented-safety-preconditions.md +msgid "// SAFETY: Caller has provided a non-null pointer\n" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/documented-safety-preconditions.md +msgid "// SAFETY: Caller has provided a data with length < isize:MAX\n" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/documented-safety-preconditions.md +msgid "// SAFETY: Caller maintains lifetime and aliasing requirements\n" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/documented-safety-preconditions.md +msgid "Changes to previous iterations:" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/documented-safety-preconditions.md +msgid "`copy` marked as unsafe" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/documented-safety-preconditions.md +msgid "Safety preconditions are documented" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/documented-safety-preconditions.md +msgid "inline safety comments" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/documented-safety-preconditions.md +msgid "" +"An unsafe function is sound when both its safety preconditions and its " +"internal unsafe blocks are documented." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/documented-safety-preconditions.md +msgid "Fixes needed in `main`." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/documented-safety-preconditions.md +msgid "" +"`a` does not satisfy one of the preconditions of `copy` (source\\` data ends " +"with a null byte within its memory allocation)" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/documented-safety-preconditions.md +msgid "SAFETY comment needed" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/crying-wolf.md +msgid "“It is also possible to create so-called crying wolf functions." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/copying-memory/crying-wolf.md +msgid "" +"“These are functions which are tagged as unsafe, but which have no safety " +"preconditions that programmers need to check." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/3-shapes-of-sound-rust.md +msgid "3 Shapes of Sound Rust" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/3-shapes-of-sound-rust.md +msgid "Functions written only in Safe Rust" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/3-shapes-of-sound-rust.md +msgid "Functions that contain `unsafe` blocks which are impossible to misuse" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/3-shapes-of-sound-rust.md +msgid "Unsafe functions that have their safety preconditions documented" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/3-shapes-of-sound-rust.md +msgid "We want to write sound code." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/3-shapes-of-sound-rust.md +msgid "Sound code can only have the following shapes:" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/3-shapes-of-sound-rust.md +msgid "safe functions that contain no unsafe blocks" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/3-shapes-of-sound-rust.md +msgid "" +"safe functions that completely encapsulate unsafe blocks, meaning that the " +"caller does not need to know about them" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/3-shapes-of-sound-rust.md +msgid "" +"unsafe functions that contain unsafe blocks but don't encapsulate them, and " +"pass the proof burden to their caller" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/3-shapes-of-sound-rust.md +msgid "Burden of proof" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/3-shapes-of-sound-rust.md +msgid "safe functions with only Safe Rust -> compiler" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/3-shapes-of-sound-rust.md +msgid "safe functions with unsafe blocks -> function author" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/3-shapes-of-sound-rust.md +msgid "unsafe functions -> function caller" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/soundness-proof/soundness.md +#: src/unsafe-deep-dive/rules-of-the-game/soundness-proof/corollary.md +#: src/unsafe-deep-dive/rules-of-the-game/soundness-proof/unsoundness.md +msgid "" +"A sound function is one that can't trigger UB if its safety preconditions " +"are satisfied." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/soundness-proof/soundness.md +msgid "Read the definition of sound functions." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/soundness-proof/soundness.md +msgid "" +"Remind the students that the programmer who implements the caller is " +"responsible for satisfying the safety precondition; the compiler is not " +"helping." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/soundness-proof/soundness.md +msgid "" +"Translate into informal terms. Soundness means that the function is nice and " +"plays by the rules. It documents its safety preconditions, and when the " +"caller satisfies them, the function behaves well (no UB)." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/soundness-proof/corollary.md +msgid "Soundness Proof (Part 2)" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/soundness-proof/corollary.md +msgid "Corollary: All functions implemented in pure safe Rust are sound." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/soundness-proof/corollary.md +msgid "Proof:" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/soundness-proof/corollary.md +msgid "Safe Rust code has no safety preconditions." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/soundness-proof/corollary.md +msgid "" +"Therefore, callers of functions implemented in pure safe Rust always " +"trivially satisfy the empty set of preconditions." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/soundness-proof/corollary.md +msgid "Safe Rust code can't trigger UB." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/soundness-proof/corollary.md +msgid "QED." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/soundness-proof/corollary.md +msgid "Read the corollary." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/soundness-proof/corollary.md +msgid "Explain the proof." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/soundness-proof/corollary.md +msgid "" +"Translate into informal terms: all safe Rust code is nice. It does not have " +"safety preconditions that the programmer has to think of, always plays by " +"the rules, and never triggers UB." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/soundness-proof/unsoundness.md +msgid "" +"An unsound function can trigger UB even if you satisfy the documented safety " +"preconditions." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/soundness-proof/unsoundness.md +msgid "Unsound code is _bad_." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/soundness-proof/unsoundness.md +msgid "Read the definition of unsound functions." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/soundness-proof/unsoundness.md +msgid "" +"Translate into informal terms: unsound code is not nice. No, that's an " +"understatement. Unsound code is BAD. Even if you play by the documented " +"rules, unsound code can still trigger UB!" +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/soundness-proof/unsoundness.md +msgid "We don't want any unsound code in our repositories." +msgstr "" + +#: src/unsafe-deep-dive/rules-of-the-game/soundness-proof/unsoundness.md +msgid "Finding unsound code is the **primary** goal of the code review." +msgstr "" + +#: src/unsafe-deep-dive/memory-lifecycle.md +msgid "" +"Memory moves through different phases as objects (values) are created and " +"destroyed." +msgstr "" + +#: src/unsafe-deep-dive/memory-lifecycle.md +msgid "Memory State" +msgstr "" + +#: src/unsafe-deep-dive/memory-lifecycle.md +msgid "Readable from Safe Rust?" +msgstr "" + +#: src/unsafe-deep-dive/memory-lifecycle.md +msgid "Available" +msgstr "" + +#: src/unsafe-deep-dive/memory-lifecycle.md +msgid "Allocated" +msgstr "" + +#: src/unsafe-deep-dive/memory-lifecycle.md +msgid "Initialized" +msgstr "" + +#: src/unsafe-deep-dive/memory-lifecycle.md +msgid "" +"This section discusses what happens as memory from the operating system " +"becomes a valid variable in the program." +msgstr "" + +#: src/unsafe-deep-dive/memory-lifecycle.md +msgid "" +"When memory is available, the operating system has provided our program with " +"it." +msgstr "" + +#: src/unsafe-deep-dive/memory-lifecycle.md +msgid "" +"When memory is allocated, it is reserved for values to be written to it. We " +"call this uninitialized memory." +msgstr "" + +#: src/unsafe-deep-dive/memory-lifecycle.md +msgid "When memory is initialized, it is safe to read from." +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit.md +msgid "`MaybeUninit` allows Rust to refer to uninitialized memory." +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit.md +msgid "\"{uninit:?}\"" +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit.md +msgid "“Safe Rust is unable to refer to data that’s potentially uninitialized”" +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit.md +msgid "“Yet, all data arrives at the program as uninitialized.”" +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit.md +msgid "" +"“Therefore, we need some bridge in the type system to allow memory to " +"transition. `MaybeUninit` is that type.”" +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit.md +msgid "" +"“`MaybeUninit` is very similar to the `Option` type, although its " +"semantics are very different. The equivalent of `Option::None` for " +"`MaybeUninit` is uninitialized memory, which is only safe to write to.”" +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit.md +msgid "“Reading from memory that may be uninitialized is extremely dangerous.”" +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/arrays.md +msgid "MaybeUninit and arrays" +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/arrays.md +msgid "b\"RUST\"" +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/arrays.md +msgid "// Initialize elements by writing values to the memory\n" +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/arrays.md +msgid "" +"// When a portion of an array is initialized, one can\n" +" // use unsafe to isolate it\n" +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/arrays.md +#: src/unsafe-deep-dive/initialization/partial-initialization.md +msgid "\"{text}\"" +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/arrays.md +msgid "// We must manually drop the initialized elements\n" +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/arrays.md +msgid "" +"To create an array of uninitialized memory, the `::uninit()` constructor can " +"be used within a `const` context." +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/arrays.md +msgid "Use `ptr::write` to initialize values as per normal." +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/arrays.md +msgid "" +"`.assume_init()` does not work as easily for arrays. It requires every value " +"to be initialized, which may not occur when reusing a buffer. This example " +"uses a pointer to isolate the initialized bytes to create a string slice." +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/arrays.md +msgid "" +"When creating a sub-slice of a partially-initialized array, be careful with " +"ownership and correctly implementing drop. Reminder: `MaybeUninit` will " +"not call drop on its `T`." +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/arrays.md +msgid "" +"`MaybeUninit<[u8;2048]>` is distinct from `[MaybeUninit::; 2048]`. This " +"is the difference between an array of uninitialized memory and an array that " +"contains uninitialized elements." +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/arrays.md +msgid "" +"`MaybeUninit<[u8;2048]>` is \"all or nothing\". You either fully initialize " +"the whole array and then call `assume_init`, or you must keep it as " +"`MaybeUninit<[u8; 2048]>` and avoid touching it as `[u8; 2048]`." +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/arrays.md +msgid "" +"`[MaybeUninit; 2048]` lets you initialize elements one at a time, then " +"take a sub-slice of just the initialized prefix and treat it as `[u8]` via " +"`std::slice::from_raw_parts`." +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/arrays.md +msgid "" +"`slice_assume_init_ref` is safe only when every element in the slice is " +"initialized. For this example, we only pass `&buf[..input.len()]` after " +"writing exactly those bytes." +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/arrays.md +msgid "" +"When `T` needs drop, you must manually call `assume_init_drop()` for the " +"initialized elements. Skipping this leaks memory. However, calling it on an " +"uninitialized element is undefined behavior." +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/zeroed-method.md +msgid "// SAFETY: All values of `x` have been written to\n" +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/zeroed-method.md +#: src/unsafe-deep-dive/pinning/what-a-move-is.md +msgid "\"{x:?}\"" +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/zeroed-method.md +msgid "" +"“MaybeUninit::zeroed() is an alternative constructor to MaybeUninit::" +"uninit(). It instructs the compiler to fill the bits of T with zeros.”" +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/zeroed-method.md +msgid "" +"Q: “Although the memory has been written to, the type remains " +"`MaybeUninit`. Can anyone think of why?”" +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/zeroed-method.md +msgid "" +"A: Some types require their values to be non-zero or non-null. The classic " +"case is references, but this applies to many other types as well. Consider " +"the `NonZeroUsize` integer type and others in its family." +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/write-vs-assignment.md +msgid "MaybeUninit.write() vs assignment" +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/write-vs-assignment.md +msgid "// Initialize\n" +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/write-vs-assignment.md +msgid "// Overwrite\n" +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/write-vs-assignment.md +msgid "\"Hi again\"" +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/write-vs-assignment.md +msgid "// Assignment replaces the whole MaybeUninit value.\n" +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/write-vs-assignment.md +msgid "\"Goodbye\"" +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/write-vs-assignment.md +msgid "// Ensure inner value is dropped\n" +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/write-vs-assignment.md +msgid "" +"Replacing inner values can cause memory leaks because the drop semantics " +"differ from most types. `MaybeUninit` does not call the destructor on its " +"`T`." +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/write-vs-assignment.md +msgid "" +"`MaybeUninit::write()` uses `ptr::write`: it initializes the memory in place " +"without reading or dropping the old contents. That is exactly what you want " +"when the memory might be uninitialized, but it also means you will leak if " +"there was already a live value there." +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/write-vs-assignment.md +msgid "" +"Assignment, e.g. `buf = MaybeUninit::new(value)`, replaces the whole " +"`MaybeUninit`. The old `MaybeUninit` is moved and then dropped, but " +"`MaybeUninit` has no destructor for `T`, so the inner value is not dropped. " +"If the old slot held an initialized value, it is leaked just like with " +"`write()`." +msgstr "" + +#: src/unsafe-deep-dive/initialization/maybeuninit/write-vs-assignment.md +msgid "" +"If you need normal drop behavior, you need to tell Rust that the value is " +"initialized with `assume_init` or one of the related methods." +msgstr "" + +#: src/unsafe-deep-dive/initialization/how-to-initialize-memory.md +msgid "How to Initialize Memory" +msgstr "" + +#: src/unsafe-deep-dive/initialization/how-to-initialize-memory.md +msgid "Steps:" +msgstr "" + +#: src/unsafe-deep-dive/initialization/how-to-initialize-memory.md +msgid "Create `MaybeUninit`" +msgstr "" + +#: src/unsafe-deep-dive/initialization/how-to-initialize-memory.md +msgid "Write a value to it" +msgstr "" + +#: src/unsafe-deep-dive/initialization/how-to-initialize-memory.md +msgid "Notify Rust that the memory is initialized" +msgstr "" + +#: src/unsafe-deep-dive/initialization/how-to-initialize-memory.md +msgid "// Step 1: Create MaybeUninit\n" +msgstr "" + +#: src/unsafe-deep-dive/initialization/how-to-initialize-memory.md +msgid "// Step 2: Write a valid value to the memory\n" +msgstr "" + +#: src/unsafe-deep-dive/initialization/how-to-initialize-memory.md +msgid "// Step 3: Inform the type system that the memory location is valid\n" +msgstr "" + +#: src/unsafe-deep-dive/initialization/how-to-initialize-memory.md +msgid "\"{init}\"" +msgstr "" + +#: src/unsafe-deep-dive/initialization/how-to-initialize-memory.md +msgid "" +"To work with uninitialized memory, follow this general workflow: create, " +"write, confirm." +msgstr "" + +#: src/unsafe-deep-dive/initialization/how-to-initialize-memory.md +msgid "" +"Create `MaybeUninit`. The `::uninit()` constructor is the most general-" +"purpose one, but there are others which perform a write as well." +msgstr "" + +#: src/unsafe-deep-dive/initialization/how-to-initialize-memory.md +msgid "" +"Write a value of T. Notice that this is available from safe Rust. Staying in " +"safe Rust is useful because you must ensure that the value you write is " +"valid." +msgstr "" + +#: src/unsafe-deep-dive/initialization/how-to-initialize-memory.md +msgid "" +"Confirm to the type system that the memory is now initialized with the `." +"assume_init()` method." +msgstr "" + +#: src/unsafe-deep-dive/initialization/partial-initialization.md +msgid "Partial Initialization" +msgstr "" + +#: src/unsafe-deep-dive/initialization/partial-initialization.md +msgid "// let mut buf = [0u8; 2048];\n" +msgstr "" + +#: src/unsafe-deep-dive/initialization/partial-initialization.md +msgid "b\"Hello, Rust!\"" +msgstr "" + +#: src/unsafe-deep-dive/initialization/partial-initialization.md +msgid "" +"// SAFETY: We initialized exactly 'len' bytes of `buf` with UTF-8 text\n" +msgstr "" + +#: src/unsafe-deep-dive/initialization/partial-initialization.md +msgid "This code simulates receiving data from some external source." +msgstr "" + +#: src/unsafe-deep-dive/initialization/partial-initialization.md +msgid "" +"When reading bytes from an external source into a buffer, you typically " +"don't know how many bytes you'll receive. Using `MaybeUninit` lets you " +"allocate the buffer once without paying for a redundant initialization pass." +msgstr "" + +#: src/unsafe-deep-dive/initialization/partial-initialization.md +msgid "" +"If we were to create the array with the standard syntax (`buf = [0u8; " +"2048]`), the whole buffer would be flushed with zeroes. `MaybeUninit` " +"tells the compiler to reserve space, but not to touch the memory yet." +msgstr "" + +#: src/unsafe-deep-dive/initialization/partial-initialization.md +msgid "" +"Q: Which part of the code snippet is performing a similar role to `." +"assume_init()`? A: The pointer cast and the implicit read." +msgstr "" + +#: src/unsafe-deep-dive/initialization/partial-initialization.md +msgid "" +"We cannot call `assume_init()` on the whole array. That would be unsound " +"because most elements remain uninitialized. Instead, we cast the pointer " +"from `*const MaybeUninit` to `*const u8` and build a slice covering only " +"the initialised portion." +msgstr "" + +#: src/unsafe-deep-dive/pinning.md +msgid "This segment of the course covers:" +msgstr "" + +#: src/unsafe-deep-dive/pinning.md +msgid "What \"pinning\" is" +msgstr "" + +#: src/unsafe-deep-dive/pinning.md +msgid "Why it is necessary" +msgstr "" + +#: src/unsafe-deep-dive/pinning.md +msgid "How Rust implements it" +msgstr "" + +#: src/unsafe-deep-dive/pinning.md +msgid "How it interacts with unsafe and FFI" +msgstr "" + +#: src/unsafe-deep-dive/pinning.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer.md +msgid "This segment should take about 1 hour and 20 minutes. It contains:" +msgstr "" + +#: src/unsafe-deep-dive/pinning.md +#: src/unsafe-deep-dive/pinning/definition-of-pin.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer.md +msgid "Definition of Pin" +msgstr "" + +#: src/unsafe-deep-dive/pinning.md +#: src/unsafe-deep-dive/pinning/phantompinned.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer.md +msgid "PhantomPinned" +msgstr "" + +#: src/unsafe-deep-dive/pinning.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer.md +msgid "Pin and Drop" +msgstr "" + +#: src/unsafe-deep-dive/pinning.md +msgid "" +"\"Pinning, or holding a value's memory address in a fixed location,is one of " +"the more challenging concepts in Rust.\"" +msgstr "" + +#: src/unsafe-deep-dive/pinning.md +msgid "" +"\"Normally only seen within async code, i.e. [`poll(self: Pin<&mut Self>)`]" +"(https://doc.rust-lang.org/std/future/trait.Future.html#tymethod.poll), " +"pinning has wider applicability.\"" +msgstr "" + +#: src/unsafe-deep-dive/pinning.md +msgid "" +"Some data structures that are difficult or impossible to write without the " +"unsafe keyword, including self-referential structs and intrusive data " +"structures." +msgstr "" + +#: src/unsafe-deep-dive/pinning.md +msgid "" +"FFI with C++ is a prominent use case that's related to this. Rust must " +"assume that any C++ with a reference might be a self-referential data " +"structure." +msgstr "" + +#: src/unsafe-deep-dive/pinning.md +msgid "" +"\"To understand this conflict in more detail, we'll first need to make sure " +"that we have a strong understanding of Rust's move semantics.\"" +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-pinning-is.md +msgid "A pinned type cannot change its memory address (move)" +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-pinning-is.md +msgid "The pointed-to value cannot be moved by safe code" +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-pinning-is.md +msgid "" +"`Pin` makes use of the ownership system to control how the pinned value " +"is accessed. Rather than changing the language, Rust's ownership system is " +"used to enforce pinning. `Pin` owns its contents and nothing in its safe API " +"triggers a move." +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-pinning-is.md +msgid "This is explained in" +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-pinning-is.md +msgid "Conceptually, pinning prevents the default movement behavior." +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-pinning-is.md +msgid "This appears to be a change in the language itself." +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-pinning-is.md +msgid "" +"However, the `Pin` wrapper doesn't actually change anything fundamental " +"about the language." +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-pinning-is.md +msgid "" +"`Pin` doesn't expose safe APIs that would allow a move. Thus, it can prevent " +"bitwise copy." +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-pinning-is.md +msgid "" +"Unsafe APIs allow library authors to wrap types that do not implement " +"`Unpin`, but they must uphold the same guarantees." +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-pinning-is.md +msgid "The documentation of `Pin` uses the term \"pointer types\"." +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-pinning-is.md +msgid "" +"The term \"pointer type\" is much more broad than the pointer primitive type " +"in the language." +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-pinning-is.md +msgid "" +"A \"pointer type\" wraps every type that implements `Deref` with a target " +"that implements `Unpin`." +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-pinning-is.md +msgid "" +"Rust style note: This trait bound is enforced through trait bounds on the `::" +"new()` constructor, rather than on the type itself." +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-a-move-is.md +msgid "What a move is in Rust" +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-a-move-is.md +msgid "Always a bitwise copy, even for types that do not implement `Copy`:" +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-a-move-is.md +msgid "b'R'" +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-a-move-is.md +msgid "b'U'" +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-a-move-is.md +msgid "b'S'" +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-a-move-is.md +msgid "b'T'" +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-a-move-is.md +msgid "" +"Generated [LLVM IR](https://play.rust-lang.org/?" +"version=stable&mode=debug&edition=2024&gist=6f587283e8e0ec02f1ea8e871fc9ac72) " +"for calling `move_and_expect()`:" +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-a-move-is.md +msgid "`memcpy` from variable `%b` to `%_12`" +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-a-move-is.md +msgid "Call to `move_and_inspect` with `%_12` (the copy)" +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-a-move-is.md +msgid "Note that `DynamicBuffer` does not implement `Copy`." +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-a-move-is.md +msgid "Implication: a value's memory address is not stable." +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-a-move-is.md +msgid "" +"To show movement as a bitwise copy, either [open the code in the playground]" +"(https://play.rust-lang.org/?" +"version=stable&mode=debug&edition=2024&gist=6f587283e8e0ec02f1ea8e871fc9ac72) " +"and look at the or [the Compiler Explorer](https://rust.godbolt.org/" +"z/6o6nP7do4)." +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-a-move-is.md +msgid "Optional for those who prefer assembly output:" +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-a-move-is.md +msgid "" +"The Compiler Explorer is useful for discussing the generated assembly and " +"focus the cursor assembly output in the `main` function on lines 128-136 " +"(should be highlighted in pink)." +msgstr "" + +#: src/unsafe-deep-dive/pinning/what-a-move-is.md +msgid "Relevant code generated output `move_and_inspect`:" +msgstr "" + +#: src/unsafe-deep-dive/pinning/definition-of-pin.md +msgid "" +"`Pin` is a minimal wrapper around a _pointer type_, which is defined as a " +"type that implements `Deref`." +msgstr "" + +#: src/unsafe-deep-dive/pinning/definition-of-pin.md +msgid "" +"However, `Pin::new()` only accepts types that dereference into a target that " +"implements `Unpin` (`Deref`). This allows `Pin` to rely on " +"the type system to enforce its guarantees." +msgstr "" + +#: src/unsafe-deep-dive/pinning/definition-of-pin.md +msgid "" +"Types that do not implement `Unpin`, i.e., types that require pinning, must " +"create a `Pin` via the unsafe `Pin::new_unchecked()`." +msgstr "" + +#: src/unsafe-deep-dive/pinning/definition-of-pin.md +msgid "" +"Aside: Unlike other `new()`/`new_unchecked()` method pairs, `new` does not " +"do any runtime checking. The check is a zero-cost compile-time check." +msgstr "" + +#: src/unsafe-deep-dive/pinning/why-difficult.md +msgid "Why Pin is difficult to use" +msgstr "" + +#: src/unsafe-deep-dive/pinning/why-difficult.md +msgid "`Pin` is \"just\" a type defined in the standard library" +msgstr "" + +#: src/unsafe-deep-dive/pinning/why-difficult.md +msgid "" +"This satisfied the needs of its original audience, the creators of async " +"runtimes, without needing to extending the core language" +msgstr "" + +#: src/unsafe-deep-dive/pinning/why-difficult.md +msgid "" +"That audience could accept some of its ergonomic downsides, as users of " +"`async` would rarely interact with `Pin` directly" +msgstr "" + +#: src/unsafe-deep-dive/pinning/why-difficult.md +msgid "" +"\"You might wonder why Pin is so awkward to use. The answer is largely " +"historical.\"" +msgstr "" + +#: src/unsafe-deep-dive/pinning/why-difficult.md +msgid "" +"\"`Pin` offered a simpler implementation for the Rust project than " +"alternatives\"." +msgstr "" + +#: src/unsafe-deep-dive/pinning/why-difficult.md +msgid "" +"\"Pin was designed primarily for the ~100 people in the world who write " +"async runtimes. The Rust team chose a simpler (for the compiler) but less " +"ergonomic design.\"" +msgstr "" + +#: src/unsafe-deep-dive/pinning/why-difficult.md +msgid "" +"\"More user-friendly proposals existed but were rejected as too complex for " +"the primary audience, who could handle the complexity.\"" +msgstr "" + +#: src/unsafe-deep-dive/pinning/unpin-trait.md +msgid "Unpin trait" +msgstr "" + +#: src/unsafe-deep-dive/pinning/unpin-trait.md +msgid "" +"`Unpin` type allows types to move freely, even when they're wrapped by a " +"`Pin`" +msgstr "" + +#: src/unsafe-deep-dive/pinning/unpin-trait.md +msgid "Most types implement `Unpin`, because it is an \"`auto trait`\"" +msgstr "" + +#: src/unsafe-deep-dive/pinning/unpin-trait.md +msgid "`auto trait` behavior can be changed:" +msgstr "" + +#: src/unsafe-deep-dive/pinning/unpin-trait.md +msgid "`!Unpin` types must never move" +msgstr "" + +#: src/unsafe-deep-dive/pinning/unpin-trait.md +msgid "" +"Types containing a `PhantomPinned` field do not implement `Unpin` by default" +msgstr "" + +#: src/unsafe-deep-dive/pinning/unpin-trait.md +msgid "" +"Explain that when a trait implements `Unpin`, the pinning behavior of " +"`Pin` does not get invoked. The value is free to move." +msgstr "" + +#: src/unsafe-deep-dive/pinning/unpin-trait.md +msgid "" +"Explain that almost all types implement `Unpin`; automatically implemented " +"by the compiler." +msgstr "" + +#: src/unsafe-deep-dive/pinning/unpin-trait.md +msgid "" +"Types implementing `Unpin` are saying: 'I promise I have no self-references, " +"so moving me is always safe.'" +msgstr "" + +#: src/unsafe-deep-dive/pinning/unpin-trait.md +msgid "Ask: What types might be `!Unpin`?" +msgstr "" + +#: src/unsafe-deep-dive/pinning/unpin-trait.md +msgid "Compiler-generated futures" +msgstr "" + +#: src/unsafe-deep-dive/pinning/unpin-trait.md +msgid "Types containing a `PhantomPinned` field" +msgstr "" + +#: src/unsafe-deep-dive/pinning/unpin-trait.md +msgid "Some types wrapping C++ objects" +msgstr "" + +#: src/unsafe-deep-dive/pinning/unpin-trait.md +msgid "`!Unpin` types cannot be moved once pinned" +msgstr "" + +#: src/unsafe-deep-dive/pinning/phantompinned.md +msgid "Definition" +msgstr "" + +#: src/unsafe-deep-dive/pinning/phantompinned.md +msgid "Usage" +msgstr "" + +#: src/unsafe-deep-dive/pinning/phantompinned.md +msgid "`PhantomPinned` is a marker type." +msgstr "" + +#: src/unsafe-deep-dive/pinning/phantompinned.md +msgid "" +"If a type contains a `PhantomPinned`, it will not implement `Unpin` by " +"default." +msgstr "" + +#: src/unsafe-deep-dive/pinning/phantompinned.md +msgid "" +"This has the effect of enforcing pinning when `DynamicBuffer` is wrapped by " +"`Pin`." +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer.md +msgid "" +"A \"self-referential buffer\" is a type that has a reference to one of its " +"own fields:" +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer.md +msgid "" +"This kind of structure is not typical in Rust, because there's no way to " +"update the cursor's address when instances of `SelfReferentialBuffer` move." +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer.md +msgid "" +"However, this kind of setup is more natural in other languages that provide " +"garbage collection, and also C++ that allows users to define their own " +"behavior during moves and copies." +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/cpp.md +msgid "Modelled in C++" +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/cpp.md +msgid "" +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/cpp.md +msgid "" +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/cpp.md +msgid "Investigate on [Compiler Explorer](https://godbolt.org/z/ascME6aje)" +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/cpp.md +msgid "" +"The `SelfReferentialBuffer` contains two members, `data` is a kilobyte of " +"memory and `cursor` is a pointer into the former." +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/cpp.md +msgid "" +"Its move constructor ensures that cursor is updated to the new memory " +"address." +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/cpp.md +msgid "This type can't be expressed easily in Rust." +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust.md +msgid "/// Raw pointers\n" +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust.md +msgid "/// Integer offsets\n" +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust.md +msgid "/// Pinning\n" +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust.md +msgid "Original C++ class definition for reference" +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust.md +msgid "" +"The next few slides show three approaches to creating a Rust type with the " +"same semantics as the original C++." +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust.md +msgid "" +"Using raw pointers: matches C++ very closely, but using the resulting type " +"is extremely hazardous" +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust.md +msgid "" +"Storing integer offsets: more natural in Rust, but references need to be " +"created manually" +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust.md +msgid "Pinning: allows raw pointers with fewer `unsafe` blocks" +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust-raw-pointers.md +msgid "// Danger: must be called after every move\n" +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust-raw-pointers.md +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust-pin.md +msgid "\"cursor is out of bounds\"" +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust-raw-pointers.md +msgid "Avoid spending too much time here." +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust-raw-pointers.md +msgid "Talking points:" +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust-raw-pointers.md +msgid "" +"Emphasize that `unsafe` appears frequently. This is a hint that another " +"design may be more appropriate." +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust-raw-pointers.md +msgid "`unsafe` blocks lack safety comments. Therefore, this code is unsound." +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust-raw-pointers.md +msgid "" +"`unsafe` blocks are too broad. Good practice uses smaller `unsafe` blocks " +"with specific behavior, specific preconditions and specific safety comments." +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust-raw-pointers.md +msgid "Questions:" +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust-raw-pointers.md +msgid "" +"Q: Should the `read()` and `write()` methods be marked as unsafe? \n" +"A: Yes, because `self.cursor` will be a null pointer unless written to." +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust-offset.md +msgid "With Offset" +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust-offset.md +msgid "" +"In Rust, it's more idiomatic to use an offset variable and to create " +"references on-demand." +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust-pin.md +msgid "" +"Pinning allows Rust programmers to create a type which is much more similar " +"to C++ classes." +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust-pin.md +msgid "/// A self-referential buffer that cannot be moved.\n" +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust-pin.md +msgid "" +"Note that the function signatures have now changed. For example, `::new()` " +"returns `Pin>` rather than `Self`. This incurs a heap allocation " +"because `Pin` must work with a pointer type like `Box`." +msgstr "" + +#: src/unsafe-deep-dive/pinning/self-referential-buffer/rust-pin.md +msgid "" +"In `::new()`, we use `Pin::get_unchecked_mut()` to get a mutable reference " +"to the buffer _after_ it has been pinned. This is `unsafe` because we are " +"breaking the pinning guarantee for a moment to initialize the `cursor`. We " +"must make sure not to move the `SelfReferentialBuffer` after this point. The " +"safety contract of `Pin` is that once a value is pinned, its memory location " +"is fixed until it is dropped." +msgstr "" + +#: src/unsafe-deep-dive/pinning/pin-and-drop.md +msgid "Pin\\ and Drop" +msgstr "" + +#: src/unsafe-deep-dive/pinning/pin-and-drop.md +msgid "" +"A key challenge with pinned, `!Unpin` types is implementing the `Drop` " +"trait. The `drop` method takes `&mut self`, which allows moving the value. " +"However, pinned values must not be moved." +msgstr "" + +#: src/unsafe-deep-dive/pinning/pin-and-drop.md +msgid "An Incorrect `Drop` Implementation" +msgstr "" + +#: src/unsafe-deep-dive/pinning/pin-and-drop.md +msgid "" +"It's easy to accidentally move a value inside `drop`. Operations like " +"assignment, `ptr::read`, and `mem::replace` can silently break the pinning " +"guarantee." +msgstr "" + +#: src/unsafe-deep-dive/pinning/pin-and-drop.md +msgid "" +"// BAD: `ptr::read` moves `self.data` out of `self`.\n" +" // When `_dupe` is dropped at the end of the function, it's a double " +"free!\n" +msgstr "" + +#: src/unsafe-deep-dive/pinning/pin-and-drop.md +msgid "" +"Pinned types make guarantees about memory stability. Operations like `ptr::" +"read` and `mem::replace` can silently break these guarantees by moving or " +"duplicating data, invalidating internal pointers without the type system's " +"knowledge." +msgstr "" + +#: src/unsafe-deep-dive/pinning/pin-and-drop.md +msgid "" +"In this `drop()` method, `_dupe` is a bitwise copy of `self.data`. At the " +"end of the method, it will be dropped along with `self`. This double drop is " +"undefined behavior." +msgstr "" + +#: src/unsafe-deep-dive/pinning/pin-and-drop.md +msgid "A Correct `Drop` Implementation" +msgstr "" + +#: src/unsafe-deep-dive/pinning/pin-and-drop.md +msgid "" +"To implement `Drop` correctly for a `!Unpin` type, you must ensure that the " +"value is not moved. A common pattern is to create a helper function that " +"operates on `Pin<&mut T>`." +msgstr "" + +#: src/unsafe-deep-dive/pinning/pin-and-drop.md +msgid "// SAFETY: `this` is pinned before we create the self-reference.\n" +msgstr "" + +#: src/unsafe-deep-dive/pinning/pin-and-drop.md +msgid "// This function can only be called on a pinned `SelfRef`.\n" +msgstr "" + +#: src/unsafe-deep-dive/pinning/pin-and-drop.md +msgid "// `self` is pinned, so we must not move out of it.\n" +msgstr "" + +#: src/unsafe-deep-dive/pinning/pin-and-drop.md +msgid "\"dropping {}\"" +msgstr "" + +#: src/unsafe-deep-dive/pinning/pin-and-drop.md +msgid "" +"// We can safely call `drop_pinned` because `drop` is the last time\n" +" // the value is used. We use `new_unchecked` because we know `self`\n" +" // will not be moved again.\n" +msgstr "" + +#: src/unsafe-deep-dive/pinning/pin-and-drop.md +msgid "\"Hello, \"" +msgstr "" + +#: src/unsafe-deep-dive/pinning/pin-and-drop.md +msgid "// `Drop` runs without moving the pinned value\n" +msgstr "" + +#: src/unsafe-deep-dive/pinning/drop-and-not-unpin-worked-example.md +msgid "Worked Example: Implementing `Drop` for `!Unpin` types" +msgstr "" + +#: src/unsafe-deep-dive/pinning/drop-and-not-unpin-worked-example.md +msgid "// SAFETY: Safe because we are reading bytes from a String\n" +msgstr "" + +#: src/unsafe-deep-dive/pinning/drop-and-not-unpin-worked-example.md +msgid "\"Rust đŸĻ€\"" +msgstr "" + +#: src/unsafe-deep-dive/pinning/drop-and-not-unpin-worked-example.md +msgid "\"Batch: {:?}\"" +msgstr "" + +#: src/unsafe-deep-dive/pinning/drop-and-not-unpin-worked-example.md +msgid "" +"This example uses the `Drop` trait to add data for some post-processing, " +"such as telemetry or logging." +msgstr "" + +#: src/unsafe-deep-dive/pinning/drop-and-not-unpin-worked-example.md +msgid "" +"**The Safety comment is incorrect.** `ptr::read` creates a bitwise copy, " +"leaving `self.data` in an invalid state. `self.data` will be dropped again " +"at the end of the method, which is a double free." +msgstr "" + +#: src/unsafe-deep-dive/pinning/drop-and-not-unpin-worked-example.md +msgid "Ask the class to fix the code." +msgstr "" + +#: src/unsafe-deep-dive/pinning/drop-and-not-unpin-worked-example.md +msgid "**Suggestion 0: Redesign**" +msgstr "" + +#: src/unsafe-deep-dive/pinning/drop-and-not-unpin-worked-example.md +msgid "Redesign the post-processing system to work without `Drop`." +msgstr "" + +#: src/unsafe-deep-dive/pinning/drop-and-not-unpin-worked-example.md +msgid "**Suggestion 1: Clone**" +msgstr "" + +#: src/unsafe-deep-dive/pinning/drop-and-not-unpin-worked-example.md +msgid "Using `.clone()` is an obvious first choice, but it allocates memory." +msgstr "" + +#: src/unsafe-deep-dive/pinning/drop-and-not-unpin-worked-example.md +msgid "**Suggestion 2: ManuallyDrop**" +msgstr "" + +#: src/unsafe-deep-dive/pinning/drop-and-not-unpin-worked-example.md +msgid "" +"Wrapping `CustomString` in `ManuallyDrop` prevents the (second) automatic " +"drop at the end of the `Drop` impl." +msgstr "" + +#: src/unsafe-deep-dive/pinning/drop-and-not-unpin-worked-example.md +msgid "// SAFETY: self.data\n" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-interop.md +msgid "Ideal scenario:" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-interop.md +#: src/unsafe-deep-dive/ffi/strategies.md +msgid "" +"```bob\n" +"╭────────────╮ ╭────────────╮\n" +"│ │ │ │\n" +"│ │ <--------------------------------------> │ │\n" +"│ │ │ │\n" +"╰────────────╯ ╰────────────╯\n" +" Rust \"C++\"\n" +"```" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-interop.md +msgid "" +"This section of the course covers interacting with Rust and external " +"languages via its foreign-function interface (FFI), with a special focus on " +"interoperability with C++." +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-interop.md +msgid "" +"Ideally, users of Rust and the external language (in this case C++) could " +"call each others’ methods directly." +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-interop.md +msgid "This ideal scenario is very difficult to achieve:" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-interop.md +msgid "" +"Different languages have different semantics and mapping between them " +"implies trade-offs Neither Rust nor C++ offer ABI stability[^1], making it " +"difficult to build from a stable foundation" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-interop.md +msgid "" +"Some C++ compiler vendors provide support for ABI stability within their " +"toolchain." +msgstr "" + +#: src/unsafe-deep-dive/ffi/strategies.md +msgid "Strategies of interop" +msgstr "" + +#: src/unsafe-deep-dive/ffi/strategies.md +msgid "Sharing data structures and symbols directly is very difficult:" +msgstr "" + +#: src/unsafe-deep-dive/ffi/strategies.md +msgid "FFI through the C ABI is much more feasible:" +msgstr "" + +#: src/unsafe-deep-dive/ffi/strategies.md +#: src/unsafe-deep-dive/ffi/language-differences.md +msgid "" +"````````bob\n" +"╭────────────╮ ╭───╮ ╭───╮ ╭────────────╮\n" +"│ │ │ │ │ │ │ │\n" +"│ │ <-----> │ │ <~~~~~~~> │ │ <------> │ │ \n" +"│ │ │ │ │ │ │ │\n" +"╰────────────╯ ╰───╯ ╰───╯ ╰────────────╯\n" +" Rust C C \"C++\"\n" +"````````" +msgstr "" + +#: src/unsafe-deep-dive/ffi/strategies.md +msgid "Other strategies:" +msgstr "" + +#: src/unsafe-deep-dive/ffi/strategies.md +msgid "Distributed system (RPC)" +msgstr "" + +#: src/unsafe-deep-dive/ffi/strategies.md +msgid "Custom ABI (i.e. WebAssembly Interface Types)" +msgstr "" + +#: src/unsafe-deep-dive/ffi/strategies.md +msgid "_High-fidelity interop_" +msgstr "" + +#: src/unsafe-deep-dive/ffi/strategies.md +msgid "The ideal scenario is currently experimental." +msgstr "" + +#: src/unsafe-deep-dive/ffi/strategies.md +msgid "" +"Two projects exploring this are [crubit](https://github.com/google/crubit) " +"and [Zngur](https://hkalbasi.github.io/zngur/). The first provides glue code " +"on each side for enabling compatible types to work seamlessly across " +"domains. The second relies on dynamic dispatch and imports C++ objects into " +"Rust as trait objects." +msgstr "" + +#: src/unsafe-deep-dive/ffi/strategies.md +msgid "_Low-fidelity interop_ work through a C API" +msgstr "" + +#: src/unsafe-deep-dive/ffi/strategies.md +msgid "" +"The typical strategy for interop is to use the C language as the interface. " +"C is a lossy codec. This strategy typically results in complicated code on " +"both sides." +msgstr "" + +#: src/unsafe-deep-dive/ffi/strategies.md +msgid "_Other strategies_ are less viable in a zero cost environment." +msgstr "" + +#: src/unsafe-deep-dive/ffi/strategies.md +msgid "_Distributed systems_ impose runtime costs." +msgstr "" + +#: src/unsafe-deep-dive/ffi/strategies.md +msgid "" +"They incur significant overhead as calling a method in a foreign library " +"incurs a round trip of serialization/transport/deserialization. Generally " +"speaking, a transparent RPC is not a good idea. There’s network in the " +"middle." +msgstr "" + +#: src/unsafe-deep-dive/ffi/strategies.md +msgid "" +"_Custom ABI_, such as wasm require a runtime or significant implementation " +"cost." +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences.md +msgid "" +"Using C as the lowest common denominator means that lots of the richness " +"available to Rust and C++ is lost." +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences.md +msgid "" +"Each translation has the potential for semantic loss, runtime overhead, and " +"subtle bugs." +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/representations.md +msgid "b\"Hello, C\\0\"" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/representations.md +msgid "b\"Hello, C++\\0\"" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/representations.md +msgid "b\"Hello, Rust\"" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/representations.md +msgid "" +"Each language has its own opinion about how to implement things, which can " +"lead to confusion and bugs. Consider three ways to represent text." +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/representations.md +msgid "Show how to convert the raw representations to a Rust string slice:" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/representations.md +msgid "// C representation to Rust\n" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/representations.md +msgid "\"{c}\"" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/representations.md +msgid "// C++ representation to Rust \n" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/representations.md +msgid "\"{cc}\"" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/representations.md +msgid "// Rust representation (bytes) to string slice\n" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/representations.md +msgid "\"{rust}\"" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/representations.md +msgid "" +"Aside: Rust has a c-prefixed string literal. It appends a null byte at the " +"end, e.g. `c\"Rust\" == b\"Rust\\0\"`." +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/semantics.md +msgid "/// Create a formatted time based on timestamp `t`.\n" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/semantics.md +msgid "" +"// SAFETY: `seconds` is generated by the system clock and will not cause\n" +" // overflow\n" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/semantics.md +msgid "" +"// SAFETY: ctime returns a pointer to a preallocated (non-null) buffer\n" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/semantics.md +msgid "// SAFETY: ctime uses valid UTF-8\n" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/semantics.md +msgid "\"{t:?}\"" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/semantics.md +msgid "" +"Some constructs that other languages allow cannot be expressed in the Rust " +"language." +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/semantics.md +msgid "" +"The `ctime` function modifies an internal buffer shared between calls. This " +"cannot be represented as Rust’s lifetimes." +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/semantics.md +msgid "`'static` does not apply, as the semantics are different" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/semantics.md +msgid "`'a` does not apply, as the buffer outlives each call" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +#: src/unsafe-deep-dive/ffi/language-differences/cpp-and-c.md +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "Concern" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "Rust" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +#: src/unsafe-deep-dive/ffi/language-differences/cpp-and-c.md +msgid "C" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "**Errors**" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "`Result`, `Option`" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "Magic return values, out-parameters, global `errno`" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "**Strings**" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "`&str`/`String` (UTF-8, length-known)" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "Null-terminated `char*`, encoding undefined" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "**Nullability**" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "Explicit via `Option`" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "Any pointer may be null" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "**Ownership**" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "Affine types, lifetimes" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "Conventions" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "**Callbacks**" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "`Fn`/`FnMut`/`FnOnce` closures" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "Function pointer + `void* userdata`" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "**Panics**" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "Stack unwinding (or abort)" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "Abort" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "" +"Errors: Must convert `Result` to abide by C conventions; easy to forget to " +"check errors on C side." +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "" +"Strings: Conversion cost; null bytes in Rust strings cause truncation; UTF-8 " +"validation on ingress." +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "" +"Nullability: Every pointer from C must be checked to create an " +"`Option>`, implying unsafe blocks or runtime cost." +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "Ownership: Must document and enforce object lifetimes manually." +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "" +"Callbacks: Must decompose closures into fn pointer + context; lifetime of " +"context is manual." +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-c.md +msgid "" +"Panics: Panic across FFI boundary is undefined behavior; must catch at " +"boundary with `catch_unwind`." +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/cpp-and-c.md +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "C++" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/cpp-and-c.md +msgid "**Overloading**" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/cpp-and-c.md +msgid "Manual/ad-hoc" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/cpp-and-c.md +msgid "Automatic" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/cpp-and-c.md +msgid "**Exceptions**" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/cpp-and-c.md +msgid "\\-" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/cpp-and-c.md +msgid "Stack unwinding" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/cpp-and-c.md +msgid "**Destructors**" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/cpp-and-c.md +msgid "Manual cleanup" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/cpp-and-c.md +msgid "Automatic via destructors (RAII)" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/cpp-and-c.md +msgid "**Non-POD types**" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/cpp-and-c.md +msgid "Objects with constructors, vtables, virtual bases" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/cpp-and-c.md +msgid "**Templates**" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/cpp-and-c.md +msgid "Compile-time code generation" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/cpp-and-c.md +msgid "" +"C++ includes a number of features that don't exist in C with an FFI impact:" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/cpp-and-c.md +msgid "" +"Overloading: Overloads become impossible to express because of name mangling" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/cpp-and-c.md +msgid "" +"Exceptions: Must catch exceptions at the FFI boundary and convert them to " +"error codes, as escaping exceptions in `extern \"C\"` functions constitute " +"undefined behavior" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/cpp-and-c.md +msgid "" +"Destructors: C callers won't run destructors; must expose explicit " +"`*_destroy()` functions" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/cpp-and-c.md +msgid "" +"Non-POD types: Must use opaque pointers across the FFI boundary as pass by " +"value does not make sense" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/cpp-and-c.md +msgid "" +"Templates: Cannot expose directly; must instantiate explicitly and wrap each " +"specialization" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "**Trivial relocatability**" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "All moves are `memcpy`" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "Self-referential types, move constructors can have side effects" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "**Destruction safety**" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "`Drop::drop()` on original location only" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "Destructor may run on moved-from objects" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "**Exception safety**" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "Panics (abort or unwind)" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "Exceptions (unwind)" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "**ABI stability**" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "Explicitly unstable" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "Vendor-specific" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "" +"Even if it were possible to avoid interop via C, there are still some areas " +"of the languages that impact FFI:" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "_Trivial relocatability_" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "" +"Cannot safely move C++ objects on the Rust side; must pin or keep in C++ " +"heap." +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "" +"In Rust, object movement, which occurs during assignment or by being passed " +"by value, always copies values bit by bit." +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "" +"C++ allows users to define their own semantics by allowing them to overload " +"the assignment operator and create move and copy constructors." +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "" +"This impacts interop because self-referential types become natural in high-" +"performance C++. Custom constructors can uphold safety invariants even when " +"the object moves its position in memory." +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "Objects with the same semantics are impossible to define in Rust." +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "_Destruction safety_" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "" +"Moved-from C++ object semantics don't map; must prevent Rust from \"moving\" " +"C++ types." +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "_Exception safety_" +msgstr "" + +#: src/unsafe-deep-dive/ffi/language-differences/rust-and-cpp.md +msgid "" +"Neither can cross into the other safely; both must catch at the boundary." +msgstr "" + +#: src/unsafe-deep-dive/ffi/abs.md +msgid "Wrapping `abs(3)`" +msgstr "" + +#: src/unsafe-deep-dive/ffi/abs.md +msgid "In this slide, we’re establishing a pattern for writing wrappers." +msgstr "" + +#: src/unsafe-deep-dive/ffi/abs.md +msgid "" +"Find the external definition of a function’s signature Write a matching " +"function in Rust within an `extern` block Confirm which safety invariants " +"need to be upheld Decide whether it’s possible to mark the function as safe" +msgstr "" + +#: src/unsafe-deep-dive/ffi/abs.md +msgid "Note that this doesn’t work _yet_." +msgstr "" + +#: src/unsafe-deep-dive/ffi/abs.md +msgid "Add the extern block:" +msgstr "" + +#: src/unsafe-deep-dive/ffi/abs.md +msgid "" +"Explain that many POSIX functions are available in Rust because Cargo links " +"against the C standard library (libc) by default, which brings its symbols " +"into the program’s scope." +msgstr "" + +#: src/unsafe-deep-dive/ffi/abs.md +msgid "" +"Show `man 3 abs` in the terminal or [a webpage](https://www.man7.org/linux/" +"man-pages/man3/abs.3.html)." +msgstr "" + +#: src/unsafe-deep-dive/ffi/abs.md +msgid "" +"Explain that our function signature must match its definition: `int abs(int " +"j);`." +msgstr "" + +#: src/unsafe-deep-dive/ffi/abs.md +msgid "Update the code block to use the C types." +msgstr "" + +#: src/unsafe-deep-dive/ffi/abs.md +msgid "" +"Discuss rationale: using `ffi::c_int` increases the portability of our code. " +"When the standard library is compiled for the target platform, the platform " +"can determine the widths. According to the C standard, a `c_int` may be " +"defined as an `i16` rather than the much more common `i32`." +msgstr "" + +#: src/unsafe-deep-dive/ffi/abs.md +msgid "" +"(Optional) Show the [documentation for c_int](https://doc.rust-lang.org/std/" +"ffi/type.c_int.html) to reveal that it is a type alias for `i32`." +msgstr "" + +#: src/unsafe-deep-dive/ffi/abs.md +msgid "" +"Attempt to compile to trigger “error: extern blocks must be unsafe” error " +"message." +msgstr "" + +#: src/unsafe-deep-dive/ffi/abs.md +msgid "Add the unsafe keyword to the block:" +msgstr "" + +#: src/unsafe-deep-dive/ffi/abs.md +msgid "" +"Check that learners understand the significance of this change. We are " +"required to uphold type safety and other safety preconditions." +msgstr "" + +#: src/unsafe-deep-dive/ffi/abs.md +msgid "Recompile." +msgstr "" + +#: src/unsafe-deep-dive/ffi/abs.md +msgid "Add safe keyword to the abs function:" +msgstr "" + +#: src/unsafe-deep-dive/ffi/abs.md +msgid "" +"Explain that the `safe fn` marks `abs` as safe to call without an `unsafe` " +"block." +msgstr "" + +#: src/unsafe-deep-dive/ffi/abs.md +msgid "Completed program for reference:" +msgstr "" + +#: src/unsafe-deep-dive/ffi/rand.md +msgid "Wrapping `srand(3)` and `rand(3)`" +msgstr "" + +#: src/unsafe-deep-dive/ffi/rand.md +msgid "" +"// unsafe extern \"C\" {\n" +"// /// Seed the rng\n" +"// fn srand(seed: std::ffi::c_uint);\n" +msgstr "" + +#: src/unsafe-deep-dive/ffi/rand.md +msgid "" +"// fn rand() -> std::ffi::c_int;\n" +"// }\n" +msgstr "" + +#: src/unsafe-deep-dive/ffi/rand.md +msgid "\"{a:?}\"" +msgstr "" + +#: src/unsafe-deep-dive/ffi/rand.md +msgid "" +"This slide attempts to demonstrate that it is very easy for wrappers to " +"trigger undefined behavior if they are written incorrectly. We’ll see how " +"easy it is to trigger type safety problems." +msgstr "" + +#: src/unsafe-deep-dive/ffi/rand.md +msgid "" +"Explain that `rand` and `srand` functions are provided by the C standard " +"library (libc)." +msgstr "" + +#: src/unsafe-deep-dive/ffi/rand.md +msgid "" +"Explain that the functions are exported by the libc crate, but we can also " +"write an FFI wrapper for them manually." +msgstr "" + +#: src/unsafe-deep-dive/ffi/rand.md +msgid "Show calling the functions from the exported." +msgstr "" + +#: src/unsafe-deep-dive/ffi/rand.md +msgid "Code compiles because libc is linked to Rust programs by default." +msgstr "" + +#: src/unsafe-deep-dive/ffi/rand.md +msgid "Explain that Rust will trust you if you use the wrong type(s)." +msgstr "" + +#: src/unsafe-deep-dive/ffi/rand.md +msgid "Modify `fn rand() -> std::ffi::c_int;` to return `char`." +msgstr "" + +#: src/unsafe-deep-dive/ffi/rand.md +msgid "" +"Avoiding type safety issues is a reason for using tools for generating " +"wrappers, rather than doing it by hand." +msgstr "" + +#: src/unsafe-deep-dive/ffi/c-library-example.md +msgid "C Library Example" +msgstr "" + +#: src/unsafe-deep-dive/ffi/c-library-example.md +#: src/unsafe-deep-dive/ffi/cpp-library-example.md +msgid "" +msgstr "" + +#: src/unsafe-deep-dive/ffi/c-library-example.md +msgid "" +msgstr "" + +#: src/unsafe-deep-dive/ffi/c-library-example.md +msgid "/* Return `false` to indicate that no token was found. */" +msgstr "" + +#: src/unsafe-deep-dive/ffi/c-library-example.md +msgid "/* TextAnalyst constructor */" +msgstr "" + +#: src/unsafe-deep-dive/ffi/c-library-example.md +msgid "/* TextAnalyst destructor */" +msgstr "" + +#: src/unsafe-deep-dive/ffi/c-library-example.md +msgid "/* Resets state to clear the current document */" +msgstr "" + +#: src/unsafe-deep-dive/ffi/c-library-example.md +msgid "/* Use custom tokenizer (defaults to whitespace) */" +msgstr "" + +#: src/unsafe-deep-dive/ffi/c-library-example.md +msgid "/* Apply `callback` to each token */" +msgstr "" + +#: src/unsafe-deep-dive/ffi/c-library-example.md +msgid "/* Get human-readable error message */" +msgstr "" + +#: src/unsafe-deep-dive/ffi/c-library-example.md +msgid "/* TEXT_ANALYSIS_H */" +msgstr "" + +#: src/unsafe-deep-dive/ffi/c-library-example.md +msgid "" +"C libraries will hide their implementation details with a `void*` argument." +msgstr "" + +#: src/unsafe-deep-dive/ffi/c-library-example.md +msgid "" +"Consider this header file of a natural language processing library that " +"hides the `TextAnalyst` and `Analysis` types." +msgstr "" + +#: src/unsafe-deep-dive/ffi/c-library-example.md +msgid "This can be emulated in Rust with a type similar to this:" +msgstr "" + +#: src/unsafe-deep-dive/ffi/c-library-example.md +msgid "Exercise: Ask learners to wrap this library." +msgstr "" + +#: src/unsafe-deep-dive/ffi/c-library-example.md +msgid "// ffi.rs\n" +msgstr "" + +#: src/unsafe-deep-dive/ffi/cpp-library-example.md +msgid "Example: String interning library" +msgstr "" + +#: src/unsafe-deep-dive/ffi/cpp-library-example.md +msgid "C++ Header: interner.hpp" +msgstr "" + +#: src/unsafe-deep-dive/ffi/cpp-library-example.md +msgid "" +msgstr "" + +#: src/unsafe-deep-dive/ffi/cpp-library-example.md +msgid "" +msgstr "" + +#: src/unsafe-deep-dive/ffi/cpp-library-example.md +msgid "" +"// Returns a pointer to the interned string (valid for lifetime of " +"interner)\n" +msgstr "" + +#: src/unsafe-deep-dive/ffi/cpp-library-example.md +msgid "C header file: interner.h" +msgstr "" + +#: src/unsafe-deep-dive/ffi/cpp-library-example.md +msgid "// interner.h (C API for FFI)\n" +msgstr "" + +#: src/unsafe-deep-dive/ffi/cpp-library-example.md +msgid "C++ implementation (interner.cpp)" +msgstr "" + +#: src/unsafe-deep-dive/ffi/cpp-library-example.md +msgid "\"interner.hpp\"" +msgstr "" + +#: src/unsafe-deep-dive/ffi/cpp-library-example.md +msgid "\"interner.h\"" +msgstr "" + +#: src/unsafe-deep-dive/ffi/cpp-library-example.md +msgid "" +"This is a larger example. Write a wrapper for the string interner. You will " +"need to guide learners on how to create an opaque pointer, either directly " +"by explaining the code below or asking learners to do further research." +msgstr "" + +#: src/unsafe-deep-dive/ffi/cpp-library-example.md +msgid "Once the raw wrapper is written, ask learners to create a safe wrapper." +msgstr "" + #: src/thanks.md msgid "" "_Thank you for taking Comprehensive Rust đŸĻ€!_ We hope you enjoyed it and " "that it was useful." msgstr "" -"Comprehensive Rust đŸĻ€ āϕ⧋āĻ°ā§āϏāϟāĻŋ āύ⧇āĻ“āϝāĻŧāĻžāϰ āϜāĻ¨ā§āϝ āφāĻĒāύāĻžāϕ⧇ āϧāĻ¨ā§āϝāĻŦāĻžāĻĻ! āφāĻŽāϰāĻž āφāĻļāĻž āĻ•āϰāĻŋ āφāĻĒāύāĻŋ āĻāϟāĻŋ " -"āωāĻĒāĻ­ā§‹āĻ— āĻ•āϰ⧇āϛ⧇āύ āĻāĻŦāĻ‚ āĻāϟāĻŋ āωāĻĒāĻ•āĻžāϰ⧀ āĻ›āĻŋāϞ⧋āĨ¤" #: src/thanks.md msgid "" -"We've had a lot of fun putting the course together. The course is not " -"perfect, so if you spotted any mistakes or have ideas for improvements, " -"please get in [contact with us on GitHub](https://github.com/google/" -"comprehensive-rust/discussions). We would love to hear from you." +"We have enjoyed putting the course together. The course is not perfect, so " +"if you spotted any mistakes or have ideas for improvements, please get in " +"[contact with us on GitHub](https://github.com/google/comprehensive-rust/" +"discussions). We would love to hear from you." +msgstr "" + +#: src/thanks.md +msgid "" +"Thank you for reading the speaker notes! We hope they have been useful. If " +"you find pages without notes, please send us a PR and link it to [issue " +"#1083](https://github.com/google/comprehensive-rust/issues/1083). We are " +"also very grateful for fixes and improvements to the existing notes." msgstr "" #: src/glossary.md @@ -19348,16 +33913,25 @@ msgid "" "the English original." msgstr "" +#. Please add the English term in italic after your translated term. Also, please keep the hard line breaks to ensure a nice formatting. #: src/glossary.md msgid "" "allocate: \n" -"Dynamic memory allocation on [the heap](memory-management/stack-vs-heap.md)." +"Dynamic memory allocation on [the heap](memory-management/review.md)." msgstr "" #: src/glossary.md msgid "" -"argument: \n" -"Information that is passed into a function or method." +"array: \n" +"A fixed-size collection of elements of the same type, stored contiguously in " +"memory. See [Arrays](tuples-and-arrays/arrays.md)." +msgstr "" + +#: src/glossary.md +msgid "" +"associated type: \n" +"A type associated with a specific trait. Useful for defining the " +"relationship between types." msgstr "" #: src/glossary.md @@ -19370,38 +33944,27 @@ msgstr "" #: src/glossary.md msgid "" "block: \n" -"See [Blocks](control-flow/blocks.md) and _scope_." +"See [Blocks](control-flow-basics/blocks-and-scopes.md) and _scope_." msgstr "" #: src/glossary.md msgid "" "borrow: \n" -"See [Borrowing](ownership/borrowing.md)." +"See [Borrowing](borrowing/shared.md)." msgstr "" #: src/glossary.md msgid "" "borrow checker: \n" -"The part of the Rust compiler which checks that all borrows are valid." +"The part of the Rust compiler which checks that all [borrows](borrowing/" +"borrowck.md) are valid." msgstr "" #: src/glossary.md msgid "" "brace: \n" -"`{` and `}`. Also called _curly brace_, they delimit _blocks_." -msgstr "" - -#: src/glossary.md -msgid "" -"build: \n" -"The process of converting source code into executable code or a usable " -"program." -msgstr "" - -#: src/glossary.md -msgid "" -"call: \n" -"To invoke or execute a function or method." +"`{` and `}`. Also called _curly brace_, they delimit [_blocks_](control-flow-" +"basics/blocks-and-scopes.md)." msgstr "" #: src/glossary.md @@ -19410,194 +33973,177 @@ msgid "" "Used to safely pass messages [between threads](concurrency/channels.md)." msgstr "" -#: src/glossary.md -msgid "" -"Comprehensive Rust đŸĻ€: \n" -"The courses here are jointly called Comprehensive Rust đŸĻ€." -msgstr "" - #: src/glossary.md msgid "" "concurrency: \n" -"The execution of multiple tasks or processes at the same time." -msgstr "" - -#: src/glossary.md -msgid "" -"Concurrency in Rust: \n" -"See [Concurrency in Rust](concurrency.md)." +"The execution of multiple tasks or processes at the same time. See [Welcome " +"to Concurrency in Rust](concurrency/welcome.md)." msgstr "" #: src/glossary.md msgid "" "constant: \n" -"A value that does not change during the execution of a program." +"A value that does not change during the execution of a program. See [const]" +"(user-defined-types/const.md)." msgstr "" #: src/glossary.md msgid "" "control flow: \n" "The order in which the individual statements or instructions are executed in " -"a program." +"a program. See [Control Flow Basics](control-flow-basics.md)." msgstr "" #: src/glossary.md msgid "" "crash: \n" -"An unexpected and unhandled failure or termination of a program." +"An unexpected and unhandled failure or termination of a program. See [panic]" +"(error-handling/panics.md)." msgstr "" #: src/glossary.md msgid "" "enumeration: \n" "A data type that holds one of several named constants, possibly with an " -"associated tuple or struct." +"associated tuple or struct. See [enum](user-defined-types/enums.md)." msgstr "" #: src/glossary.md msgid "" "error: \n" -"An unexpected condition or result that deviates from the expected behavior." +"An unexpected condition or result that deviates from the expected behavior. " +"See [Error Handling](error-handling.md)." msgstr "" #: src/glossary.md msgid "" "error handling: \n" -"The process of managing and responding to errors that occur during program " -"execution." -msgstr "" - -#: src/glossary.md -msgid "" -"exercise: \n" -"A task or problem designed to practice and test programming skills." +"The process of managing and responding to [errors](error-handling.md) that " +"occur during program execution." msgstr "" #: src/glossary.md msgid "" "function: \n" -"A reusable block of code that performs a specific task." +"A reusable block of code that performs a specific task. See [Functions]" +"(control-flow-basics/functions.md)." msgstr "" #: src/glossary.md msgid "" "garbage collector: \n" "A mechanism that automatically frees up memory occupied by objects that are " -"no longer in use." +"no longer in use. See [Approaches to Memory Management](memory-management/" +"approaches.md)." msgstr "" #: src/glossary.md msgid "" "generics: \n" "A feature that allows writing code with placeholders for types, enabling " -"code reuse with different data types." +"code reuse with different data types. See [Generics](generics.md)." msgstr "" #: src/glossary.md msgid "" "immutable: \n" -"Unable to be changed after creation." +"Unable to be changed after creation. See [Variables](types-and-values/" +"variables.md)." msgstr "" #: src/glossary.md msgid "" "integration test: \n" "A type of test that verifies the interactions between different parts or " -"components of a system." -msgstr "" - -#: src/glossary.md -msgid "" -"keyword: \n" -"A reserved word in a programming language that has a specific meaning and " -"cannot be used as an identifier." +"components of a system. See [Other Types of Tests](testing/other.md)." msgstr "" #: src/glossary.md msgid "" "library: \n" -"A collection of precompiled routines or code that can be used by programs." +"A collection of precompiled routines or code that can be used by programs. " +"See [Modules](modules.md)." msgstr "" #: src/glossary.md msgid "" "macro: \n" -"Rust macros can be recognized by a `!` in the name. Macros are used when " -"normal functions are not enough. A typical example is `format!`, which takes " -"a variable number of arguments, which isn't supported by Rust functions." +"Rust [macros](control-flow-basics/macros.md) can be recognized by a `!` in " +"the name. Macros are used when normal functions are not enough. A typical " +"example is `format!`, which takes a variable number of arguments, which " +"isn't supported by Rust functions." msgstr "" #: src/glossary.md msgid "" "`main` function: \n" -"Rust programs start executing with the `main` function." +"Rust programs start executing with the [`main` function](types-and-values/" +"hello-world.md)." msgstr "" #: src/glossary.md msgid "" "match: \n" -"A control flow construct in Rust that allows for pattern matching on the " -"value of an expression." +"A control flow construct in Rust that allows for [pattern matching](pattern-" +"matching.md) on the value of an expression." msgstr "" #: src/glossary.md msgid "" "memory leak: \n" "A situation where a program fails to release memory that is no longer " -"needed, leading to a gradual increase in memory usage." +"needed, leading to a gradual increase in memory usage. See [Approaches to " +"Memory Management](memory-management/approaches.md)." msgstr "" #: src/glossary.md msgid "" "method: \n" -"A function associated with an object or a type in Rust." +"A function associated with an object or a type in Rust. See [Methods]" +"(methods-and-traits/methods.md)." msgstr "" #: src/glossary.md msgid "" "module: \n" "A namespace that contains definitions, such as functions, types, or traits, " -"to organize code in Rust." +"to organize code in Rust. See [Modules](modules.md)." msgstr "" #: src/glossary.md msgid "" "move: \n" -"The transfer of ownership of a value from one variable to another in Rust." +"The transfer of ownership of a value from one variable to another in Rust. " +"See [Move Semantics](memory-management/move.md)." msgstr "" #: src/glossary.md msgid "" "mutable: \n" -"A property in Rust that allows variables to be modified after they have been " -"declared." +"A property in Rust that allows [variables](types-and-values/variables.md) to " +"be modified after they have been declared." msgstr "" #: src/glossary.md msgid "" "ownership: \n" "The concept in Rust that defines which part of the code is responsible for " -"managing the memory associated with a value." +"managing the memory associated with a value. See [Ownership](memory-" +"management/ownership.md)." msgstr "" #: src/glossary.md msgid "" "panic: \n" "An unrecoverable error condition in Rust that results in the termination of " -"the program." -msgstr "" - -#: src/glossary.md -msgid "" -"parameter: \n" -"A value that is passed into a function or method when it is called." +"the program. See [Panics](error-handling/panics.md)." msgstr "" #: src/glossary.md msgid "" "pattern: \n" "A combination of values, literals, or structures that can be matched against " -"an expression in Rust." +"an expression in Rust. See [Pattern Matching](pattern-matching.md)." msgstr "" #: src/glossary.md @@ -19606,196 +34152,183 @@ msgid "" "The data or information carried by a message, event, or data structure." msgstr "" -#: src/glossary.md -msgid "" -"program: \n" -"A set of instructions that a computer can execute to perform a specific task " -"or solve a particular problem." -msgstr "" - -#: src/glossary.md -msgid "" -"programming language: \n" -"A formal system used to communicate instructions to a computer, such as Rust." -msgstr "" - #: src/glossary.md msgid "" "receiver: \n" -"The first parameter in a Rust method that represents the instance on which " -"the method is called." +"The first parameter in a Rust [method](methods-and-traits/methods.md) that " +"represents the instance on which the method is called." +msgstr "" + +#: src/glossary.md +msgid "" +"reference: \n" +"A non-owning pointer to a value that borrows it without transferring " +"ownership. References can be [shared (immutable)](references/shared.md) or " +"[exclusive (mutable)](references/exclusive.md)." msgstr "" #: src/glossary.md msgid "" "reference counting: \n" "A memory management technique in which the number of references to an object " -"is tracked, and the object is deallocated when the count reaches zero." -msgstr "" - -#: src/glossary.md -msgid "" -"return: \n" -"A keyword in Rust used to indicate the value to be returned from a function." +"is tracked, and the object is deallocated when the count reaches zero. See " +"[Rc](smart-pointers/rc.md)." msgstr "" #: src/glossary.md msgid "" "Rust: \n" "A systems programming language that focuses on safety, performance, and " -"concurrency." -msgstr "" - -#: src/glossary.md -msgid "" -"Rust Fundamentals: \n" -"Days 1 to 4 of this course." -msgstr "" - -#: src/glossary.md -msgid "" -"Rust in Android: \n" -"See [Rust in Android](android.md)." -msgstr "" - -#: src/glossary.md -msgid "" -"Rust in Chromium: \n" -"See [Rust in Chromium](chromium.md)." +"concurrency. See [What is Rust?](hello-world/what-is-rust.md)." msgstr "" #: src/glossary.md msgid "" "safe: \n" "Refers to code that adheres to Rust's ownership and borrowing rules, " -"preventing memory-related errors." +"preventing memory-related errors. See [Unsafe Rust](unsafe-rust.md)." +msgstr "" + +#: src/glossary.md +msgid "" +"slice: \n" +"A dynamically-sized view into a contiguous sequence, such as an array or " +"vector. Unlike arrays, slices have a size determined at runtime. See [Slices]" +"(references/slices.md)." msgstr "" #: src/glossary.md msgid "" "scope: \n" -"The region of a program where a variable is valid and can be used." +"The region of a program where a variable is valid and can be used. See " +"[Blocks and Scopes](control-flow-basics/blocks-and-scopes.md)." msgstr "" #: src/glossary.md msgid "" "standard library: \n" -"A collection of modules providing essential functionality in Rust." +"A collection of modules providing essential functionality in Rust. See " +"[Standard Library](std-types/std.md)." msgstr "" #: src/glossary.md msgid "" "static: \n" "A keyword in Rust used to define static variables or items with a `'static` " -"lifetime." +"lifetime. See [static](user-defined-types/static.md)." msgstr "" #: src/glossary.md msgid "" "string: \n" -"A data type storing textual data. See [`String` vs `str`](basic-syntax/" -"string-slices.html) for more." +"A data type storing textual data. See [Strings](references/strings.md)." msgstr "" #: src/glossary.md msgid "" "struct: \n" "A composite data type in Rust that groups together variables of different " -"types under a single name." +"types under a single name. See [Structs](user-defined-types/named-structs." +"md)." msgstr "" #: src/glossary.md msgid "" "test: \n" -"A Rust module containing functions that test the correctness of other " -"functions." +"A function that tests the correctness of other code. Rust has a built-in " +"test runner. See [Testing](testing.md)." msgstr "" #: src/glossary.md msgid "" "thread: \n" -"A separate sequence of execution in a program, allowing concurrent execution." +"A separate sequence of execution in a program, allowing concurrent " +"execution. See [Threads](concurrency/threads.md)." msgstr "" #: src/glossary.md msgid "" "thread safety: \n" "The property of a program that ensures correct behavior in a multithreaded " -"environment." +"environment. See [Send and Sync](concurrency/send-sync.md)." msgstr "" #: src/glossary.md msgid "" "trait: \n" "A collection of methods defined for an unknown type, providing a way to " -"achieve polymorphism in Rust." +"achieve polymorphism in Rust. See [Traits](methods-and-traits/traits.md)." msgstr "" #: src/glossary.md msgid "" "trait bound: \n" "An abstraction where you can require types to implement some traits of your " -"interest." +"interest. See [Trait Bounds](generics/trait-bounds.md)." msgstr "" #: src/glossary.md msgid "" "tuple: \n" "A composite data type that contains variables of different types. Tuple " -"fields have no names, and are accessed by their ordinal numbers." +"fields have no names, and are accessed by their ordinal numbers. See [Tuples]" +"(tuples-and-arrays/tuples.md)." msgstr "" #: src/glossary.md msgid "" "type: \n" "A classification that specifies which operations can be performed on values " -"of a particular kind in Rust." +"of a particular kind in Rust. See [Types and Values](types-and-values.md)." msgstr "" #: src/glossary.md msgid "" "type inference: \n" "The ability of the Rust compiler to deduce the type of a variable or " -"expression." +"expression. See [Type Inference](types-and-values/inference.md)." msgstr "" #: src/glossary.md msgid "" "undefined behavior: \n" "Actions or conditions in Rust that have no specified result, often leading " -"to unpredictable program behavior." +"to unpredictable program behavior. See [Unsafe Rust](unsafe-rust.md)." msgstr "" #: src/glossary.md msgid "" "union: \n" -"A data type that can hold values of different types but only one at a time." +"A data type that can hold values of different types but only one at a time. " +"See [Unions](unsafe-rust/unions.md)." msgstr "" #: src/glossary.md msgid "" "unit test: \n" "Rust comes with built-in support for running small unit tests and larger " -"integration tests. See [Unit Tests](testing/unit-tests.html)." +"integration tests. See [Unit Tests](testing/unit-tests.md)." msgstr "" #: src/glossary.md msgid "" "unit type: \n" -"Type that holds no data, written as a tuple with no members." +"Type that holds no data, written as a tuple with no members. See speaker " +"notes on [Functions](control-flow-basics/functions.html)." msgstr "" #: src/glossary.md msgid "" "unsafe: \n" "The subset of Rust which allows you to trigger _undefined behavior_. See " -"[Unsafe Rust](unsafe.html)." +"[Unsafe Rust](unsafe-rust/unsafe.md)." msgstr "" #: src/glossary.md msgid "" "variable: \n" -"A memory location storing data. Variables are valid in a _scope_." +"A memory location storing data. Variables are valid in a _scope_. See " +"[Variables](types-and-values/variables.md)." msgstr "" #: src/other-resources.md @@ -19810,7 +34343,7 @@ msgstr "" #: src/other-resources.md msgid "Official Documentation" -msgstr "āĻ…āĻĢāĻŋāϏāĻŋāϝāĻŧāĻžāϞ āĻĄāϕ⧁āĻŽā§‡āĻ¨ā§āĻŸā§‡āĻļāύ" +msgstr "" #: src/other-resources.md msgid "The Rust project hosts many resources. These cover Rust in general:" @@ -19843,6 +34376,12 @@ msgid "" "book which describes the Rust grammar and memory model." msgstr "" +#: src/other-resources.md +msgid "" +"[Rust API Guidelines](https://rust-lang.github.io/api-guidelines/): " +"recommendations on how to design APIs." +msgstr "" + #: src/other-resources.md msgid "More specialized guides hosted on the official Rust site:" msgstr "" @@ -19884,9 +34423,9 @@ msgstr "" #: src/other-resources.md msgid "" -"[Rust for Embedded C Programmers](https://docs.opentitan.org/doc/ug/" -"rust_for_c/): covers Rust from the perspective of developers who write " -"firmware in C." +"[Rust for Embedded C Programmers](https://opentitan.org/book/doc/" +"rust_for_c_devs.html): covers Rust from the perspective of developers who " +"write firmware in C." msgstr "" #: src/other-resources.md @@ -19910,6 +34449,14 @@ msgid "" "and async/await are also covered." msgstr "" +#: src/other-resources.md +msgid "" +"[Advanced testing for Rust applications](https://rust-exercises.com/advanced-" +"testing/): a self-paced workshop that goes beyond Rust's built-in testing " +"framework. It covers `googletest`, snapshot testing, mocking as well as how " +"to write your own custom test harness." +msgstr "" + #: src/other-resources.md msgid "" "[Beginner's Series to Rust](https://docs.microsoft.com/en-us/shows/beginners-" @@ -19926,6 +34473,12 @@ msgid "" "rules, through implementing a few different types of list structures." msgstr "" +#: src/other-resources.md +msgid "" +"[The Little Book of Rust Macros](https://danielkeep.github.io/tlborm/): " +"covers many details on Rust macros with practical examples." +msgstr "" + #: src/other-resources.md msgid "" "Please see the [Little Book of Rust Books](https://lborb.github.io/book/) " @@ -19946,32 +34499,9 @@ msgid "" "rust/blob/main/LICENSE) for details." msgstr "" -#: src/credits.md -msgid "Rust by Example" -msgstr "āωāĻĻāĻžāĻšāϰāϪ⧇āϰ āĻŽāĻžāĻ§ā§āϝāĻŽā§‡ āϰāĻžāĻ¸ā§āϟ" - -#: src/credits.md -msgid "" -"Some examples and exercises have been copied and adapted from [Rust by " -"Example](https://doc.rust-lang.org/rust-by-example/). Please see the " -"`third_party/rust-by-example/` directory for details, including the license " -"terms." -msgstr "" - -#: src/credits.md -msgid "Rust on Exercism" -msgstr "āĻ…āύ⧁āĻļā§€āϞāύ⧇ āϰāĻžāĻ¸ā§āϟ" - -#: src/credits.md -msgid "" -"Some exercises have been copied and adapted from [Rust on Exercism](https://" -"exercism.org/tracks/rust). Please see the `third_party/rust-on-exercism/` " -"directory for details, including the license terms." -msgstr "" - #: src/credits.md msgid "CXX" -msgstr "CXX" +msgstr "" #: src/credits.md msgid "" @@ -19979,637 +34509,3 @@ msgid "" "uses an image from [CXX](https://cxx.rs/). Please see the `third_party/cxx/` " "directory for details, including the license terms." msgstr "" - -#~ msgid "Much of the Rust syntax will be familiar to you from C, C++ or Java:" -#~ msgstr "" -#~ "C, C++ or Java āĻĨ⧇āϕ⧇ āĻŦ⧇āĻļāĻŋāϰāĻ­āĻžāĻ— āϰāĻžāĻ¸ā§āϟ āϏāĻŋāύāĻŸā§āϝāĻžāĻ•ā§āϏ āφāĻĒāύāĻžāϰ āĻ•āĻžāϛ⧇ āĻĒāϰāĻŋāϚāĻŋāϤ āĻŽāύ⧇ āĻšāĻŦ⧇āσ" - -#, fuzzy -#~ msgid "\"aarch64-linux-gnu\"" -#~ msgstr "aarch64-paging" - -#, fuzzy -#~ msgid "\"exceptions.S\"" -#~ msgstr "āĻŦā§āϝāϤāĻŋāĻ•ā§āϰāĻŽ" - -#, fuzzy -#~ msgid "aarch64-linux-gnu" -#~ msgstr "aarch64-paging" - -#~ msgid "Small Example" -#~ msgstr "āϛ⧋āĻŸā§āϟ āωāĻĻāĻžāĻšāϰāĻŖ" - -#~ msgid "Why Rust?" -#~ msgstr "Rust āϕ⧇āύ⧋?" - -#~ msgid "Compile Time Guarantees" -#~ msgstr "āĻ•āĻŽā§āĻĒāĻžāχāϞ āϏāĻŽāϝāĻŧ⧇āϰ āĻ—ā§āϝāĻžāϰāĻžāĻ¨ā§āϟāĻŋ" - -#~ msgid "Runtime Guarantees" -#~ msgstr "āϰāĻžāύāϟāĻžāχāĻŽ āĻ—ā§āϝāϰāĻžāĻ¨ā§āϟāĻŋ" - -#~ msgid "Modern Features" -#~ msgstr "āφāϧ⧁āύāĻŋāĻ• āϏ⧁āĻŦāĻŋāϧāĻžāϏāĻŽā§‚āĻš" - -#~ msgid "Basic Syntax" -#~ msgstr "āĻŽā§ŒāϞāĻŋāĻ• āϏāĻŋāύāĻŸā§āϝāĻžāĻ•ā§āϏ" - -#~ msgid "String vs str" -#~ msgstr "String āĻŦāύāĻžāĻŽ str" - -#~ msgid "Overloading" -#~ msgstr "āĻ…āĻ­āĻžāϰāϞ⧋āĻĄāĻŋāĻ‚" - -#~ msgid "Arrays and for Loops" -#~ msgstr "Arrays āĻāĻŦāĻ‚ for-Loops" - -#~ msgid "for expressions" -#~ msgstr "for āĻāĻ•ā§āϏāĻĒā§āϰ⧇āĻļāύ" - -#~ msgid "while expressions" -#~ msgstr "while āĻāĻ•ā§āϏāĻĒā§āϰ⧇āĻļāύ" - -#~ msgid "break & continue" -#~ msgstr "break & continue" - -#~ msgid "loop expressions" -#~ msgstr "loop āĻāĻ•ā§āϏāĻĒā§āϰ⧇āĻļāύ" - -#~ msgid "Variant Payloads" -#~ msgstr "āĻ­āĻŋāĻ¨ā§āύ Payloads" - -#~ msgid "Enum Sizes" -#~ msgstr "Enum āĻāϰ āĻŽāĻžāĻĒ" - -#~ msgid "Novel Control Flow" -#~ msgstr "āύāϭ⧇āϞ āĻ•āĻ¨ā§āĻŸā§āϰ⧋āϞ āĻĢā§āϞ⧋" - -#~ msgid "if let expressions" -#~ msgstr "if let āĻāĻ•ā§āϏāĻĒā§āϰ⧇āĻļāύ" - -#~ msgid "while let expressions" -#~ msgstr "while let āĻāĻ•ā§āϏāĻĒā§āϰ⧇āĻļāύ" - -#~ msgid "match expressions" -#~ msgstr "match āĻāĻ•ā§āϏāĻĒā§āϰ⧇āĻļāύ" - -#~ msgid "Destructuring Structs" -#~ msgstr "Structs āĻĄāĻŋāĻ¸ā§āĻŸā§āϰāĻžāĻ•āϚāĻžāϰ " - -#~ msgid "Destructuring Arrays" -#~ msgstr "Arrays āĻĄāĻŋāĻ¸ā§āĻŸā§āϰāĻžāĻ•āϚāĻžāϰ " - -#~ msgid "Match Guards" -#~ msgstr "Match Guards" - -#~ msgid "Pattern Matching (TBD)" -#~ msgstr "āĻĒā§āϝāĻžāϟāĻžāĻ°ā§āύ āĻŽā§āϝāĻžāϚāĻŋāĻ‚ (TBD)" - -#~ msgid "Stack vs Heap" -#~ msgstr "Stack āĻŦāύāĻžāĻŽ Heap" - -#~ msgid "Stack Memory" -#~ msgstr "Stack āĻŽā§‡āĻŽā§‹āϰāĻŋ" - -#~ msgid "Manual Memory Management" -#~ msgstr "āĻŽā§āϝāĻžāύ⧁āϝāĻŧāĻžāϞ āĻŽā§‡āĻŽā§‹āϰāĻŋ āĻŦā§āϝāĻŦāĻ¸ā§āĻĨāĻžāĻĒāύāĻž" - -#~ msgid "Scope-Based Memory Management" -#~ msgstr "āĻ¸ā§āϕ⧋āĻĒ āĻ­āĻŋāĻ¤ā§āϤāĻŋāĻ• āĻŽā§‡āĻŽā§‹āϰāĻŋ āĻŦā§āϝāĻŦāĻ¸ā§āĻĨāĻžāĻĒāύāĻž" - -#~ msgid "Comparison" -#~ msgstr "āϤ⧁āϞāύāĻž" - -#~ msgid "Copying and Cloning" -#~ msgstr "āĻ…āύ⧁āϞāĻŋāĻĒāĻŋ āĻāĻŦāĻ‚ āĻ•ā§āϞ⧋āύāĻŋāĻ‚" - -#~ msgid "Shared and Unique Borrows" -#~ msgstr "āĻ­āĻžāĻ— āĻ•āϰāĻž āϧāĻžāϰ āĻāĻŦāĻ‚ āĻ…āύāĻ¨ā§āϝ āϧāĻžāϰ" - -#~ msgid "Storing Books" -#~ msgstr "āĻŦāχ āϏāĻ‚āϰāĻ•ā§āώāĻŖ āĻ•āϰāĻž" - -#~ msgid "Field Shorthand Syntax" -#~ msgstr "Field Shorthand Syntax" - -#~ msgid "Method Receiver" -#~ msgstr "Method Receiver" - -#~ msgid "Option and Result" -#~ msgstr "Option āĻāĻŦāĻ‚ Result" - -#~ msgid "Vec" -#~ msgstr "Vec" - -#~ msgid "HashMap" -#~ msgstr "HashMap" - -#~ msgid "Box" -#~ msgstr "Box" - -#~ msgid "Recursive Data Types" -#~ msgstr "āϰāĻŋāĻ•āĻžāĻ°ā§āϏāĻŋāĻ­ āĻĄā§‡āϟāĻž āϟāĻžāχāĻĒ" - -#~ msgid "Rc" -#~ msgstr "Rc" - -#~ msgid "Strings and Iterators" -#~ msgstr "Strings āĻāĻŦāĻ‚ Iterators" - -#~ msgid "Generic Methods" -#~ msgstr "āĻœā§‡āύ⧇āϰāĻŋāĻ• āĻŽā§‡āĻĨāĻĄ-āϏāĻŽā§‚āĻš" - -#~ msgid "Monomorphization" -#~ msgstr "Monomorphization" - -#~ msgid "Default Methods" -#~ msgstr "āĻĄāĻŋāĻĢāĻ˛ā§āϟ āĻŽā§‡āĻĨāĻĄ-āϏāĻŽā§‚āĻš" - -#~ msgid "impl Trait" -#~ msgstr "impl Trait" - -#~ msgid "Important Traits" -#~ msgstr "āϗ⧁āϰ⧁āĻ¤ā§āĻŦāĻĒā§‚āĻ°ā§āĻŖ Traits" - -#~ msgid "From and Into" -#~ msgstr "From āĻāĻŦāĻ‚ Into" - -#~ msgid "Default" -#~ msgstr "Default" - -#~ msgid "Operators: Add, Mul, ..." -#~ msgstr "āĻ…āĻĒāĻžāϰ⧇āϟāϰāσ Add, Mul, ..." - -#~ msgid "Closures: Fn, FnMut, FnOnce" -#~ msgstr "Closures: Fn, FnMut, FnOnce" - -#~ msgid "A Simple GUI Library" -#~ msgstr "āĻāĻ•āϟāĻŋ āϏāĻžāϧāĻžāϰāĻŖ GUI āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋ" - -#~ msgid "Points and Polygons" -#~ msgstr "Points and Polygons" - -#~ msgid "Catching Stack Unwinding" -#~ msgstr "Catching Stack Unwinding" - -#~ msgid "Structured Error Handling" -#~ msgstr "āĻ¸ā§āĻŸā§āϰāĻžāĻ•āϚāĻžāĻ°ā§āĻĄ āĻāϰāϰ āĻšā§āϝāĻžāĻ¨ā§āĻĄāϞāĻŋāĻ‚" - -#~ msgid "Propagating Errors with ?" -#~ msgstr "āĻāϰ āϏāĻžāĻšāĻžāĻ¯ā§āϝ⧇ āĻāϰāϰ/āĻ¤ā§āϰ⧁āϟāĻŋ āĻšāĻ¸ā§āϤāĻžāĻ¨ā§āϤāϰ āĻ•āϰāĻž ?" - -#~ msgid "Converting Error Types" -#~ msgstr "āĻāϰāϰ⧇āϰ āϟāĻžāχāĻĒ āϰ⧂āĻĒāĻžāĻ¨ā§āϤāϰ" - -#~ msgid "Deriving Error Enums" -#~ msgstr "āĻāϰāϰ⧇āϰ āχāύāĻžāĻŽāϗ⧁āϞ⧋ āĻŦ⧇āϰ āĻ•āϰāĻž" - -#~ msgid "Adding Context to Errors" -#~ msgstr "āĻ¤ā§āϰ⧁āϟāĻŋāϤ⧇ āĻ•āĻ¨ā§āĻŸā§‡āĻ•ā§āϏāϟ āϝ⧋āĻ— āĻ•āϰāĻž" - -#~ msgid "no_std" -#~ msgstr "no_std" - -#~ msgid "alloc" -#~ msgstr "alloc" - -#~ msgid "zerocopy" -#~ msgstr "zerocopy" - -#~ msgid "buddy_system_allocator" -#~ msgstr "buddy_system_allocator" - -#~ msgid "tinyvec" -#~ msgstr "tinyvec" - -#~ msgid "spin" -#~ msgstr "spin" - -#~ msgid "Send and Sync" -#~ msgstr "Send āĻāĻŦāĻ‚ Sync" - -#~ msgid "Send" -#~ msgstr "Send" - -#~ msgid "Sync" -#~ msgstr "Sync" - -#~ msgid "Arc" -#~ msgstr "Arc" - -#~ msgid "Mutex" -#~ msgstr "Mutex" - -#~ msgid "async/await" -#~ msgstr "async/await" - -#~ msgid "Pin" -#~ msgstr "Pin" - -#~ msgid "Day 1 Morning" -#~ msgstr "āĻĒā§āϰāĻĨāĻŽ āĻĻāĻŋāύāσ āϏāĻ•āĻžāϞ" - -#~ msgid "Day 1 Afternoon" -#~ msgstr "āĻĒā§āϰāĻĨāĻŽ āĻĻāĻŋāύāσ āĻŦāĻŋāĻ•āĻžāϞ" - -#~ msgid "Day 2 Morning" -#~ msgstr "āĻĻā§āĻŦāĻŋāϤ⧀āϝāĻŧ āĻĻāĻŋāύāσ āϏāĻ•āĻžāϞ" - -#~ msgid "Day 2 Afternoon" -#~ msgstr "āĻĻā§āĻŦāĻŋāϤ⧀āϝāĻŧ āĻĻāĻŋāύāσ āĻŦāĻŋāĻ•āĻžāϞ" - -#~ msgid "Day 3 Morning" -#~ msgstr "āϤ⧃āϤ⧀āϝāĻŧ āĻĻāĻŋāύāσ āϏāĻ•āĻžāϞ" - -#~ msgid "Day 3 Afternoon" -#~ msgstr "āϤ⧃āϤ⧀āϝāĻŧ āĻĻāĻŋāύāσ āĻŦāĻŋāĻ•āĻžāϞ" - -#~ msgid "Bare Metal Rust Morning" -#~ msgstr "Bare Metal Rust: āϏāĻ•āĻžāϞ" - -#~ msgid "Concurrency Morning" -#~ msgstr "Concurrency: āĻŦāĻŋāĻ•āĻžāϞ" - -#~ msgid "Concurrency Afternoon" -#~ msgstr "Concurrency: āĻŦāĻŋāĻ•āĻžāϞ" - -#~ msgid "The course is fast paced and covers a lot of ground:" -#~ msgstr "āϕ⧋āĻ°ā§āϏāϟāĻŋ āĻĻā§āϰ⧁āϤ āĻ—āϤāĻŋāϰ āĻāĻŦāĻ‚ āĻ…āύ⧇āĻ• āĻ•āĻŋāϛ⧁ āĻ•āĻ­āĻžāϰ āĻ•āϰ⧇āσ" - -#~ msgid "" -#~ "Day 2: Memory management, ownership, compound data types, and the " -#~ "standard library." -#~ msgstr "" -#~ "āĻĻā§āĻŦāĻŋāϤ⧀āϝāĻŧ āĻĻāĻŋāύāσ āĻŽā§‡āĻŽā§‹āϰāĻŋ āĻŽā§āϝāĻžāύ⧇āϜāĻŽā§‡āĻ¨ā§āϟ, āĻŽāĻžāϞāĻŋāĻ•āĻžāύāĻž, āĻ•āĻŽā§āĻĒāĻžāωāĻ¨ā§āĻĄ āĻĄā§‡āϟāĻž āϟāĻžāχāĻĒāϏ, āĻāĻŦāĻ‚ āĻĻāĻŋ " -#~ "āĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄ āϞāĻžāχāĻŦā§āϰ⧇āϰāĻŋāĨ¤" - -#~ msgid "Day 3: Generics, traits, error handling, testing, and unsafe Rust." -#~ msgstr "" -#~ "āϤ⧃āϤ⧀āϝāĻŧ āĻĻāĻŋāύāσ Traits āĻāĻŦāĻ‚ Generics, āĻāϰāϰ āĻšā§āϝāĻžāĻ¨ā§āĻĄāϞāĻŋāĻ‚, āĻŸā§‡āĻ¸ā§āϟāĻŋāĻ‚, āĻāĻŦāĻ‚ āĻ…āύāĻŋāϰāĻžāĻĒāĻĻ āϰāĻžāĻ¸ā§āϟāĨ¤" - -#~ msgid "" -#~ "```shell\n" -#~ "cargo init concurrency\n" -#~ "cd concurrency\n" -#~ "cargo add tokio --features full\n" -#~ "cargo run\n" -#~ "```" -#~ msgstr "" -#~ "```shell\n" -#~ "cargo init concurrency\n" -#~ "cd concurrency\n" -#~ "cargo add tokio --features full\n" -#~ "cargo run\n" -#~ "```" - -#~ msgid "" -#~ "```shell\n" -#~ "sudo apt install cargo rust-src rustfmt\n" -#~ "```" -#~ msgstr "" -#~ "```shell\n" -#~ "sudo apt install cargo rust-src rustfmt\n" -#~ "```" - -#, fuzzy -#~ msgid "" -#~ "We suggest using [VS Code](https://code.visualstudio.com/) to edit the " -#~ "code (but any LSP compatible editor works with rust-analyzer[3](https://" -#~ "rust-analyzer.github.io/))." -#~ msgstr "" -#~ "āĻāϟāĻŋ \\[rust-analyzer\\] \\[1\\] āϕ⧇ āϏāĻ‚āĻœā§āĻžāĻžāϝāĻŧ āϝ⧇āϤ⧇ āĻ…āύ⧁āĻŽāϤāĻŋ āĻĻ⧇āĻŦ⧇āĨ¤ āφāĻŽāϰāĻž āĻŦā§āϝāĻŦāĻšāĻžāϰ " -#~ "āĻ•āϰāĻžāϰ āĻĒāϰāĻžāĻŽāĻ°ā§āĻļ āĻĻāĻŋāχ [VS Code](https://code.visualstudio.com/) āϕ⧋āĻĄ āĻāĻĄāĻŋāϟ āĻ•āϰāϤ⧇ " -#~ "(āĻ•āĻŋāĻ¨ā§āϤ⧁ āϝ⧇āϕ⧋āύ⧋ LSP āϏāĻžāĻŽāĻžā§āϜāĻ¸ā§āϝāĻĒā§‚āĻ°ā§āĻŖ āĻāĻĄāĻŋāϟāϰ āĻ•āĻžāϜ āĻ•āϰ⧇)āĨ¤" - -#~ msgid "" -#~ "Some folks also like to use the [JetBrains](https://www.jetbrains.com/" -#~ "clion/) family of IDEs, which do their own analysis but have their own " -#~ "tradeoffs. If you prefer them, you can install the [Rust Plugin](https://" -#~ "www.jetbrains.com/rust/). Please take note that as of January 2023 " -#~ "debugging only works on the CLion version of the JetBrains IDEA suite." -#~ msgstr "" -#~ "āĻ•āĻŋāϛ⧁ āϞ⧋āĻ• IDE-āĻāϰ āϜāĻ¨ā§āϝ [JetBrains](https://www.jetbrains.com/clion/) āĻŦā§āϝāĻŦāĻšāĻžāϰ " -#~ "āĻ•āϰāϤ⧇ āĻĒāĻ›āĻ¨ā§āĻĻ āĻ•āϰ⧇, āϝāĻžāϰāĻž āϤāĻžāĻĻ⧇āϰ āύāĻŋāϜāĻ¸ā§āĻŦ āĻŦāĻŋāĻļā§āϞ⧇āώāϪ⧇ āĻ•āϰ⧇ āĻ•āĻŋāĻ¨ā§āϤ⧁ āϤāĻžāĻĻ⧇āϰ āύāĻŋāϜāĻ¸ā§āĻŦ āĻŸā§āϰ⧇āĻĄāĻ…āĻĢ " -#~ "āϰāϝāĻŧ⧇āϛ⧇āĨ¤ āφāĻĒāύāĻŋ āϝāĻĻāĻŋ āϤāĻžāĻĻ⧇āϰ āĻĒāĻ›āĻ¨ā§āĻĻ āĻ•āϰ⧇āύ āϤāĻŦ⧇ āφāĻĒāύāĻŋ [Rust Plugin](https://www." -#~ "jetbrains.com/rust/) āχāύāĻ¸ā§āϟāϞ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤ āĻ…āύ⧁āĻ—ā§āϰāĻš āĻ•āϰ⧇ āĻŽāύ⧇ āϰāĻžāĻ–āĻŦ⧇āύ āϝ⧇ āϜāĻžāύ⧁āϝāĻŧāĻžāϰ⧀ " -#~ "2023 āĻ…āύ⧁āϝāĻžāϝāĻŧā§€ āĻĄāĻŋāĻŦāĻžāĻ—āĻŋāĻ‚ āĻļ⧁āϧ⧁āĻŽāĻžāĻ¤ā§āϰ JetBrains IDEA āĻ¸ā§āϝ⧁āĻŸā§‡āϰ CLion āϏāĻ‚āĻ¸ā§āĻ•āϰāϪ⧇ āĻ•āĻžāϜ āĻ•āϰ⧇āĨ¤" - -#~ msgid "" -#~ "```rust,editable\n" -#~ "fn main() {\n" -#~ " println!(\"Edit me!\");\n" -#~ "}\n" -#~ "```" -#~ msgstr "" -#~ "```rust,editable\n" -#~ "fn main() {\n" -#~ " println!(\"Edit me!\");\n" -#~ "}\n" -#~ "```" - -#, fuzzy -#~ msgid "" -#~ "```shell\n" -#~ "% rustc --version\n" -#~ "rustc 1.69.0 (84c898d65 2023-04-16)\n" -#~ "% cargo --version\n" -#~ "cargo 1.69.0 (6e9a83356 2023-04-12)\n" -#~ "```" -#~ msgstr "" -#~ "```shell\n" -#~ "% rustc --version\n" -#~ "rustc 1.61.0 (fe5b13d68 2022-05-18)\n" -#~ "% cargo --version\n" -#~ "cargo 1.61.0 (a028ae4 2022-04-29)\n" -#~ "```" - -#~ msgid "" -#~ "If you're teaching this in a classroom, this is a good place to go over " -#~ "the schedule. We suggest splitting the day into two parts (following the " -#~ "slides):" -#~ msgstr "" -#~ "āϝāĻĻāĻŋ āφāĻĒāύāĻŋ āĻāϟāĻŋ āĻāĻ•āϟāĻŋ āĻļā§āϰ⧇āύ⧀āĻ•āĻ•ā§āώ⧇ āĻĒāĻĄāĻŧāĻžāĻšā§āϛ⧇āύ, āĻāϟāĻŋ āĻāĻ•āϟāĻŋ āĻ­āĻžāϞ⧋ āϝāĻžāϝāĻŧāĻ—āĻž āύāĻŋāϝāĻŧāĻŽāĻŽāĻžāĻĢāĻŋāĻ• āϚāϞāĻžāϰ " -#~ "āϜāĻ¨ā§āϝāĨ¤ āφāĻŽāϰāĻž āĻĒāϰāĻžāĻŽāĻ°ā§āĻļ āĻĻāĻŋāχ āϝ⧇ āĻĻāĻŋāύāϟāĻžāϕ⧇ āĻĻ⧁āχāϟāĻž āĻ­āĻžāϗ⧇ āĻ­āĻžāĻ— āĻ•āϰ⧁āύ(āĻ¸ā§āϞāĻžāχāĻĄāϗ⧁āϞ⧋āϕ⧇ āĻ…āύ⧁āϏāϰāύ āĻ•āϰ⧇):" - -#~ msgid "Morning: 9:00 to 12:00," -#~ msgstr "āϏāĻ•āĻžāϞāσ ⧝:ā§Ļā§Ļ āĻĨ⧇āϕ⧇ ⧧⧍:ā§Ļā§Ļ," - -#~ msgid "Afternoon: 13:00 to 16:00." -#~ msgstr "āĻŦāĻŋāĻ•āĻžāϞ ā§§:ā§Ļā§Ļ āĻĨ⧇āϕ⧇ ā§Ē:ā§Ļā§Ļ." - -#~ msgid "" -#~ "You can of course adjust this as necessary. Please make sure to include " -#~ "breaks, we recommend a break every hour!" -#~ msgstr "" -#~ "āφāĻĒāύāĻŋ āĻ…āĻŦāĻļā§āϝāχ āĻāϟāĻŋ āĻĒā§āϰāϝāĻŧā§‹āϜāύ āĻ…āύ⧁āϏāĻžāϰ⧇ āĻĒāϰāĻŋāĻŦāĻ°ā§āϤāύ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤ āĻ…āύ⧁āĻ—ā§āϰāĻš āĻ•āϰ⧇ āύāĻŋāĻļā§āϚāĻŋāϤ āĻ•āϰ⧁āύ " -#~ "āĻŦāĻŋāϰāϤāĻŋ āύāĻŋāϤ⧇, āφāĻŽāϰāĻž āĻĒāϰāĻžāĻŽāĻ°ā§āĻļ āĻĻāĻŋāχ āĻĒā§āϰāϤāĻŋ āϘāĻ¨ā§āϟāĻžāϝāĻŧ āĻāĻ•āĻŦāĻžāϰ āĻŦāĻŋāϰāϤāĻŋ āύāĻŋāϤ⧇!" - -#~ msgid "" -#~ "```rust,editable\n" -#~ "fn main() {\n" -#~ " println!(\"Hello 🌍!\");\n" -#~ "}\n" -#~ "```" -#~ msgstr "" -#~ "```rust,editable\n" -#~ "fn main() {\n" -#~ " println!(\"Hello 🌍!\");\n" -#~ "}\n" -#~ "```" - -#~ msgid "Here is a small example program in Rust:" -#~ msgstr "āĻāϟāĻŋ āĻāĻ•āϟāĻŋ āϛ⧋āϟ āωāĻĻāĻžāĻšāϰāĻŖ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽ Rust āĻ:" - -#~ msgid "" -#~ "```rust,editable\n" -#~ "fn main() { // Program entry point\n" -#~ " let mut x: i32 = 6; // Mutable variable binding\n" -#~ " print!(\"{x}\"); // Macro for printing, like printf\n" -#~ " while x != 1 { // No parenthesis around expression\n" -#~ " if x % 2 == 0 { // Math like in other languages\n" -#~ " x = x / 2;\n" -#~ " } else {\n" -#~ " x = 3 * x + 1;\n" -#~ " }\n" -#~ " print!(\" -> {x}\");\n" -#~ " }\n" -#~ " println!();\n" -#~ "}\n" -#~ "```" -#~ msgstr "" -#~ "```rust,editable\n" -#~ "fn main() { // Program entry point\n" -#~ " let mut x: i32 = 6; // Mutable variable binding\n" -#~ " print!(\"{x}\"); // Macro for printing, like printf\n" -#~ " while x != 1 { // No parenthesis around expression\n" -#~ " if x % 2 == 0 { // Math like in other languages\n" -#~ " x = x / 2;\n" -#~ " } else {\n" -#~ " x = 3 * x + 1;\n" -#~ " }\n" -#~ " print!(\" -> {x}\");\n" -#~ " }\n" -#~ " println!();\n" -#~ "}\n" -#~ "```" - -#, fuzzy -#~ msgid "Rust is built with all the experience gained in the last decades." -#~ msgstr "āĻ—āϤ 40 āĻŦāĻ›āϰ⧇ āĻ…āĻ°ā§āϜāĻŋāϤ āϏāĻŽāĻ¸ā§āϤ āĻ…āĻ­āĻŋāĻœā§āĻžāϤāĻž āĻĻāĻŋāϝāĻŧ⧇ Rust āϤ⧈āϰāĻŋ āĻ•āϰāĻž āĻšāϝāĻŧ⧇āϛ⧇āĨ¤" - -#~ msgid "Language Features" -#~ msgstr "āĻ­āĻžāώāĻžāϰ āĻŦ⧈āĻļāĻŋāĻˇā§āĻŸā§āϝāϏāĻŽā§‚āĻš" - -#~ msgid "Tooling" -#~ msgstr "Tooling" - -#~ msgid "`\"foo\"`, `\"two\\nlines\"`" -#~ msgstr "`\"foo\"`, `\"two\\nlines\"`" - -#~ msgid "" -#~ "```rust,editable\n" -#~ "fn main() {\n" -#~ " println!(r#\"link\"#);\n" -#~ " println!(\"link\");\n" -#~ "}\n" -#~ "```" -#~ msgstr "" -#~ "```rust,editable\n" -#~ "fn main() {\n" -#~ " println!(r#\"link\"#);\n" -#~ " println!(\"link\");\n" -#~ "}\n" -#~ "```" - -#~ msgid "" -#~ "```rust,editable\n" -#~ "fn main() {\n" -#~ " println!(\"{:?}\", b\"abc\");\n" -#~ " println!(\"{:?}\", &[97, 98, 99]);\n" -#~ "}\n" -#~ "```" -#~ msgstr "" -#~ "```rust,editable\n" -#~ "fn main() {\n" -#~ " println!(\"{:?}\", b\"abc\");\n" -#~ " println!(\"{:?}\", &[97, 98, 99]);\n" -#~ "}\n" -#~ "```" - -#~ msgid "" -#~ "```rust,editable\n" -#~ "fn main() {\n" -#~ " let mut a: [i8; 10] = [42; 10];\n" -#~ " a[5] = 0;\n" -#~ " println!(\"a: {:?}\", a);\n" -#~ "}\n" -#~ "```" -#~ msgstr "" -#~ "```rust,editable\n" -#~ "fn main() {\n" -#~ " let mut a: [i8; 10] = [42; 10];\n" -#~ " a[5] = 0;\n" -#~ " println!(\"a: {:?}\", a);\n" -#~ "}\n" -#~ "```" - -#~ msgid "Like C++, Rust has references:" -#~ msgstr "C++ āĻāϰ āĻŽāϤ⧋, Rust āĻāϰ āĻ“ references āφāϛ⧇" - -#, fuzzy -#~ msgid "" -#~ "```rust,editable\n" -#~ "fn main() {\n" -#~ " let mut a: [i32; 6] = [10, 20, 30, 40, 50, 60];\n" -#~ " println!(\"a: {a:?}\");\n" -#~ "\n" -#~ " let s: &[i32] = &a[2..4];\n" -#~ "\n" -#~ " println!(\"s: {s:?}\");\n" -#~ "}\n" -#~ "```" -#~ msgstr "" -#~ "```rust,editable\n" -#~ "fn main() {\n" -#~ " let mut a: [i8; 10] = [42; 10];\n" -#~ " a[5] = 0;\n" -#~ " println!(\"a: {:?}\", a);\n" -#~ "}\n" -#~ "```" - -#~ msgid "Day 1: Morning Exercises" -#~ msgstr "āĻĒā§āϰāĻĨāĻŽ āĻĻāĻŋāύāσ āϏāĻ•āĻžāϞ⧇āϰ āĻ…āύ⧁āĻļā§€āϞāύ" - -#, fuzzy -#~ msgid "The Luhn algorithm," -#~ msgstr "āϞ⧁āύ āĻ…ā§āϝāĻžāϞāĻ—āϰāĻŋāĻĻāĻŽ" - -#, fuzzy -#~ msgid "An exercise on pattern matching." -#~ msgstr "Enums and pattern matching." - -#, fuzzy -#~ msgid "Structs and methods." -#~ msgstr "Strings āĻāĻŦāĻ‚ Iterators" - -#, fuzzy -#~ msgid "Stack and Heap Example" -#~ msgstr "Stack āĻŦāύāĻžāĻŽ Heap" - -#~ msgid "You allocate and deallocate heap memory yourself." -#~ msgstr "āφāĻĒāύāĻŋ āύāĻŋāĻœā§‡āχ heap-memory āĻāϞ⧋āϕ⧇āϟ āĻāĻŦāĻ‚ āĻĄāĻŋ-āĻāϞ⧋āϕ⧇āϟ āĻ•āϰ⧁āύāĨ¤" - -#~ msgid "C Example" -#~ msgstr "C āωāĻĻāĻžāĻšāϰāĻŖ" - -#, fuzzy -#~ msgid "Extra Work in Modern C++" -#~ msgstr "āφāϧ⧁āύāĻŋāĻ• C++ āĻ āĻĄāĻŦāϞ āĻŽā§āĻ•ā§āϤ" - -#~ msgid "Day 2: Morning Exercises" -#~ msgstr "āĻĻā§āĻŦāĻŋāϤ⧀āϝāĻŧ āĻĻāĻŋāύāσ āϏāĻ•āĻžāϞ⧇āϰ āĻ…āύ⧁āĻļāĻŋāϞāύ" - -#~ msgid "Day 3: Morning Exercises" -#~ msgstr "āϤ⧃āϤ⧀āϝāĻŧ āĻĻāĻŋāύāσ āϏāĻ•āĻžāϞ⧇āϰ āĻ…āύ⧁āĻļā§€āϞāύ" - -#, fuzzy -#~ msgid "" -#~ "```shell\n" -#~ "adb logcat -s rust\n" -#~ "```" -#~ msgstr "" -#~ "```shell\n" -#~ "$ sudo apt install cargo rust-src rustfmt\n" -#~ "```" - -#, fuzzy -#~ msgid "" -#~ "```shell\n" -#~ "cargo new link-checker\n" -#~ "cd link-checker\n" -#~ "cargo add --features blocking,rustls-tls reqwest\n" -#~ "```" -#~ msgstr "" -#~ "```shell\n" -#~ "cargo init concurrency\n" -#~ "cd concurrency\n" -#~ "cargo add tokio --features full\n" -#~ "cargo run\n" -#~ "```" - -#~ msgid "You will find solutions to the exercises on the following pages." -#~ msgstr "āφāĻĒāύāĻŋ āĻ…āύ⧁āĻļā§€āϞāύ⧀āϰ āϏāĻŽāĻžāϧāĻžāύ āĻāχ āĻĒ⧃āĻˇā§āĻ āĻžāϗ⧁āϞ⧋āϤ⧇ āϖ⧁āĻœā§‡ āĻĒāĻžāĻŦ⧇āύāĨ¤" - -#~ msgid "Day 1 Morning Exercises" -#~ msgstr "āĻĒā§āϰāĻĨāĻŽ āĻĻāĻŋāύāσ āϏāĻ•āĻžāϞ⧇āϰ āĻ…āύ⧁āĻļā§€āϞāύ" - -#, fuzzy -#~ msgid "Pattern matching" -#~ msgstr "āĻĒā§āϝāĻžāϟāĻžāĻ°ā§āύ āĻŽāĻŋāϞāĻžāύ⧋" - -#~ msgid "Elevator Operations" -#~ msgstr "āϞāĻŋāĻĢāϟ āĻ…āĻĒāĻžāϰ⧇āĻļāύ" - -#~ msgid "" -#~ "[![Build workflow](https://img.shields.io/github/actions/workflow/status/" -#~ "google/comprehensive-rust/build.yml?style=flat-square)](https://github." -#~ "com/google/comprehensive-rust/actions/workflows/build.yml)" -#~ msgstr "" -#~ "[![Build workflow](https://img.shields.io/github/actions/workflow/status/" -#~ "google/comprehensive-rust/build.yml?style=flat-square)](https://github." -#~ "com/google/comprehensive-rust/actions/workflows/build.yml)" - -#~ msgid "Build workflow" -#~ msgstr "āĻ•āĻ°ā§āĻŽāĻĒā§āϰāĻŦāĻžāĻš āϤ⧈āϰāĻŋ" - -#~ msgid "GitHub contributors" -#~ msgstr "GitHub āĻ…āĻŦāĻĻāĻžāύāĻ•āĻžāϰ⧀" - -#~ msgid "" -#~ "[![GitHub contributors](https://img.shields.io/github/contributors/google/" -#~ "comprehensive-rust?style=flat-square)](https://github.com/google/" -#~ "comprehensive-rust/graphs/contributors) [![GitHub stars](https://img." -#~ "shields.io/github/stars/google/comprehensive-rust?style=flat-square)]" -#~ "(https://github.com/google/comprehensive-rust/stargazers)" -#~ msgstr "" -#~ "[![GitHub contributors](https://img.shields.io/github/contributors/google/" -#~ "comprehensive-rust?style=flat-square)](https://github.com/google/" -#~ "comprehensive-rust/graphs/contributors) [![GitHub stars](https://img." -#~ "shields.io/github/stars/google/comprehensive-rust?style=flat-square)]" -#~ "(https://github.com/google/comprehensive-rust/stargazers)" - -#~ msgid "GitHub stars" -#~ msgstr "GitHub stars" - -#~ msgid "" -#~ "[![GitHub stars](https://img.shields.io/github/stars/google/comprehensive-" -#~ "rust?style=flat-square)](https://github.com/google/comprehensive-rust/" -#~ "stargazers)" -#~ msgstr "" -#~ "[![GitHub stars](https://img.shields.io/github/stars/google/comprehensive-" -#~ "rust?style=flat-square)](https://github.com/google/comprehensive-rust/" -#~ "stargazers)" - -#~ msgid "Day 1: Basic Rust, ownership and the borrow checker." -#~ msgstr "āĻĒā§āϰāĻĨāĻŽ āĻĻāĻŋāύāσ āĻĒā§āϰāĻžāĻĨāĻŽāĻŋāĻ• āϰāĻžāĻ¸ā§āϟ, āĻŽāĻžāϞāĻŋāĻ•āĻžāύāĻž āĻāĻŦāĻ‚ āϧāĻžāϰ āĻĒāϰ⧀āĻ•ā§āώāĻ•āĨ¤" - -#~ msgid "Concurrency" -#~ msgstr "Concurrency" - -#~ msgid "Rustup (Recommended)" -#~ msgstr "Rustup (āĻĒā§āϰāĻ¸ā§āϤāĻžāĻŦāĻŋāϤ)" - -#~ msgid "" -#~ "You can follow the instructions to install cargo and rust compiler, among " -#~ "other standard ecosystem tools with the [rustup](https://rust-analyzer." -#~ "github.io/) tool, which is maintained by the Rust Foundation." -#~ msgstr "" -#~ "āϰāĻžāĻ¸ā§āϟ āĻĢāĻžāωāĻ¨ā§āĻĄā§‡āĻļāύ āĻĻā§āĻŦāĻžāϰāĻž āϰāĻ•ā§āώāĻŖāĻžāĻŦ⧇āĻ•ā§āώāĻŖ āĻ•āϰāĻž [rustup](https://rust-analyzer.github." -#~ "io/) āϟ⧁āϞ āϏāĻš āĻ…āĻ¨ā§āϝāĻžāĻ¨ā§āϝ āĻ¸ā§āĻŸā§āϝāĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄ āχāϕ⧋āϏāĻŋāĻ¸ā§āĻŸā§‡āĻŽ āϟ⧁āϞ⧇āϰ āĻŽāĻ§ā§āϝ⧇ āφāĻĒāύāĻŋ Cargo āĻāĻŦāĻ‚ āϰāĻžāĻ¸ā§āϟ " -#~ "āĻ•āĻŽā§āĻĒāĻžāχāϞāĻžāϰ āχāύāĻ¸ā§āϟāϞ āĻ•āϰāĻžāϰ āύāĻŋāĻ°ā§āĻĻ⧇āĻļāĻžāĻŦāϞ⧀ āĻ…āύ⧁āϏāϰāĻŖ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āύāĨ¤" - -#~ msgid "Package Managers" -#~ msgstr "āĻĒā§āϝāĻžāϕ⧇āϜ āĻŽā§āϝāĻžāύ⧇āϜāĻžāϰ" - -#~ msgid "Debian" -#~ msgstr "Debian"