diff --git a/po/es.po b/po/es.po
index 266c75ce0a9..c6f63c59f22 100644
--- a/po/es.po
+++ b/po/es.po
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Project-Id-Version: Comprehensive Rust 🦀\n"
-"POT-Creation-Date: 2023-09-11\n"
+"POT-Creation-Date: 2023-12-02T17:36:47-03:00\n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -12,6 +12,10 @@ msgstr ""
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Poedit 3.4\n"
+#: src/SUMMARY.md:1
+msgid "Summary"
+msgstr ""
+
#: src/SUMMARY.md:4 src/index.md:1
msgid "Welcome to Comprehensive Rust 🦀"
msgstr "Te damos la bienvenida a Comprehensive Rust 🦀"
@@ -52,8 +56,8 @@ msgstr "Ejecutar Cargo a nivel local"
msgid "Day 1: Morning"
msgstr "Día 1: mañana"
-#: src/SUMMARY.md:19 src/SUMMARY.md:79 src/SUMMARY.md:134 src/SUMMARY.md:192
-#: src/SUMMARY.md:218 src/SUMMARY.md:268
+#: src/SUMMARY.md:19 src/SUMMARY.md:80 src/SUMMARY.md:135 src/SUMMARY.md:193
+#: src/SUMMARY.md:219 src/SUMMARY.md:269
msgid "Welcome"
msgstr "Te damos la bienvenida"
@@ -73,66 +77,72 @@ msgstr "Pequeño ejemplo"
msgid "Why Rust?"
msgstr "¿Por qué Rust?"
-#: src/SUMMARY.md:24 src/why-rust/compile-time.md:1
+#: src/SUMMARY.md:24 src/why-rust/an-example-in-c.md:1 src/credits.md:32
+#, fuzzy
+#| msgid "C Example"
+msgid "An Example in C"
+msgstr "Ejemplo en C"
+
+#: src/SUMMARY.md:25 src/why-rust/compile-time.md:1
msgid "Compile Time Guarantees"
msgstr "Garantías en Tiempo de Compilación"
-#: src/SUMMARY.md:25 src/why-rust/runtime.md:1
+#: src/SUMMARY.md:26 src/why-rust/runtime.md:1
msgid "Runtime Guarantees"
msgstr "Garantías en Runtime (Tiempo de Ejecución)"
-#: src/SUMMARY.md:26 src/why-rust/modern.md:1
+#: src/SUMMARY.md:27 src/why-rust/modern.md:1
msgid "Modern Features"
msgstr "Funcionalidades Modernas"
-#: src/SUMMARY.md:27 src/basic-syntax.md:1
+#: src/SUMMARY.md:28 src/basic-syntax.md:1
msgid "Basic Syntax"
msgstr "Sintaxis básica"
-#: src/SUMMARY.md:28 src/basic-syntax/scalar-types.md:1
+#: src/SUMMARY.md:29 src/basic-syntax/scalar-types.md:1
msgid "Scalar Types"
msgstr "Tipos escalares"
-#: src/SUMMARY.md:29 src/basic-syntax/compound-types.md:1
+#: src/SUMMARY.md:30 src/basic-syntax/compound-types.md:1
msgid "Compound Types"
msgstr "Tipos compuestos"
-#: src/SUMMARY.md:30 src/basic-syntax/references.md:1
+#: src/SUMMARY.md:31 src/basic-syntax/references.md:1
msgid "References"
msgstr "Referencias"
-#: src/SUMMARY.md:31 src/basic-syntax/references-dangling.md:1
+#: src/SUMMARY.md:32 src/basic-syntax/references-dangling.md:1
msgid "Dangling References"
msgstr "Referencias colgantes"
-#: src/SUMMARY.md:32 src/basic-syntax/slices.md:1
+#: src/SUMMARY.md:33 src/basic-syntax/slices.md:1
msgid "Slices"
msgstr "Slices"
-#: src/SUMMARY.md:33
+#: src/SUMMARY.md:34
msgid "String vs str"
msgstr "String o str"
-#: src/SUMMARY.md:34 src/basic-syntax/functions.md:1
+#: src/SUMMARY.md:35 src/basic-syntax/functions.md:1
msgid "Functions"
msgstr "Funciones"
-#: src/SUMMARY.md:35 src/basic-syntax/rustdoc.md:1
+#: src/SUMMARY.md:36 src/basic-syntax/rustdoc.md:1
msgid "Rustdoc"
msgstr "Rustdoc"
-#: src/SUMMARY.md:36 src/SUMMARY.md:102 src/basic-syntax/methods.md:1
+#: src/SUMMARY.md:37 src/SUMMARY.md:103 src/basic-syntax/methods.md:1
#: src/methods.md:1
msgid "Methods"
msgstr "Métodos"
-#: src/SUMMARY.md:37
+#: src/SUMMARY.md:38
msgid "Overloading"
msgstr "Sobrecarga"
-#: src/SUMMARY.md:38 src/SUMMARY.md:71 src/SUMMARY.md:105 src/SUMMARY.md:125
-#: src/SUMMARY.md:154 src/SUMMARY.md:184 src/SUMMARY.md:211 src/SUMMARY.md:232
-#: src/SUMMARY.md:260 src/SUMMARY.md:282 src/SUMMARY.md:303
+#: src/SUMMARY.md:39 src/SUMMARY.md:72 src/SUMMARY.md:106 src/SUMMARY.md:126
+#: src/SUMMARY.md:155 src/SUMMARY.md:185 src/SUMMARY.md:212 src/SUMMARY.md:233
+#: src/SUMMARY.md:261 src/SUMMARY.md:283 src/SUMMARY.md:304
#: src/exercises/android/morning.md:1 src/exercises/bare-metal/morning.md:1
#: src/exercises/bare-metal/afternoon.md:1
#: src/exercises/concurrency/morning.md:1
@@ -140,893 +150,896 @@ msgstr "Sobrecarga"
msgid "Exercises"
msgstr "Ejercicios"
-#: src/SUMMARY.md:39 src/exercises/day-1/implicit-conversions.md:1
+#: src/SUMMARY.md:40 src/exercises/day-1/implicit-conversions.md:1
msgid "Implicit Conversions"
msgstr "Conversiones Implícitas"
-#: src/SUMMARY.md:40
+#: src/SUMMARY.md:41
msgid "Arrays and for Loops"
msgstr "Arrays y Loops for"
-#: src/SUMMARY.md:42
+#: src/SUMMARY.md:43
msgid "Day 1: Afternoon"
msgstr "Día 1: Tarde"
-#: src/SUMMARY.md:44 src/SUMMARY.md:295 src/control-flow.md:1
+#: src/SUMMARY.md:45 src/SUMMARY.md:296 src/control-flow.md:1
msgid "Control Flow"
msgstr "Control de Flujo"
-#: src/SUMMARY.md:45 src/control-flow/blocks.md:1
+#: src/SUMMARY.md:46 src/control-flow/blocks.md:1
msgid "Blocks"
msgstr "Bloques"
-#: src/SUMMARY.md:46
+#: src/SUMMARY.md:47
msgid "if expressions"
msgstr "expresiones if"
-#: src/SUMMARY.md:47
+#: src/SUMMARY.md:48
msgid "for expressions"
msgstr "expresiones for"
-#: src/SUMMARY.md:48
+#: src/SUMMARY.md:49
msgid "while expressions"
msgstr "expresiones while"
-#: src/SUMMARY.md:49
+#: src/SUMMARY.md:50
msgid "break & continue"
msgstr "break y continue"
-#: src/SUMMARY.md:50
+#: src/SUMMARY.md:51
msgid "loop expressions"
msgstr "Expresiones loop"
-#: src/SUMMARY.md:52 src/basic-syntax/variables.md:1
+#: src/SUMMARY.md:53 src/basic-syntax/variables.md:1
msgid "Variables"
msgstr "Variables"
-#: src/SUMMARY.md:53 src/basic-syntax/type-inference.md:1
+#: src/SUMMARY.md:54 src/basic-syntax/type-inference.md:1
msgid "Type Inference"
msgstr "Inferencia de tipos"
-#: src/SUMMARY.md:54
-msgid "static & const"
+#: src/SUMMARY.md:55
+#, fuzzy
+#| msgid "static & const"
+msgid "static & const)"
msgstr "static y const"
-#: src/SUMMARY.md:55 src/basic-syntax/scopes-shadowing.md:1
+#: src/SUMMARY.md:56 src/basic-syntax/scopes-shadowing.md:1
msgid "Scopes and Shadowing"
msgstr "Ámbitos y _Shadowing_"
-#: src/SUMMARY.md:56 src/enums.md:1
+#: src/SUMMARY.md:57 src/enums.md:1
msgid "Enums"
msgstr ""
-#: src/SUMMARY.md:57 src/enums/variant-payloads.md:1
+#: src/SUMMARY.md:58 src/enums/variant-payloads.md:1
msgid "Variant Payloads"
msgstr "Payloads Variantes"
-#: src/SUMMARY.md:58 src/enums/sizes.md:1
+#: src/SUMMARY.md:59 src/enums/sizes.md:1
msgid "Enum Sizes"
msgstr "Tamaños de Enum"
-#: src/SUMMARY.md:60 src/control-flow/novel.md:1
+#: src/SUMMARY.md:61 src/control-flow/novel.md:1
#, fuzzy
msgid "Novel Control Flow"
msgstr "Control de Flujo"
-#: src/SUMMARY.md:61
+#: src/SUMMARY.md:62
msgid "if let expressions"
msgstr "expresiones if let"
-#: src/SUMMARY.md:62
+#: src/SUMMARY.md:63
msgid "while let expressions"
msgstr "expresiones while let"
-#: src/SUMMARY.md:63
+#: src/SUMMARY.md:64
msgid "match expressions"
msgstr "expresiones match"
-#: src/SUMMARY.md:65 src/pattern-matching.md:1
+#: src/SUMMARY.md:66 src/SUMMARY.md:74 src/pattern-matching.md:1
msgid "Pattern Matching"
msgstr "Correspondencia de Patrones"
-#: src/SUMMARY.md:66 src/pattern-matching/destructuring-enums.md:1
+#: src/SUMMARY.md:67 src/pattern-matching/destructuring-enums.md:1
msgid "Destructuring Enums"
msgstr "Desestructurando Enums"
-#: src/SUMMARY.md:67 src/pattern-matching/destructuring-structs.md:1
+#: src/SUMMARY.md:68 src/pattern-matching/destructuring-structs.md:1
msgid "Destructuring Structs"
msgstr "Desestructurando Structs"
-#: src/SUMMARY.md:68 src/pattern-matching/destructuring-arrays.md:1
+#: src/SUMMARY.md:69 src/pattern-matching/destructuring-arrays.md:1
msgid "Destructuring Arrays"
msgstr "Desestructurando Arrays"
-#: src/SUMMARY.md:69 src/pattern-matching/match-guards.md:1
+#: src/SUMMARY.md:70 src/pattern-matching/match-guards.md:1
msgid "Match Guards"
msgstr "Guardas de Match"
-#: src/SUMMARY.md:72 src/exercises/day-1/luhn.md:1
+#: src/SUMMARY.md:73 src/exercises/day-1/luhn.md:1
#: src/exercises/day-1/solutions-afternoon.md:3
msgid "Luhn Algorithm"
msgstr "Algoritmo de Luhn"
-#: src/SUMMARY.md:73
-#, fuzzy
-msgid "Pattern Matching (TBD)"
-msgstr "Correspondencia de Patrones"
-
-#: src/SUMMARY.md:75
+#: src/SUMMARY.md:76
msgid "Day 2: Morning"
msgstr "Día 2: Mañana"
-#: src/SUMMARY.md:81 src/memory-management.md:1
+#: src/SUMMARY.md:82 src/memory-management.md:1
msgid "Memory Management"
msgstr "Manejo de Memoria"
-#: src/SUMMARY.md:82
+#: src/SUMMARY.md:83
msgid "Stack vs Heap"
msgstr ""
-#: src/SUMMARY.md:83
+#: src/SUMMARY.md:84
msgid "Stack Memory"
msgstr "Memoria de la Pila (_Stack_)"
-#: src/SUMMARY.md:84 src/memory-management/manual.md:1
+#: src/SUMMARY.md:85 src/memory-management/manual.md:1
msgid "Manual Memory Management"
msgstr "Manejo Manual de Memoria"
-#: src/SUMMARY.md:85 src/memory-management/scope-based.md:1
+#: src/SUMMARY.md:86 src/memory-management/scope-based.md:1
msgid "Scope-Based Memory Management"
msgstr "Manejo de Memoria basado en Scope (ámbitos)"
-#: src/SUMMARY.md:86
+#: src/SUMMARY.md:87
msgid "Garbage Collection"
msgstr "Recolección de memoria residual"
-#: src/SUMMARY.md:87
+#: src/SUMMARY.md:88
msgid "Rust Memory Management"
msgstr "Manejo de la Memoria en Rust"
-#: src/SUMMARY.md:88 src/ownership.md:1
+#: src/SUMMARY.md:89 src/ownership.md:1
msgid "Ownership"
msgstr "Ownership"
-#: src/SUMMARY.md:89 src/ownership/move-semantics.md:1
+#: src/SUMMARY.md:90 src/ownership/move-semantics.md:1
msgid "Move Semantics"
msgstr "Semántica de movimiento"
-#: src/SUMMARY.md:90 src/ownership/moved-strings-rust.md:1
+#: src/SUMMARY.md:91 src/ownership/moved-strings-rust.md:1
msgid "Moved Strings in Rust"
msgstr "Cadenas movidas en Rust"
-#: src/SUMMARY.md:91
+#: src/SUMMARY.md:92
msgid "Double Frees in Modern C++"
msgstr "Double free en código C++ moderno"
-#: src/SUMMARY.md:92 src/ownership/moves-function-calls.md:1
+#: src/SUMMARY.md:93 src/ownership/moves-function-calls.md:1
msgid "Moves in Function Calls"
msgstr "Movimientos en llamadas de función"
-#: src/SUMMARY.md:93 src/ownership/copy-clone.md:1
+#: src/SUMMARY.md:94 src/ownership/copy-clone.md:1
msgid "Copying and Cloning"
msgstr "Copiar y clonar"
-#: src/SUMMARY.md:94 src/ownership/borrowing.md:1
+#: src/SUMMARY.md:95 src/ownership/borrowing.md:1
msgid "Borrowing"
msgstr "Préstamos (_Borrowing_)"
-#: src/SUMMARY.md:95 src/ownership/shared-unique-borrows.md:1
+#: src/SUMMARY.md:96 src/ownership/shared-unique-borrows.md:1
msgid "Shared and Unique Borrows"
msgstr "Préstamos compartidos y únicos"
-#: src/SUMMARY.md:96 src/ownership/lifetimes.md:1
+#: src/SUMMARY.md:97 src/ownership/lifetimes.md:1
msgid "Lifetimes"
msgstr "Tiempos de vida"
-#: src/SUMMARY.md:97 src/ownership/lifetimes-function-calls.md:1
+#: src/SUMMARY.md:98 src/ownership/lifetimes-function-calls.md:1
msgid "Lifetimes in Function Calls"
msgstr "Tiempos de Vida en Llamadas a Función"
-#: src/SUMMARY.md:98 src/ownership/lifetimes-data-structures.md:1
+#: src/SUMMARY.md:99 src/ownership/lifetimes-data-structures.md:1
msgid "Lifetimes in Data Structures"
msgstr "Tiempos de vida en estructuras de datos"
-#: src/SUMMARY.md:99 src/structs.md:1
+#: src/SUMMARY.md:100 src/structs.md:1
msgid "Structs"
msgstr "Structs"
-#: src/SUMMARY.md:100 src/structs/tuple-structs.md:1
+#: src/SUMMARY.md:101 src/structs/tuple-structs.md:1
msgid "Tuple Structs"
msgstr "Estructuras de tuplas"
-#: src/SUMMARY.md:101 src/structs/field-shorthand.md:1
+#: src/SUMMARY.md:102 src/structs/field-shorthand.md:1
msgid "Field Shorthand Syntax"
msgstr "Sintaxis abreviada de campos"
-#: src/SUMMARY.md:103 src/methods/receiver.md:1
+#: src/SUMMARY.md:104 src/methods/receiver.md:1
msgid "Method Receiver"
msgstr "Receptor de método"
-#: src/SUMMARY.md:104 src/SUMMARY.md:166 src/SUMMARY.md:281
+#: src/SUMMARY.md:105 src/SUMMARY.md:167 src/SUMMARY.md:282
#: src/methods/example.md:1 src/concurrency/shared_state/example.md:1
msgid "Example"
msgstr "Ejemplo"
-#: src/SUMMARY.md:106 src/exercises/day-2/book-library.md:1
+#: src/SUMMARY.md:107 src/exercises/day-2/book-library.md:1
msgid "Storing Books"
msgstr "Almacenar libros"
-#: src/SUMMARY.md:107 src/exercises/day-2/health-statistics.md:1
+#: src/SUMMARY.md:108 src/exercises/day-2/health-statistics.md:1
+#: src/exercises/day-2/solutions-morning.md:151
msgid "Health Statistics"
msgstr "Estadísticas de salud"
-#: src/SUMMARY.md:109
+#: src/SUMMARY.md:110
msgid "Day 2: Afternoon"
msgstr "Día 2: tarde"
-#: src/SUMMARY.md:111 src/std.md:1
+#: src/SUMMARY.md:112 src/std.md:1
msgid "Standard Library"
msgstr "Biblioteca estándar"
-#: src/SUMMARY.md:112
+#: src/SUMMARY.md:113
msgid "Option and Result"
msgstr "Option y Result"
-#: src/SUMMARY.md:113 src/std/string.md:1
+#: src/SUMMARY.md:114 src/std/string.md:1
msgid "String"
msgstr "String"
-#: src/SUMMARY.md:114
+#: src/SUMMARY.md:115
msgid "Vec"
msgstr "Vec"
-#: src/SUMMARY.md:115
+#: src/SUMMARY.md:116
msgid "HashMap"
msgstr "HashMap"
-#: src/SUMMARY.md:116
+#: src/SUMMARY.md:117
msgid "Box"
msgstr "Box"
-#: src/SUMMARY.md:117
+#: src/SUMMARY.md:118
msgid "Recursive Data Types"
msgstr "Tipos de datos recursivos"
-#: src/SUMMARY.md:118 src/std/box-niche.md:1
+#: src/SUMMARY.md:119 src/std/box-niche.md:1
msgid "Niche Optimization"
msgstr "Optimización de la Memoria"
-#: src/SUMMARY.md:119
+#: src/SUMMARY.md:120
msgid "Rc"
msgstr "Rc"
-#: src/SUMMARY.md:120
+#: src/SUMMARY.md:121
msgid "Cell/RefCell"
msgstr ""
-#: src/SUMMARY.md:121 src/modules.md:1
+#: src/SUMMARY.md:122 src/modules.md:1
msgid "Modules"
msgstr "Módulos"
-#: src/SUMMARY.md:122 src/modules/visibility.md:1
+#: src/SUMMARY.md:123 src/modules/visibility.md:1
msgid "Visibility"
msgstr "Visibilidad"
-#: src/SUMMARY.md:123 src/modules/paths.md:1
+#: src/SUMMARY.md:124 src/modules/paths.md:1
msgid "Paths"
msgstr "Rutas"
-#: src/SUMMARY.md:124 src/modules/filesystem.md:1
+#: src/SUMMARY.md:125 src/modules/filesystem.md:1
msgid "Filesystem Hierarchy"
msgstr "Jerarquía del sistema de archivos"
-#: src/SUMMARY.md:126 src/exercises/day-2/iterators-and-ownership.md:1
+#: src/SUMMARY.md:127 src/exercises/day-2/iterators-and-ownership.md:1
msgid "Iterators and Ownership"
msgstr "Iteradores y Ownership (Propiedad)"
-#: src/SUMMARY.md:127 src/exercises/day-2/strings-iterators.md:1
+#: src/SUMMARY.md:128 src/exercises/day-2/strings-iterators.md:1
#: src/exercises/day-2/solutions-afternoon.md:3
msgid "Strings and Iterators"
msgstr "Cadenas e Iteradores"
-#: src/SUMMARY.md:130
+#: src/SUMMARY.md:131
msgid "Day 3: Morning"
msgstr "Día 3: Mañana"
-#: src/SUMMARY.md:135 src/generics.md:1
+#: src/SUMMARY.md:136 src/generics.md:1
msgid "Generics"
msgstr "Genéricos"
-#: src/SUMMARY.md:136 src/generics/data-types.md:1
+#: src/SUMMARY.md:137 src/generics/data-types.md:1
msgid "Generic Data Types"
msgstr "Tipos de Datos Genéricos"
-#: src/SUMMARY.md:137 src/generics/methods.md:1
+#: src/SUMMARY.md:138 src/generics/methods.md:1
msgid "Generic Methods"
msgstr "Métodos Genéricos"
-#: src/SUMMARY.md:138 src/generics/monomorphization.md:1
+#: src/SUMMARY.md:139 src/generics/monomorphization.md:1
msgid "Monomorphization"
msgstr "Monomorfización"
-#: src/SUMMARY.md:139 src/traits.md:1
+#: src/SUMMARY.md:140 src/traits.md:1
msgid "Traits"
msgstr "Traits"
-#: src/SUMMARY.md:140 src/traits/trait-objects.md:1
+#: src/SUMMARY.md:141 src/traits/trait-objects.md:1
msgid "Trait Objects"
msgstr "Objetos Trait"
-#: src/SUMMARY.md:141 src/traits/deriving-traits.md:1
+#: src/SUMMARY.md:142 src/traits/deriving-traits.md:1
msgid "Deriving Traits"
msgstr "Derivación de Traits"
-#: src/SUMMARY.md:142 src/traits/default-methods.md:1
+#: src/SUMMARY.md:143 src/traits/default-methods.md:1
msgid "Default Methods"
msgstr "Métodos por Default"
-#: src/SUMMARY.md:143 src/traits/trait-bounds.md:1
+#: src/SUMMARY.md:144 src/traits/trait-bounds.md:1
msgid "Trait Bounds"
msgstr "Trait Bounds"
-#: src/SUMMARY.md:144
+#: src/SUMMARY.md:145
msgid "impl Trait"
msgstr "impl Trait"
-#: src/SUMMARY.md:145 src/traits/important-traits.md:1
+#: src/SUMMARY.md:146 src/traits/important-traits.md:1
msgid "Important Traits"
msgstr "Traits Importantes"
-#: src/SUMMARY.md:146
+#: src/SUMMARY.md:147
msgid "Iterator"
msgstr "Iteradores"
-#: src/SUMMARY.md:147 src/traits/from-iterator.md:1
+#: src/SUMMARY.md:148 src/traits/from-iterator.md:1
msgid "FromIterator"
msgstr "FromIterator"
-#: src/SUMMARY.md:148
+#: src/SUMMARY.md:149
msgid "From and Into"
msgstr "From e Into"
-#: src/SUMMARY.md:149
+#: src/SUMMARY.md:150
msgid "Read and Write"
msgstr "Read y Write"
-#: src/SUMMARY.md:150
+#: src/SUMMARY.md:151
msgid "Drop"
msgstr ""
-#: src/SUMMARY.md:151
+#: src/SUMMARY.md:152
msgid "Default"
msgstr ""
-#: src/SUMMARY.md:152
+#: src/SUMMARY.md:153
msgid "Operators: Add, Mul, ..."
msgstr "Operadores: Add, Mul, …."
-#: src/SUMMARY.md:153
+#: src/SUMMARY.md:154
msgid "Closures: Fn, FnMut, FnOnce"
msgstr ""
-#: src/SUMMARY.md:155 src/exercises/day-3/simple-gui.md:1
-#: src/exercises/day-3/solutions-morning.md:3
+#: src/SUMMARY.md:156
msgid "A Simple GUI Library"
msgstr "Una Biblioteca GUI sencilla"
-#: src/SUMMARY.md:156 src/exercises/day-3/solutions-morning.md:175
+#: src/SUMMARY.md:157 src/exercises/day-3/solutions-morning.md:142
msgid "Points and Polygons"
msgstr "Puntos y Polígonos"
-#: src/SUMMARY.md:158
+#: src/SUMMARY.md:159
msgid "Day 3: Afternoon"
msgstr "Día 3: Tarde"
-#: src/SUMMARY.md:160 src/error-handling.md:1
+#: src/SUMMARY.md:161 src/error-handling.md:1
msgid "Error Handling"
msgstr "Manejo de Errores"
-#: src/SUMMARY.md:161 src/error-handling/panics.md:1
+#: src/SUMMARY.md:162 src/error-handling/panics.md:1
msgid "Panics"
msgstr ""
-#: src/SUMMARY.md:162
+#: src/SUMMARY.md:163
msgid "Catching Stack Unwinding"
msgstr "Catching Stack Unwinding"
-#: src/SUMMARY.md:163
+#: src/SUMMARY.md:164
msgid "Structured Error Handling"
msgstr "Manejo de Errores Estructurado"
-#: src/SUMMARY.md:164
+#: src/SUMMARY.md:165
msgid "Propagating Errors with ?"
msgstr "Propagación de Errores con ?"
-#: src/SUMMARY.md:165 src/error-handling/converting-error-types.md:1
+#: src/SUMMARY.md:166 src/error-handling/converting-error-types.md:1
#: src/error-handling/converting-error-types-example.md:1
msgid "Converting Error Types"
msgstr "Conversión de Tipos de Errores"
-#: src/SUMMARY.md:167 src/error-handling/deriving-error-enums.md:1
+#: src/SUMMARY.md:168 src/error-handling/deriving-error-enums.md:1
msgid "Deriving Error Enums"
msgstr "Derivación de Enums de Error"
-#: src/SUMMARY.md:168 src/error-handling/dynamic-errors.md:1
+#: src/SUMMARY.md:169 src/error-handling/dynamic-errors.md:1
msgid "Dynamic Error Types"
msgstr "Tipos de Errores Dinámicos"
-#: src/SUMMARY.md:169 src/error-handling/error-contexts.md:1
+#: src/SUMMARY.md:170 src/error-handling/error-contexts.md:1
msgid "Adding Context to Errors"
msgstr "Añadir Contexto a los Errores"
-#: src/SUMMARY.md:170 src/testing.md:1
+#: src/SUMMARY.md:171 src/testing.md:1
msgid "Testing"
msgstr "Probando"
-#: src/SUMMARY.md:171 src/testing/unit-tests.md:1
+#: src/SUMMARY.md:172 src/testing/unit-tests.md:1
msgid "Unit Tests"
msgstr "Pruebas Unitarias"
-#: src/SUMMARY.md:172 src/testing/test-modules.md:1
+#: src/SUMMARY.md:173 src/testing/test-modules.md:1
msgid "Test Modules"
msgstr "Módulos de Pruebas"
-#: src/SUMMARY.md:173 src/testing/doc-tests.md:1
+#: src/SUMMARY.md:174 src/testing/doc-tests.md:1
msgid "Documentation Tests"
msgstr "Pruebas de Documentación"
-#: src/SUMMARY.md:174 src/testing/integration-tests.md:1
+#: src/SUMMARY.md:175 src/testing/integration-tests.md:1
msgid "Integration Tests"
msgstr "Pruebas de Integración"
-#: src/SUMMARY.md:175 src/bare-metal/useful-crates.md:1
+#: src/SUMMARY.md:176 src/bare-metal/useful-crates.md:1
msgid "Useful crates"
msgstr "Crates Útiles"
-#: src/SUMMARY.md:176 src/unsafe.md:1
+#: src/SUMMARY.md:177 src/unsafe.md:1
msgid "Unsafe Rust"
msgstr "Unsafe Rust"
-#: src/SUMMARY.md:177 src/unsafe/raw-pointers.md:1
+#: src/SUMMARY.md:178 src/unsafe/raw-pointers.md:1
msgid "Dereferencing Raw Pointers"
msgstr "Dereferenciación de Punteros Sin Formato"
-#: src/SUMMARY.md:178 src/unsafe/mutable-static-variables.md:1
+#: src/SUMMARY.md:179 src/unsafe/mutable-static-variables.md:1
msgid "Mutable Static Variables"
msgstr "Variables Estáticas Mutables"
-#: src/SUMMARY.md:179 src/unsafe/unions.md:1
+#: src/SUMMARY.md:180 src/unsafe/unions.md:1
msgid "Unions"
msgstr "Uniones"
-#: src/SUMMARY.md:180 src/unsafe/calling-unsafe-functions.md:1
+#: src/SUMMARY.md:181 src/unsafe/calling-unsafe-functions.md:1
msgid "Calling Unsafe Functions"
msgstr "Llamar Funciones Unsafe (Inseguras)"
-#: src/SUMMARY.md:181 src/unsafe/writing-unsafe-functions.md:1
+#: src/SUMMARY.md:182 src/unsafe/writing-unsafe-functions.md:1
msgid "Writing Unsafe Functions"
msgstr "Escribir Funciones Unsafe (Inseguras)"
-#: src/SUMMARY.md:182
+#: src/SUMMARY.md:183
msgid "Extern Functions"
msgstr "Funciones Externas"
-#: src/SUMMARY.md:183 src/unsafe/unsafe-traits.md:1
+#: src/SUMMARY.md:184 src/unsafe/unsafe-traits.md:1
msgid "Implementing Unsafe Traits"
msgstr "Implementación de Traits Unsafe (Inseguras) "
-#: src/SUMMARY.md:185 src/exercises/day-3/safe-ffi-wrapper.md:1
+#: src/SUMMARY.md:186 src/exercises/day-3/safe-ffi-wrapper.md:1
#: src/exercises/day-3/solutions-afternoon.md:3
msgid "Safe FFI Wrapper"
msgstr "Envoltorio de FFI Seguro"
-#: src/SUMMARY.md:188 src/SUMMARY.md:258 src/bare-metal/android.md:1
+#: src/SUMMARY.md:189 src/SUMMARY.md:259 src/bare-metal/android.md:1
msgid "Android"
msgstr ""
-#: src/SUMMARY.md:193 src/android/setup.md:1
+#: src/SUMMARY.md:194 src/android/setup.md:1
msgid "Setup"
msgstr "Configurar"
-#: src/SUMMARY.md:194 src/android/build-rules.md:1
+#: src/SUMMARY.md:195 src/android/build-rules.md:1
msgid "Build Rules"
msgstr "Reglas de Compilación (Build)"
-#: src/SUMMARY.md:195
+#: src/SUMMARY.md:196
msgid "Binary"
msgstr "Binarios"
-#: src/SUMMARY.md:196
+#: src/SUMMARY.md:197
msgid "Library"
msgstr "Biblioteca"
-#: src/SUMMARY.md:197 src/android/aidl.md:1
+#: src/SUMMARY.md:198 src/android/aidl.md:1
msgid "AIDL"
msgstr ""
-#: src/SUMMARY.md:198
+#: src/SUMMARY.md:199
msgid "Interface"
msgstr "Interfaz"
-#: src/SUMMARY.md:199
+#: src/SUMMARY.md:200
msgid "Implementation"
msgstr "Implementación"
-#: src/SUMMARY.md:200
+#: src/SUMMARY.md:201
msgid "Server"
msgstr "Servidor"
-#: src/SUMMARY.md:201 src/android/aidl/deploy.md:1
+#: src/SUMMARY.md:202 src/android/aidl/deploy.md:1
msgid "Deploy"
msgstr "Despliegue"
-#: src/SUMMARY.md:202
+#: src/SUMMARY.md:203
msgid "Client"
msgstr "Cliente"
-#: src/SUMMARY.md:203 src/android/aidl/changing.md:1
+#: src/SUMMARY.md:204 src/android/aidl/changing.md:1
msgid "Changing API"
msgstr "Cambio de API"
-#: src/SUMMARY.md:204 src/SUMMARY.md:248 src/android/logging.md:1
+#: src/SUMMARY.md:205 src/SUMMARY.md:249 src/android/logging.md:1
#: src/bare-metal/aps/logging.md:1
msgid "Logging"
msgstr "Almacenamiento de registros"
-#: src/SUMMARY.md:205 src/android/interoperability.md:1
+#: src/SUMMARY.md:206 src/android/interoperability.md:1
msgid "Interoperability"
msgstr "Interoperabilidad"
-#: src/SUMMARY.md:206
+#: src/SUMMARY.md:207
msgid "With C"
msgstr "Con C"
-#: src/SUMMARY.md:207
+#: src/SUMMARY.md:208
msgid "Calling C with Bindgen"
msgstr "Llamar a C con Bindgen"
-#: src/SUMMARY.md:208
+#: src/SUMMARY.md:209
msgid "Calling Rust from C"
msgstr "Llamar a Rust desde C"
-#: src/SUMMARY.md:209 src/android/interoperability/cpp.md:1
-msgid "With C++"
+#: src/SUMMARY.md:210
+#, fuzzy
+#| msgid "With C++"
+msgid "With C++)"
msgstr "Con C++"
-#: src/SUMMARY.md:210
+#: src/SUMMARY.md:211
msgid "With Java"
msgstr "Con Java"
-#: src/SUMMARY.md:214
+#: src/SUMMARY.md:215
msgid "Bare Metal: Morning"
msgstr "Bare Metal: mañana"
-#: src/SUMMARY.md:219
+#: src/SUMMARY.md:220
msgid "no_std"
msgstr "no_std"
-#: src/SUMMARY.md:220
+#: src/SUMMARY.md:221
msgid "A Minimal Example"
msgstr "Un Pequeño Ejemplo"
-#: src/SUMMARY.md:221
+#: src/SUMMARY.md:222
msgid "alloc"
msgstr "alloc"
-#: src/SUMMARY.md:222 src/bare-metal/microcontrollers.md:1
+#: src/SUMMARY.md:223 src/bare-metal/microcontrollers.md:1
msgid "Microcontrollers"
msgstr "Microcontroladores"
-#: src/SUMMARY.md:223 src/bare-metal/microcontrollers/mmio.md:1
+#: src/SUMMARY.md:224 src/bare-metal/microcontrollers/mmio.md:1
msgid "Raw MMIO"
msgstr "MMIO sin procesar"
-#: src/SUMMARY.md:224
+#: src/SUMMARY.md:225
msgid "PACs"
msgstr "PAC"
-#: src/SUMMARY.md:225
+#: src/SUMMARY.md:226
msgid "HAL Crates"
msgstr "Crates HAL"
-#: src/SUMMARY.md:226
+#: src/SUMMARY.md:227
msgid "Board Support Crates"
msgstr "Crates de Soporte de Placa"
-#: src/SUMMARY.md:227
+#: src/SUMMARY.md:228
msgid "The Type State Pattern"
msgstr "El Patrón de Tipo de Estado"
-#: src/SUMMARY.md:228
+#: src/SUMMARY.md:229
msgid "embedded-hal"
msgstr "embedded-hal"
-#: src/SUMMARY.md:229
+#: src/SUMMARY.md:230
msgid "probe-rs, cargo-embed"
msgstr "probe-rs, cargo-embed"
-#: src/SUMMARY.md:230 src/bare-metal/microcontrollers/debugging.md:1
+#: src/SUMMARY.md:231 src/bare-metal/microcontrollers/debugging.md:1
msgid "Debugging"
msgstr "Depuración"
-#: src/SUMMARY.md:231 src/SUMMARY.md:251
+#: src/SUMMARY.md:232 src/SUMMARY.md:252
msgid "Other Projects"
msgstr "Otros proyectos"
-#: src/SUMMARY.md:233 src/exercises/bare-metal/compass.md:1
+#: src/SUMMARY.md:234 src/exercises/bare-metal/compass.md:1
#: src/exercises/bare-metal/solutions-morning.md:3
msgid "Compass"
msgstr "Brújula"
-#: src/SUMMARY.md:235
+#: src/SUMMARY.md:236
msgid "Bare Metal: Afternoon"
msgstr "Bare Metal: tarde"
-#: src/SUMMARY.md:237
+#: src/SUMMARY.md:238
msgid "Application Processors"
msgstr "Procesadores de aplicaciones"
-#: src/SUMMARY.md:238 src/bare-metal/aps/entry-point.md:1
+#: src/SUMMARY.md:239 src/bare-metal/aps/entry-point.md:1
msgid "Getting Ready to Rust"
msgstr "Iniciación a Rust"
-#: src/SUMMARY.md:239
+#: src/SUMMARY.md:240
msgid "Inline Assembly"
msgstr "Ensamblador en línea"
-#: src/SUMMARY.md:240
+#: src/SUMMARY.md:241
msgid "MMIO"
msgstr "MMIO"
-#: src/SUMMARY.md:241
+#: src/SUMMARY.md:242
msgid "Let's Write a UART Driver"
msgstr "Escribir un controlador UART"
-#: src/SUMMARY.md:242
+#: src/SUMMARY.md:243
msgid "More Traits"
msgstr "Más traits"
-#: src/SUMMARY.md:243
+#: src/SUMMARY.md:244
msgid "A Better UART Driver"
msgstr "Un controlador UART mejor"
-#: src/SUMMARY.md:244 src/bare-metal/aps/better-uart/bitflags.md:1
+#: src/SUMMARY.md:245 src/bare-metal/aps/better-uart/bitflags.md:1
msgid "Bitflags"
msgstr "Bitflags"
-#: src/SUMMARY.md:245
+#: src/SUMMARY.md:246
msgid "Multiple Registers"
msgstr "Varios registros"
-#: src/SUMMARY.md:246 src/bare-metal/aps/better-uart/driver.md:1
+#: src/SUMMARY.md:247 src/bare-metal/aps/better-uart/driver.md:1
msgid "Driver"
msgstr "Conductor"
-#: src/SUMMARY.md:247 src/SUMMARY.md:249
+#: src/SUMMARY.md:248 src/SUMMARY.md:250
msgid "Using It"
msgstr "Cómo usarlo"
-#: src/SUMMARY.md:250 src/bare-metal/aps/exceptions.md:1
+#: src/SUMMARY.md:251 src/bare-metal/aps/exceptions.md:1
msgid "Exceptions"
msgstr "Excepciones"
-#: src/SUMMARY.md:252
+#: src/SUMMARY.md:253
msgid "Useful Crates"
msgstr "Crates útiles"
-#: src/SUMMARY.md:253
+#: src/SUMMARY.md:254
msgid "zerocopy"
msgstr "zerocopy"
-#: src/SUMMARY.md:254
+#: src/SUMMARY.md:255
msgid "aarch64-paging"
msgstr "aarch64-paging"
-#: src/SUMMARY.md:255
+#: src/SUMMARY.md:256
msgid "buddy_system_allocator"
msgstr "buddy_system_allocator"
-#: src/SUMMARY.md:256
+#: src/SUMMARY.md:257
msgid "tinyvec"
msgstr "tinyvec"
-#: src/SUMMARY.md:257
+#: src/SUMMARY.md:258
msgid "spin"
msgstr "girar"
-#: src/SUMMARY.md:259 src/bare-metal/android/vmbase.md:1
+#: src/SUMMARY.md:260 src/bare-metal/android/vmbase.md:1
msgid "vmbase"
msgstr "vmbase"
-#: src/SUMMARY.md:261
+#: src/SUMMARY.md:262
msgid "RTC Driver"
msgstr "Controlador RTC"
-#: src/SUMMARY.md:264
+#: src/SUMMARY.md:265
msgid "Concurrency: Morning"
msgstr "Concurrencia: mañana"
-#: src/SUMMARY.md:269 src/concurrency/threads.md:1
+#: src/SUMMARY.md:270 src/concurrency/threads.md:1
msgid "Threads"
msgstr "Hilos"
-#: src/SUMMARY.md:270 src/concurrency/scoped-threads.md:1
+#: src/SUMMARY.md:271 src/concurrency/scoped-threads.md:1
msgid "Scoped Threads"
msgstr "Hilos con ámbito"
-#: src/SUMMARY.md:271 src/concurrency/channels.md:1
+#: src/SUMMARY.md:272 src/concurrency/channels.md:1
msgid "Channels"
msgstr "Canales"
-#: src/SUMMARY.md:272 src/concurrency/channels/unbounded.md:1
+#: src/SUMMARY.md:273 src/concurrency/channels/unbounded.md:1
msgid "Unbounded Channels"
msgstr "Canales sin límites"
-#: src/SUMMARY.md:273 src/concurrency/channels/bounded.md:1
+#: src/SUMMARY.md:274 src/concurrency/channels/bounded.md:1
msgid "Bounded Channels"
msgstr "Canales delimitados"
-#: src/SUMMARY.md:274
+#: src/SUMMARY.md:275
msgid "Send and Sync"
msgstr "Send y Sync"
-#: src/SUMMARY.md:274
+#: src/SUMMARY.md:276
msgid "Send"
msgstr "Send"
-#: src/SUMMARY.md:274
+#: src/SUMMARY.md:277
msgid "Sync"
msgstr "Sync"
-#: src/SUMMARY.md:277 src/concurrency/send-sync/examples.md:1
+#: src/SUMMARY.md:278 src/concurrency/send-sync/examples.md:1
msgid "Examples"
msgstr "Ejemplos"
-#: src/SUMMARY.md:278 src/concurrency/shared_state.md:1
+#: src/SUMMARY.md:279 src/concurrency/shared_state.md:1
msgid "Shared State"
msgstr "Estado compartido"
-#: src/SUMMARY.md:279
+#: src/SUMMARY.md:280
msgid "Arc"
msgstr "Arc"
-#: src/SUMMARY.md:280
+#: src/SUMMARY.md:281
msgid "Mutex"
msgstr "Mutex"
-#: src/SUMMARY.md:283 src/SUMMARY.md:304
+#: src/SUMMARY.md:284 src/SUMMARY.md:305
#: src/exercises/concurrency/dining-philosophers.md:1
#: src/exercises/concurrency/solutions-morning.md:3
msgid "Dining Philosophers"
msgstr "La cena de los filósofos"
-#: src/SUMMARY.md:284 src/exercises/concurrency/link-checker.md:1
+#: src/SUMMARY.md:285 src/exercises/concurrency/link-checker.md:1
msgid "Multi-threaded Link Checker"
msgstr "Comprobador de enlaces multihilo"
-#: src/SUMMARY.md:286
+#: src/SUMMARY.md:287
msgid "Concurrency: Afternoon"
msgstr "Concurrencia: tarde"
-#: src/SUMMARY.md:288
+#: src/SUMMARY.md:289
msgid "Async Basics"
msgstr "Conceptos básicos de Async"
-#: src/SUMMARY.md:289
+#: src/SUMMARY.md:290
msgid "async/await"
msgstr "async / await"
-#: src/SUMMARY.md:290 src/async/futures.md:1
+#: src/SUMMARY.md:291 src/async/futures.md:1
msgid "Futures"
msgstr "Future"
-#: src/SUMMARY.md:291 src/async/runtimes.md:1
+#: src/SUMMARY.md:292 src/async/runtimes.md:1
msgid "Runtimes"
msgstr "Runtimes (Tiempos de Ejecución)"
-#: src/SUMMARY.md:292 src/async/runtimes/tokio.md:1
+#: src/SUMMARY.md:293 src/async/runtimes/tokio.md:1
msgid "Tokio"
msgstr "Tokio"
-#: src/SUMMARY.md:293 src/exercises/concurrency/link-checker.md:126
+#: src/SUMMARY.md:294 src/exercises/concurrency/link-checker.md:126
#: src/async/tasks.md:1 src/exercises/concurrency/chat-app.md:143
msgid "Tasks"
msgstr "Tasks"
-#: src/SUMMARY.md:294 src/async/channels.md:1
+#: src/SUMMARY.md:295 src/async/channels.md:1
msgid "Async Channels"
msgstr "Canales asíncronos"
-#: src/SUMMARY.md:296 src/async/control-flow/join.md:1
+#: src/SUMMARY.md:297 src/async/control-flow/join.md:1
msgid "Join"
msgstr "Unir"
-#: src/SUMMARY.md:297 src/async/control-flow/select.md:1
+#: src/SUMMARY.md:298 src/async/control-flow/select.md:1
msgid "Select"
msgstr "Seleccionar"
-#: src/SUMMARY.md:298
+#: src/SUMMARY.md:299
msgid "Pitfalls"
msgstr "Inconvenientes"
-#: src/SUMMARY.md:299
+#: src/SUMMARY.md:300
msgid "Blocking the Executor"
msgstr "Bloqueo del ejecutor"
-#: src/SUMMARY.md:300 src/async/pitfalls/pin.md:1
+#: src/SUMMARY.md:301 src/async/pitfalls/pin.md:1
msgid "Pin"
msgstr "Fijar"
-#: src/SUMMARY.md:301 src/async/pitfalls/async-traits.md:1
+#: src/SUMMARY.md:302 src/async/pitfalls/async-traits.md:1
msgid "Async Traits"
msgstr "Traits asíncronos"
-#: src/SUMMARY.md:302 src/async/pitfalls/cancellation.md:1
+#: src/SUMMARY.md:303 src/async/pitfalls/cancellation.md:1
msgid "Cancellation"
msgstr "Cancelación"
-#: src/SUMMARY.md:305 src/exercises/concurrency/chat-app.md:1
-#: src/exercises/concurrency/solutions-afternoon.md:119
+#: src/SUMMARY.md:306 src/exercises/concurrency/chat-app.md:1
+#: src/exercises/concurrency/solutions-afternoon.md:95
msgid "Broadcast Chat Application"
msgstr "Aplicación de chat de difusión"
-#: src/SUMMARY.md:308
+#: src/SUMMARY.md:309
msgid "Final Words"
msgstr "Conclusiones"
-#: src/SUMMARY.md:312 src/thanks.md:1
+#: src/SUMMARY.md:313 src/thanks.md:1
msgid "Thanks!"
msgstr "Gracias."
-#: src/SUMMARY.md:313
+#: src/SUMMARY.md:314 src/glossary.md:1
+msgid "Glossary"
+msgstr ""
+
+#: src/SUMMARY.md:315
msgid "Other Resources"
msgstr "Otros recursos"
-#: src/SUMMARY.md:314 src/credits.md:1
+#: src/SUMMARY.md:316 src/credits.md:1
msgid "Credits"
msgstr "Créditos"
-#: src/SUMMARY.md:317 src/exercises/solutions.md:1
+#: src/SUMMARY.md:319 src/SUMMARY.md:323 src/exercises/solutions.md:1
msgid "Solutions"
msgstr "Soluciones"
-#: src/SUMMARY.md:322
+#: src/SUMMARY.md:324
msgid "Day 1 Morning"
msgstr "Día 1: mañana"
-#: src/SUMMARY.md:323
+#: src/SUMMARY.md:325
msgid "Day 1 Afternoon"
msgstr "Día 1: tarde"
-#: src/SUMMARY.md:324
+#: src/SUMMARY.md:326
msgid "Day 2 Morning"
msgstr "Día 2: mañana"
-#: src/SUMMARY.md:325
+#: src/SUMMARY.md:327
msgid "Day 2 Afternoon"
msgstr "Día 2: tarde"
-#: src/SUMMARY.md:326
+#: src/SUMMARY.md:328
msgid "Day 3 Morning"
msgstr "Día 3: mañana"
-#: src/SUMMARY.md:327
+#: src/SUMMARY.md:329
msgid "Day 3 Afternoon"
msgstr "Día 3: tarde"
-#: src/SUMMARY.md:328
+#: src/SUMMARY.md:330
msgid "Bare Metal Rust Morning"
msgstr "Rust Bare Metal: mañana"
-#: src/SUMMARY.md:329 src/exercises/bare-metal/solutions-afternoon.md:1
+#: src/SUMMARY.md:331 src/exercises/bare-metal/solutions-afternoon.md:1
msgid "Bare Metal Rust Afternoon"
msgstr "Rust Bare Metal: tarde"
-#: src/SUMMARY.md:330
+#: src/SUMMARY.md:332
msgid "Concurrency Morning"
msgstr "Concurrencia: mañana"
-#: src/SUMMARY.md:331
+#: src/SUMMARY.md:333
msgid "Concurrency Afternoon"
msgstr "Concurrencia: tarde"
@@ -1448,22 +1461,6 @@ msgstr ""
"dependencias. A continuación, podrás copiar y pegar los ejemplos en `src/"
"main.rs` para experimentar con ellos:"
-#: src/running-the-course/course-structure.md:57
-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"
-"```"
-
#: src/running-the-course/course-structure.md:64
msgid "Format"
msgstr "Formato"
@@ -1524,28 +1521,43 @@ msgstr ""
msgid ""
"[Brazilian Portuguese](https://google.github.io/comprehensive-rust/pt-BR/) "
"by [@rastringer](https://github.com/rastringer), [@hugojacob](https://github."
-"com/hugojacob), [@joaovicmendes](https://github.com/joaovicmendes) and "
+"com/hugojacob), [@joaovicmendes](https://github.com/joaovicmendes), and "
"[@henrif75](https://github.com/henrif75)."
msgstr ""
#: src/running-the-course/translations.md:7
msgid ""
+"[Chinese (Simplified)](https://google.github.io/comprehensive-rust/zh-CN/) "
+"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), and [@SketchK](https://github.com/SketchK)."
+msgstr ""
+
+#: src/running-the-course/translations.md:8
+msgid ""
"[Korean](https://google.github.io/comprehensive-rust/ko/) by [@keispace]"
-"(https://github.com/keispace), [@jiyongp](https://github.com/jiyongp) and "
+"(https://github.com/keispace), [@jiyongp](https://github.com/jiyongp), and "
"[@jooyunghan](https://github.com/jooyunghan)."
msgstr ""
#: src/running-the-course/translations.md:9
msgid ""
+"[Spanish](https://google.github.io/comprehensive-rust/es/) by [@deavid]"
+"(https://github.com/deavid)."
+msgstr ""
+
+#: src/running-the-course/translations.md:11
+msgid ""
"Use the language picker in the top-right corner to switch between languages."
msgstr ""
"Cambia el idioma con el selector situado en la esquina superior derecha."
-#: src/running-the-course/translations.md:11
+#: src/running-the-course/translations.md:13
msgid "Incomplete Translations"
msgstr "Traducciones Incompletas"
-#: src/running-the-course/translations.md:13
+#: src/running-the-course/translations.md:15
msgid ""
"There is a large number of in-progress translations. We link to the most "
"recently updated translations:"
@@ -1553,32 +1565,40 @@ msgstr ""
"Hay muchas traducciones todavía en curso. A continuación, incluimos enlaces "
"a las traducciones más actualizadas:"
-#: src/running-the-course/translations.md:16
+#: src/running-the-course/translations.md:18
msgid ""
"[Bengali](https://google.github.io/comprehensive-rust/bn/) by [@raselmandol]"
"(https://github.com/raselmandol)."
msgstr ""
-#: src/running-the-course/translations.md:17
+#: src/running-the-course/translations.md:19
+msgid ""
+"[Chinese (Traditional)](https://google.github.io/comprehensive-rust/zh-TW/) "
+"by [@hueich](https://github.com/hueich), [@victorhsieh](https://github.com/"
+"victorhsieh), [@mingyc](https://github.com/mingyc), and [@johnathan79717]"
+"(https://github.com/johnathan79717)."
+msgstr ""
+
+#: src/running-the-course/translations.md:20
msgid ""
"[French](https://google.github.io/comprehensive-rust/fr/) by [@KookaS]"
"(https://github.com/KookaS) and [@vcaen](https://github.com/vcaen)."
msgstr ""
-#: src/running-the-course/translations.md:18
+#: src/running-the-course/translations.md:21
msgid ""
"[German](https://google.github.io/comprehensive-rust/de/) by [@Throvn]"
"(https://github.com/Throvn) and [@ronaldfw](https://github.com/ronaldfw)."
msgstr ""
-#: src/running-the-course/translations.md:19
+#: src/running-the-course/translations.md:22
msgid ""
"[Japanese](https://google.github.io/comprehensive-rust/ja/) by [@CoinEZ-JPN]"
"(https://github.com/CoinEZ) and [@momotaro1105](https://github.com/"
"momotaro1105)."
msgstr ""
-#: src/running-the-course/translations.md:21
+#: src/running-the-course/translations.md:24
msgid ""
"If you want to help with this effort, please see [our instructions](https://"
"github.com/google/comprehensive-rust/blob/main/TRANSLATIONS.md) for how to "
@@ -1614,17 +1634,33 @@ msgid "**Please follow the instructions on .**"
msgstr "**Sigue las instrucciones que se indican en .**"
#: src/cargo.md:12
+#, fuzzy
+#| 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/switch toolchains, setup cross compilation, etc."
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/switch toolchains, setup cross compilation, etc."
+"use to install to different compiler versions."
msgstr ""
"De este modo, obtendrás la herramienta de compilación de Cargo (`cargo`) y "
"el compilador de Rust (`rustc`). También obtendrás `rustup`, una utilidad de "
"línea de comandos que puedes utilizar para instalar o cambiar cadenas de "
"herramientas, configurar la compilación cruzada, etc."
-#: src/cargo.md:16
+#: src/cargo.md:14
+msgid ""
+"After installing Rust, you should configure your editor or IDE to work with "
+"Rust. Most editors do this by talking to [rust-analyzer](https://rust-"
+"analyzer.github.io/), which provides auto-completion and jump-to-definition "
+"functionality for [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), and many others. There is also a "
+"different IDE available called [RustRover](https://www.jetbrains.com/rust/)."
+msgstr ""
+
+#: src/cargo.md:18
#, fuzzy
msgid ""
"On Debian/Ubuntu, you can also install Cargo, the Rust source and the [Rust "
@@ -1637,42 +1673,6 @@ msgstr ""
"`apt`. Sin embargo, solo podrás conseguir una versión de Rust obsoleta que "
"podría dar lugar a comportamientos inesperados. El comando es el siguiente:"
-#: src/cargo.md:18
-msgid ""
-"```shell\n"
-"sudo apt install cargo rust-src rustfmt\n"
-"```"
-msgstr ""
-"```shell\n"
-"sudo apt install cargo rust-src rustfmt\n"
-"```"
-
-#: src/cargo.md:22
-#, 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 ""
-"Recomendamos usar [VS Code](https://code.visualstudio.com/) para editar el "
-"código (aunque cualquier editor compatible con LSP funciona con [rust-"
-"analyzer](https://rust-analyzer.github.io/))."
-
-#: src/cargo.md:24
-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 ""
-"A algunos compañeros también les gusta usar la familia [JetBrains](https://"
-"www.jetbrains.com/clion/) de IDEs, que hacen sus propios análisis, pero "
-"también tienen inconvenientes. Si lo prefieres, puedes instalar el [Rust "
-"Plugin](https://www.jetbrains.com/rust/). Ten en cuenta que, a partir de "
-"enero del 2023, la depuración solo funciona en la versión CLion del paquete "
-"de JetBrains IDEA."
-
#: src/cargo/rust-ecosystem.md:1
msgid "The Rust Ecosystem"
msgstr "El ecosistema de Rust"
@@ -1723,8 +1723,8 @@ msgstr ""
#: src/cargo/rust-ecosystem.md:21 src/hello-world.md:25
#: src/hello-world/small-example.md:27 src/why-rust/runtime.md:10
-#: src/why-rust/modern.md:21 src/basic-syntax/compound-types.md:30
-#: src/basic-syntax/references.md:23
+#: src/why-rust/modern.md:21 src/basic-syntax/compound-types.md:32
+#: src/basic-syntax/references.md:24
#: src/pattern-matching/destructuring-enums.md:35
#: src/ownership/double-free-modern-cpp.md:55
#: src/error-handling/try-operator.md:48
@@ -1881,19 +1881,9 @@ msgstr ""
msgid "The code blocks in this course are fully interactive:"
msgstr "Los bloques de código de este curso son totalmente interactivos:"
-#: src/cargo/code-samples.md:13
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" println!(\"Edit me!\");\n"
-"}\n"
-"```"
+#: src/cargo/code-samples.md:15 src/cargo/running-locally.md:45
+msgid "\"Edit me!\""
msgstr ""
-"```rust,editable\n"
-"fn main() {\n"
-" println!(\"Edit me!\");\n"
-"}\n"
-"```"
#: src/cargo/code-samples.md:19
msgid "You can use "
@@ -1949,22 +1939,6 @@ msgstr ""
"funcionen. En el momento en que se redactó este documento, los números de "
"las últimas versiones estables de Rust eran los siguientes:"
-#: src/cargo/running-locally.md:8
-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.69.0 (84c898d65 2023-04-16)\n"
-"% cargo --version\n"
-"cargo 1.69.0 (6e9a83356 2023-04-12)\n"
-"```"
-
#: src/cargo/running-locally.md:15
msgid ""
"You can use any later version too since Rust maintains backwards "
@@ -1991,44 +1965,12 @@ msgid ""
msgstr ""
"Usa `cargo new exercise` para crear un directorio `exercise/` para tu código:"
-#: src/cargo/running-locally.md:24
-msgid ""
-"```shell\n"
-"$ cargo new exercise\n"
-" Created binary (application) `exercise` package\n"
-"```"
-msgstr ""
-"```shell\n"
-"$ cargo new exercise\n"
-" Created binary (application) `exercise` package\n"
-"```"
-
#: src/cargo/running-locally.md:29
msgid ""
"Navigate into `exercise/` and use `cargo run` to build and run your binary:"
msgstr ""
"Ve a `exercise/` y usa `cargo run` para compilar y ejecutar tu binario:"
-#: src/cargo/running-locally.md:31
-msgid ""
-"```shell\n"
-"$ cd exercise\n"
-"$ cargo run\n"
-" Compiling exercise v0.1.0 (/home/mgeisler/tmp/exercise)\n"
-" Finished dev [unoptimized + debuginfo] target(s) in 0.75s\n"
-" Running `target/debug/exercise`\n"
-"Hello, world!\n"
-"```"
-msgstr ""
-"```shell\n"
-"$ cd exercise\n"
-"$ cargo run\n"
-" Compiling exercise v0.1.0 (/home/mgeisler/tmp/exercise)\n"
-" Finished dev [unoptimized + debuginfo] target(s) in 0.75s\n"
-" Running `target/debug/exercise`\n"
-"Hola Mundo!\n"
-"```"
-
#: src/cargo/running-locally.md:40
msgid ""
"Replace the boiler-plate code in `src/main.rs` with your own code. For "
@@ -2038,42 +1980,10 @@ msgstr ""
"ejemplo, si usamos el ejemplo de la página anterior, podemos hacer que `src/"
"main.rs` tenga el siguiente aspecto:"
-#: src/cargo/running-locally.md:43
-msgid ""
-"```rust\n"
-"fn main() {\n"
-" println!(\"Edit me!\");\n"
-"}\n"
-"```"
-msgstr ""
-"```rust\n"
-"fn main() {\n"
-" println!(\"Edit me!\");\n"
-"}\n"
-"```"
-
#: src/cargo/running-locally.md:49
msgid "Use `cargo run` to build and run your updated binary:"
msgstr "Usa `cargo run` para hacer build y ejecutar tu binario actualizado:"
-#: src/cargo/running-locally.md:51
-msgid ""
-"```shell\n"
-"$ cargo run\n"
-" Compiling exercise v0.1.0 (/home/mgeisler/tmp/exercise)\n"
-" Finished dev [unoptimized + debuginfo] target(s) in 0.24s\n"
-" Running `target/debug/exercise`\n"
-"Edit me!\n"
-"```"
-msgstr ""
-"```shell\n"
-"$ cargo run\n"
-" Compiling exercise v0.1.0 (/home/mgeisler/tmp/exercise)\n"
-" Finished dev [unoptimized + debuginfo] target(s) in 0.24s\n"
-" Running `target/debug/ejercicio`\n"
-"Modifícame!\n"
-"```"
-
#: src/cargo/running-locally.md:59
msgid ""
"Use `cargo check` to quickly check your project for errors, use `cargo "
@@ -2311,19 +2221,9 @@ msgid ""
"program:"
msgstr "Vamos a hablar del programa Rust más simple, un clásico Hola Mundo:"
-#: src/hello-world.md:6
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" println!(\"Hello 🌍!\");\n"
-"}\n"
-"```"
+#: src/hello-world.md:8
+msgid "\"Hello 🌍!\""
msgstr ""
-"```rust,editable\n"
-"fn main() {\n"
-" println!(\"Hola 🌍!\");\n"
-"}\n"
-"```"
#: src/hello-world.md:12
msgid "What you see:"
@@ -2411,39 +2311,33 @@ msgstr ""
msgid "Here is a small example program in Rust:"
msgstr "A continuación, se muestra un pequeño programa de ejemplo de Rust:"
-#: src/hello-world/small-example.md:5
-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"
-"```"
+#: src/hello-world/small-example.md:6
+msgid "// Program entry point\n"
+msgstr ""
+
+#: src/hello-world/small-example.md:7
+msgid "// Mutable variable binding\n"
+msgstr ""
+
+#: src/hello-world/small-example.md:8 src/traits/impl-trait.md:15
+msgid "\"{x}\""
+msgstr ""
+
+#: src/hello-world/small-example.md:8
+msgid "// Macro for printing, like printf\n"
+msgstr ""
+
+#: src/hello-world/small-example.md:9
+msgid "// No parenthesis around expression\n"
+msgstr ""
+
+#: src/hello-world/small-example.md:10
+msgid "// Math like in other languages\n"
+msgstr ""
+
+#: src/hello-world/small-example.md:15
+msgid "\" -> {x}\""
msgstr ""
-"```rust,editable\n"
-"fn main() { // Punto de entrada del programa\n"
-" let mut x: i32 = 6; // Variable mutable vinculante\n"
-" print!(\"{x}\"); // Macro para printing, como printf\n"
-" while x != 1 { // Sin paréntesis alrededor de las expresiones\n"
-" if x % 2 == 0 { // Operaciones matemáticas como en otros lenguajes\n"
-" x = x / 2;\n"
-" } else {\n"
-" x = 3 * x + 1;\n"
-" }\n"
-" print!(\" -> {x}\");\n"
-" }\n"
-" println!();\n"
-"}\n"
-"```"
#: src/hello-world/small-example.md:23
msgid ""
@@ -2554,41 +2448,223 @@ msgstr ""
"rápido y predecible como en C y C++ (sin recolector de memoria residual), "
"así como acceso a hardware de bajo nivel (si lo necesitas)."
-#: src/why-rust/compile-time.md:3
-msgid "Static memory management at compile time:"
-msgstr "Gestión estática de la memoria en tiempo de compilación:"
+#: src/why-rust/an-example-in-c.md:4
+msgid "Let's consider the following \"minimum wrong example\" program in C:"
+msgstr ""
-#: src/why-rust/compile-time.md:5
-msgid "No uninitialized variables."
-msgstr "No hay variables no inicializadas."
+#: src/why-rust/an-example-in-c.md:7
+#: src/android/interoperability/with-c/bindgen.md:22
+msgid ""
+msgstr ""
-#: src/why-rust/compile-time.md:6
-msgid "No memory leaks (_mostly_, see notes)."
-msgstr "No hay pérdidas de memoria (_casi siempre_, consulta las notas)."
+#: src/why-rust/an-example-in-c.md:8
+msgid ""
+msgstr ""
-#: src/why-rust/compile-time.md:7
-msgid "No double-frees."
-msgstr "No hay errores double free."
+#: src/why-rust/an-example-in-c.md:9
+msgid ""
+msgstr ""
-#: src/why-rust/compile-time.md:8
-msgid "No use-after-free."
-msgstr "No hay errores use-after-free."
+#: src/why-rust/an-example-in-c.md:19
+msgid "\"Too few arguments!\\n\""
+msgstr ""
-#: src/why-rust/compile-time.md:9
-msgid "No `NULL` pointers."
-msgstr "No hay punteros `NULL`."
+#: src/why-rust/an-example-in-c.md:29
+msgid "\"malloc failed!\\n\""
+msgstr ""
-#: src/why-rust/compile-time.md:10
-msgid "No forgotten locked mutexes."
-msgstr "No se olvidan las exclusiones mutuas bloqueadas."
+#: src/why-rust/an-example-in-c.md:32
+msgid "\"rb\""
+msgstr ""
-#: src/why-rust/compile-time.md:11
-msgid "No data races between threads."
-msgstr "No hay condiciones de carrera de datos entre hilos."
+#: src/why-rust/an-example-in-c.md:35
+msgid "\"%s\""
+msgstr ""
-#: src/why-rust/compile-time.md:12
-msgid "No iterator invalidation."
-msgstr "No se invalidan los iteradores."
+#: src/why-rust/an-example-in-c.md:37
+msgid "\"fread failed!\\n\""
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:40
+msgid "\"Too many arguments!\\n\""
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:48
+msgid "How many bugs do you spot?"
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:52
+msgid ""
+"Despite just 29 lines of code, this C example contains serious bugs in at "
+"least 11:"
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:54
+msgid "Assignment `=` instead of equality comparison `==` (line 28)"
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:55
+msgid "Excess argument to `printf` (line 23)"
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:56
+msgid "File descriptor leak (after line 26)"
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:57
+msgid "Forgotten braces in multi-line `if` (line 22)"
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:58
+msgid "Forgotten `break` in a `switch` statement (line 32)"
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:59
+msgid ""
+"Forgotten NUL-termination of the `buf` string, leading to a buffer overflow "
+"(line 29)"
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:60
+msgid "Memory leak by not freeing the `malloc`\\-allocated buffer (line 21)"
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:61
+msgid "Out-of-bounds access (line 17)"
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:62
+msgid "Unchecked cases in the `switch` statement (line 11)"
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:63
+msgid "Unchecked return values of `stat` and `fopen` (lines 18 and 26)"
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:65
+msgid ""
+"_Shouldn't these bugs be obvious even for a C compiler?_ \n"
+"No, surprisingly this code compiles warning-free at the default warning "
+"level, even in the latest GCC version (13.2 as of writing)."
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:68
+msgid ""
+"_Isn't this a highly unrealistic example?_ \n"
+"Absolutely not, these kind of bugs have lead to serious security "
+"vulnerabilities in the past. Some examples:"
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:71
+msgid ""
+"Assignment `=` instead of equality comparison `==`: [The Linux Backdoor "
+"Attempt of 2003](https://freedom-to-tinker.com/2013/10/09/the-linux-backdoor-"
+"attempt-of-2003)"
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:72
+msgid ""
+"Forgotten braces in multi-line `if`: [The Apple goto fail vulnerability]"
+"(https://dwheeler.com/essays/apple-goto-fail.html)"
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:73
+msgid ""
+"Forgotten `break` in a `switch` statement: [The break that broke sudo]"
+"(https://nakedsecurity.sophos.com/2012/05/21/anatomy-of-a-security-hole-the-"
+"break-that-broke-sudo)"
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:75
+msgid ""
+"_How is Rust any better here?_ \n"
+"Safe Rust makes all of these bugs impossible:"
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:78
+msgid "Assignments inside an `if` clause are not supported."
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:79
+msgid "Format strings are checked at compile-time."
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:80
+msgid "Resources are freed at the end of scope via the `Drop` trait."
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:81
+msgid "All `if` clauses require braces."
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:82
+msgid ""
+"`match` (as the Rust equivalent to `switch`) does not fall-through, hence "
+"you can't accidentally forget a `break`."
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:83
+msgid "Buffer slices carry their size and don't rely on a NUL terminator."
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:84
+msgid ""
+"Heap-allocated memory is freed via the `Drop` trait when the corresponding "
+"`Box` leaves the scope."
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:85
+msgid ""
+"Out-of-bounds accesses cause a panic or can be checked via the `get` method "
+"of a slice."
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:86
+msgid "`match` mandates that all cases are handled."
+msgstr ""
+
+#: src/why-rust/an-example-in-c.md:87
+msgid ""
+"Fallible Rust functions return `Result` values that need to be unwrapped and "
+"thereby checked for success. Additionally, the compiler emits a warning if "
+"you miss to check the return value of a function marked with `#[must_use]`."
+msgstr ""
+
+#: src/why-rust/compile-time.md:3
+msgid "Static memory management at compile time:"
+msgstr "Gestión estática de la memoria en tiempo de compilación:"
+
+#: src/why-rust/compile-time.md:5
+msgid "No uninitialized variables."
+msgstr "No hay variables no inicializadas."
+
+#: src/why-rust/compile-time.md:6
+msgid "No memory leaks (_mostly_, see notes)."
+msgstr "No hay pérdidas de memoria (_casi siempre_, consulta las notas)."
+
+#: src/why-rust/compile-time.md:7
+msgid "No double-frees."
+msgstr "No hay errores double free."
+
+#: src/why-rust/compile-time.md:8
+msgid "No use-after-free."
+msgstr "No hay errores use-after-free."
+
+#: src/why-rust/compile-time.md:9
+msgid "No `NULL` pointers."
+msgstr "No hay punteros `NULL`."
+
+#: src/why-rust/compile-time.md:10
+msgid "No forgotten locked mutexes."
+msgstr "No se olvidan las exclusiones mutuas bloqueadas."
+
+#: src/why-rust/compile-time.md:11
+msgid "No data races between threads."
+msgstr "No hay condiciones de carrera de datos entre hilos."
+
+#: src/why-rust/compile-time.md:12
+msgid "No iterator invalidation."
+msgstr "No se invalidan los iteradores."
#: src/why-rust/compile-time.md:16
msgid ""
@@ -2971,31 +3047,11 @@ msgstr ""
"inhabilitados: `r\"\\n\" == \"\\\\n\"`. Puedes insertar comillas dobles con "
"la misma cantidad de `#` a cada lado de ellas:"
-#: src/basic-syntax/scalar-types.md:27
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" println!(r#\"link \"#);\n"
-" println!(\"link \");\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/basic-syntax/scalar-types.md:34
+#: src/basic-syntax/scalar-types.md:35
msgid "Byte strings allow you to create a `&[u8]` value directly:"
msgstr "Las cadenas de bytes te permiten crear un valor `&[u8]` directamente:"
-#: src/basic-syntax/scalar-types.md:36
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" println!(\"{:?}\", b\"abc\");\n"
-" println!(\"{:?}\", &[97, 98, 99]);\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/basic-syntax/scalar-types.md:43
+#: src/basic-syntax/scalar-types.md:45
msgid ""
"All underscores in numbers can be left out, they are for legibility only. So "
"`1_000` can be written as `1000` (or `10_00`), and `123_i64` can be written "
@@ -3033,37 +3089,15 @@ msgstr ""
msgid "Array assignment and access:"
msgstr "Asignación y acceso a arrays:"
-#: src/basic-syntax/compound-types.md:10
-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 ""
-
-#: src/basic-syntax/compound-types.md:18
+#: src/basic-syntax/compound-types.md:19
msgid "Tuple assignment and access:"
msgstr "Asignación y acceso a tuplas:"
-#: src/basic-syntax/compound-types.md:20
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let t: (i8, bool) = (7, true);\n"
-" println!(\"1st index: {}\", t.0);\n"
-" println!(\"2nd index: {}\", t.1);\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/basic-syntax/compound-types.md:32
+#: src/basic-syntax/compound-types.md:34
msgid "Arrays:"
msgstr "Arrays:"
-#: src/basic-syntax/compound-types.md:34
+#: src/basic-syntax/compound-types.md:36
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 "
@@ -3075,11 +3109,11 @@ msgstr ""
"array es *parte de su tipo*, lo que significa que `[u8; 3]` y `[u8; 4]` se "
"consideran dos tipos diferentes."
-#: src/basic-syntax/compound-types.md:38
+#: src/basic-syntax/compound-types.md:40
msgid "We can use literals to assign values to arrays."
msgstr "Podemos usar literales para asignar valores a arrays."
-#: src/basic-syntax/compound-types.md:40
+#: src/basic-syntax/compound-types.md:42
msgid ""
"In the main function, the print statement asks for the debug implementation "
"with the `?` format parameter: `{}` gives the default output, `{:?}` gives "
@@ -3092,7 +3126,7 @@ msgstr ""
"haber usado `{a}` y `{a:?}` sin especificar el valor después de la cadena de "
"formato."
-#: src/basic-syntax/compound-types.md:45
+#: src/basic-syntax/compound-types.md:47
msgid ""
"Adding `#`, eg `{a:#?}`, invokes a \"pretty printing\" format, which can be "
"easier to read."
@@ -3100,19 +3134,19 @@ msgstr ""
"Si se añade `#`, por ejemplo `{a:#?}`, se da formato al texto para facilitar "
"la lectura."
-#: src/basic-syntax/compound-types.md:47
+#: src/basic-syntax/compound-types.md:49
msgid "Tuples:"
msgstr "Tuplas:"
-#: src/basic-syntax/compound-types.md:49
+#: src/basic-syntax/compound-types.md:51
msgid "Like arrays, tuples have a fixed length."
msgstr "Al igual que los arrays, las tuplas tienen una longitud fija."
-#: src/basic-syntax/compound-types.md:51
+#: src/basic-syntax/compound-types.md:53
msgid "Tuples group together values of different types into a compound type."
msgstr "Las tuplas agrupan valores de diferentes tipos en un tipo compuesto."
-#: src/basic-syntax/compound-types.md:53
+#: src/basic-syntax/compound-types.md:55
msgid ""
"Fields of a tuple can be accessed by the period and the index of the value, "
"e.g. `t.0`, `t.1`."
@@ -3120,7 +3154,7 @@ msgstr ""
"Se puede acceder a los campos de una tupla por el punto y el índice del "
"valor, por ejemplo, `t.0`, `t.1`."
-#: src/basic-syntax/compound-types.md:55
+#: src/basic-syntax/compound-types.md:57
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 "
@@ -3133,7 +3167,7 @@ msgstr ""
"función o expresión no tiene valor de retorno, como veremos en una "
"diapositiva posterior."
-#: src/basic-syntax/compound-types.md:59
+#: src/basic-syntax/compound-types.md:61
msgid ""
"You can think of it as `void` that can be familiar to you from other "
"programming languages."
@@ -3145,23 +3179,11 @@ msgstr ""
msgid "Like C++, Rust has references:"
msgstr "Al igual que C++, Rust tiene referencias:"
-#: src/basic-syntax/references.md:5
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let mut x: i32 = 10;\n"
-" let ref_x: &mut i32 = &mut x;\n"
-" *ref_x = 20;\n"
-" println!(\"x: {x}\");\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/basic-syntax/references.md:14
+#: src/basic-syntax/references.md:15
msgid "Some notes:"
msgstr "Algunas notas:"
-#: src/basic-syntax/references.md:16
+#: src/basic-syntax/references.md:17
msgid ""
"We must dereference `ref_x` when assigning to it, similar to C and C++ "
"pointers."
@@ -3169,7 +3191,7 @@ msgstr ""
"Debemos desreferenciar `ref_x` al asignarle un valor, de forma similar a los "
"punteros de C y C++."
-#: src/basic-syntax/references.md:17
+#: src/basic-syntax/references.md:18
msgid ""
"Rust will auto-dereference in some cases, in particular when invoking "
"methods (try `ref_x.count_ones()`)."
@@ -3177,7 +3199,7 @@ msgstr ""
"Rust realizará una desreferencia automática en algunos casos, en especial al "
"invocar métodos (prueba `ref_x.count_ones()`)."
-#: src/basic-syntax/references.md:19
+#: src/basic-syntax/references.md:20
msgid ""
"References that are declared as `mut` can be bound to different values over "
"their lifetime."
@@ -3185,7 +3207,7 @@ msgstr ""
"Las referencias que se declaran como `mut` se pueden vincular a distintos "
"valores durante su tiempo de vida."
-#: src/basic-syntax/references.md:25
+#: src/basic-syntax/references.md:26
msgid ""
"Be sure to note the difference between `let mut ref_x: &i32` and `let ref_x: "
"&mut i32`. The first one represents a mutable reference which can be bound "
@@ -3201,26 +3223,12 @@ msgstr ""
msgid "Rust will statically forbid dangling references:"
msgstr "Rust prohibirá estáticamente las referencias colgantes:"
-#: src/basic-syntax/references-dangling.md:5
-msgid ""
-"```rust,editable,compile_fail\n"
-"fn main() {\n"
-" let ref_x: &i32;\n"
-" {\n"
-" let x: i32 = 10;\n"
-" ref_x = &x;\n"
-" }\n"
-" println!(\"ref_x: {ref_x}\");\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/basic-syntax/references-dangling.md:16
+#: src/basic-syntax/references-dangling.md:17
msgid "A reference is said to \"borrow\" the value it refers to."
msgstr ""
"Se dice que una referencia \"toma prestado\" el valor al que hace referencia."
-#: src/basic-syntax/references-dangling.md:17
+#: src/basic-syntax/references-dangling.md:18
msgid ""
"Rust is tracking the lifetimes of all references to ensure they live long "
"enough."
@@ -3228,7 +3236,7 @@ msgstr ""
"Rust hace un seguimiento del tiempo de vida de todas las referencias para "
"asegurarse de que duran lo suficiente."
-#: src/basic-syntax/references-dangling.md:19
+#: src/basic-syntax/references-dangling.md:20
msgid "We will talk more about borrowing when we get to ownership."
msgstr ""
"Más adelante hablaremos de los préstamos cuando lleguemos a la parte de "
@@ -3238,30 +3246,16 @@ msgstr ""
msgid "A slice gives you a view into a larger collection:"
msgstr "Un _slice_ ofrece una visión de una colección más amplia:"
-#: src/basic-syntax/slices.md:5
-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 ""
-
-#: src/basic-syntax/slices.md:16
+#: src/basic-syntax/slices.md:17
msgid "Slices borrow data from the sliced type."
msgstr "Los slices toman prestados datos del tipo slice."
-#: src/basic-syntax/slices.md:17
+#: src/basic-syntax/slices.md:18
msgid "Question: What happens if you modify `a[3]` right before printing `s`?"
msgstr ""
"Pregunta: ¿Qué ocurre si se modifica `a[3]` justo antes de imprimir `s`?"
-#: src/basic-syntax/slices.md:21
+#: src/basic-syntax/slices.md:22
msgid ""
"We create a slice by borrowing `a` and specifying the starting and ending "
"indexes in brackets."
@@ -3269,7 +3263,7 @@ msgstr ""
"Creamos un slice tomando prestado `a` y especificando entre paréntesis los "
"índices de inicio y de fin."
-#: src/basic-syntax/slices.md:23
+#: src/basic-syntax/slices.md:24
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 "
@@ -3279,7 +3273,7 @@ msgstr ""
"permite eliminar el índice inicial, lo que significa que `&a[0..a.len()]` y "
"`&a[..a.len()]` son idénticos."
-#: src/basic-syntax/slices.md:25
+#: src/basic-syntax/slices.md:26
msgid ""
"The same is true for the last index, so `&a[2..a.len()]` and `&a[2..]` are "
"identical."
@@ -3287,13 +3281,13 @@ msgstr ""
"Lo mismo ocurre con el último índice, por lo que `&a[2..a.len()]` y "
"`&a[2..]` son idénticos."
-#: src/basic-syntax/slices.md:27
+#: src/basic-syntax/slices.md:28
msgid ""
"To easily create a slice of the full array, we can therefore use `&a[..]`."
msgstr ""
"Para crear fácilmente un slice del array completo, podemos usar `&a[..]`."
-#: src/basic-syntax/slices.md:29
+#: src/basic-syntax/slices.md:30
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 "
@@ -3303,7 +3297,7 @@ msgstr ""
"(`&[i32]`) ya no menciona la longitud del array. Esto nos permite realizar "
"cálculos en slices de diferentes tamaños."
-#: src/basic-syntax/slices.md:31
+#: src/basic-syntax/slices.md:32
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. "
@@ -3312,7 +3306,7 @@ msgstr ""
"tiene que permanecer \"con vida\" (en el ámbito) al menos durante el tiempo "
"que dure el slice. "
-#: src/basic-syntax/slices.md:33
+#: src/basic-syntax/slices.md:34
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 "
@@ -3336,22 +3330,29 @@ msgstr "`String` o `str`"
msgid "We can now understand the two string types in Rust:"
msgstr "Ahora podemos entender los dos tipos de cadenas de Rust:"
-#: src/basic-syntax/string-slices.md:5
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let s1: &str = \"World\";\n"
-" println!(\"s1: {s1}\");\n"
-"\n"
-" let mut s2: String = String::from(\"Hello \");\n"
-" println!(\"s2: {s2}\");\n"
-" s2.push_str(s1);\n"
-" println!(\"s2: {s2}\");\n"
-" \n"
-" let s3: &str = &s2[6..];\n"
-" println!(\"s3: {s3}\");\n"
-"}\n"
-"```"
+#: src/basic-syntax/string-slices.md:7 src/traits/read-write.md:36
+#: src/testing/test-modules.md:12
+msgid "\"World\""
+msgstr ""
+
+#: src/basic-syntax/string-slices.md:8
+msgid "\"s1: {s1}\""
+msgstr ""
+
+#: src/basic-syntax/string-slices.md:10 src/memory-management/scope-based.md:16
+#: src/memory-management/garbage-collection.md:15
+#, fuzzy
+#| msgid "Hello World!"
+msgid "\"Hello \""
+msgstr "¡Hola, mundo!"
+
+#: src/basic-syntax/string-slices.md:11 src/basic-syntax/string-slices.md:13
+#: src/ownership/move-semantics.md:9
+msgid "\"s2: {s2}\""
+msgstr ""
+
+#: src/basic-syntax/string-slices.md:16
+msgid "\"s3: {s3}\""
msgstr ""
#: src/basic-syntax/string-slices.md:20
@@ -3434,38 +3435,7 @@ msgstr ""
"Una versión de Rust de la famosa pregunta de la entrevista de [FizzBuzz]"
"(https://es.wikipedia.org/wiki/Fizz_buzz):"
-#: src/basic-syntax/functions.md:5
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" print_fizzbuzz_to(20);\n"
-"}\n"
-"\n"
-"fn is_divisible(n: u32, divisor: u32) -> bool {\n"
-" if divisor == 0 {\n"
-" return false;\n"
-" }\n"
-" n % divisor == 0\n"
-"}\n"
-"\n"
-"fn fizzbuzz(n: u32) -> String {\n"
-" let fizz = if is_divisible(n, 3) { \"fizz\" } else { \"\" };\n"
-" let buzz = if is_divisible(n, 5) { \"buzz\" } else { \"\" };\n"
-" if fizz.is_empty() && buzz.is_empty() {\n"
-" return format!(\"{n}\");\n"
-" }\n"
-" format!(\"{fizz}{buzz}\")\n"
-"}\n"
-"\n"
-"fn print_fizzbuzz_to(n: u32) {\n"
-" for i in 1..=n {\n"
-" println!(\"{}\", fizzbuzz(i));\n"
-" }\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/basic-syntax/functions.md:35
+#: src/basic-syntax/functions.md:36
msgid ""
"We refer in `main` to a function written below. Neither forward declarations "
"nor headers are necessary. "
@@ -3473,7 +3443,7 @@ msgstr ""
"En `main` hacemos referencia a una función escrita más abajo. No se "
"necesitan declaraciones de redirección ni encabezados. "
-#: src/basic-syntax/functions.md:36
+#: src/basic-syntax/functions.md:37
msgid ""
"Declaration parameters are followed by a type (the reverse of some "
"programming languages), then a return type."
@@ -3482,7 +3452,7 @@ msgstr ""
"algunos lenguajes de programación) y, a continuación, de un tipo de "
"resultado devuelto."
-#: src/basic-syntax/functions.md:37
+#: src/basic-syntax/functions.md:38
msgid ""
"The last expression in a function body (or any block) becomes the return "
"value. Simply omit the `;` at the end of the expression."
@@ -3491,7 +3461,7 @@ msgstr ""
"convierte en el valor devuelto. Basta con omitir el carácter `;` al final de "
"la expresión."
-#: src/basic-syntax/functions.md:38
+#: src/basic-syntax/functions.md:39
msgid ""
"Some functions have no return value, and return the 'unit type', `()`. The "
"compiler will infer this if the `-> ()` return type is omitted."
@@ -3499,7 +3469,7 @@ msgstr ""
"Algunas funciones no devuelven ningún valor, devuelven el \"tipo unitario\", "
"`()`. El compilador deducirá esto si se omite el tipo de retorno `-> ()`."
-#: src/basic-syntax/functions.md:39
+#: src/basic-syntax/functions.md:40
msgid ""
"The range expression in the `for` loop in `print_fizzbuzz_to()` contains "
"`=n`, which causes it to include the upper bound."
@@ -3514,29 +3484,40 @@ msgstr ""
"Todos los elementos del lenguaje de Rust se pueden documentar con la "
"sintaxis especial `///`."
-#: src/basic-syntax/rustdoc.md:5
+#: src/basic-syntax/rustdoc.md:6
msgid ""
-"```rust,editable\n"
"/// Determine whether the first argument is divisible by the second "
"argument.\n"
"///\n"
"/// If the second argument is zero, the result is false.\n"
-"fn is_divisible_by(lhs: u32, rhs: u32) -> bool {\n"
-" if rhs == 0 {\n"
-" return false; // Corner case, early return\n"
-" }\n"
-" lhs % rhs == 0 // The last expression in a block is the return "
-"value\n"
-"}\n"
-"```"
+"///\n"
+"/// # Example\n"
+"/// ```\n"
+"/// assert!(is_divisible_by(42, 2));\n"
+"/// ```\n"
+msgstr ""
+
+#: src/basic-syntax/rustdoc.md:16
+msgid "// Corner case, early return\n"
+msgstr ""
+
+#: src/basic-syntax/rustdoc.md:18
+msgid "// The last expression in a block is the return value\n"
msgstr ""
-#: src/basic-syntax/rustdoc.md:17
+#: src/basic-syntax/rustdoc.md:22
+#, fuzzy
+#| msgid ""
+#| "The contents are treated as Markdown. All published Rust library crates "
+#| "are automatically documented at [`docs.rs`](https://docs.rs) using the "
+#| "[rustdoc](https://doc.rust-lang.org/rustdoc/what-is-rustdoc.html) tool. "
+#| "It is idiomatic to document all public items in an API using this pattern."
msgid ""
"The contents are treated as Markdown. All published Rust library crates are "
"automatically documented at [`docs.rs`](https://docs.rs) using the [rustdoc]"
"(https://doc.rust-lang.org/rustdoc/what-is-rustdoc.html) tool. It is "
-"idiomatic to document all public items in an API using this pattern."
+"idiomatic to document all public items in an API using this pattern. Code "
+"snippets can document usage and will be used as unit tests."
msgstr ""
"El contenido se trata como Markdown. Todos los crates de la biblioteca de "
"Rust publicados se documentan automáticamente\n"
@@ -3545,7 +3526,7 @@ msgstr ""
"propio\n"
"documentar todos los elementos públicos de una API usando este patrón."
-#: src/basic-syntax/rustdoc.md:24
+#: src/basic-syntax/rustdoc.md:30
msgid ""
"Show students the generated docs for the `rand` crate at [`docs.rs/rand`]"
"(https://docs.rs/rand)."
@@ -3553,7 +3534,7 @@ msgstr ""
"Muestra a los alumnos los documentos generados para el crate `rand` en "
"[`docs.rs/rand`](https://docs.rs/rand)."
-#: src/basic-syntax/rustdoc.md:27
+#: src/basic-syntax/rustdoc.md:33
msgid ""
"This course does not include rustdoc on slides, just to save space, but in "
"real code they should be present."
@@ -3561,7 +3542,7 @@ msgstr ""
"Este curso no incluye diapositivas sobre rustdoc para ahorrar espacio, pero "
"deben aparecer en el código real."
-#: src/basic-syntax/rustdoc.md:30
+#: src/basic-syntax/rustdoc.md:36
msgid ""
"Inner doc comments are discussed later (in the page on modules) and need not "
"be addressed here."
@@ -3569,7 +3550,7 @@ msgstr ""
"Los comentarios internos de los documentos se tratarán más adelante (en la "
"página de módulos), no es necesario tratarlos aquí."
-#: src/basic-syntax/rustdoc.md:33
+#: src/basic-syntax/rustdoc.md:39
msgid ""
"Rustdoc comments can contain code snippets that we can run and test using "
"`cargo test`. We will discuss these tests in the [Testing section](../"
@@ -3587,31 +3568,12 @@ msgstr ""
"Los métodos son funciones asociadas a un tipo. El argumento `self` de un "
"método es una instancia del tipo al que está asociada:"
-#: src/basic-syntax/methods.md:6
-msgid ""
-"```rust,editable\n"
-"struct Rectangle {\n"
-" width: u32,\n"
-" height: u32,\n"
-"}\n"
-"\n"
-"impl Rectangle {\n"
-" fn area(&self) -> u32 {\n"
-" self.width * self.height\n"
-" }\n"
-"\n"
-" fn inc_width(&mut self, delta: u32) {\n"
-" self.width += delta;\n"
-" }\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let mut rect = Rectangle { width: 10, height: 5 };\n"
-" println!(\"old area: {}\", rect.area());\n"
-" rect.inc_width(5);\n"
-" println!(\"new area: {}\", rect.area());\n"
-"}\n"
-"```"
+#: src/basic-syntax/methods.md:24
+msgid "\"old area: {}\""
+msgstr ""
+
+#: src/basic-syntax/methods.md:26
+msgid "\"new area: {}\""
msgstr ""
#: src/basic-syntax/methods.md:30
@@ -3627,20 +3589,6 @@ msgid "Add a static method called `Rectangle::new` and call this from `main`:"
msgstr ""
"Añade un método estático denominado `Rectangle::new` y llámalo desde `main`:"
-#: src/basic-syntax/methods.md:36
-msgid ""
-"```rust,editable,compile_fail\n"
-"fn new(width: u32, height: u32) -> Rectangle {\n"
-" Rectangle { width, height }\n"
-"}\n"
-"```"
-msgstr ""
-"```rust,editable,compile_fail\n"
-"fn new(width: u32, height: u32) -> Rectangle {\n"
-" Rectangle { width, height }\n"
-"}\n"
-"```"
-
#: src/basic-syntax/methods.md:42
msgid ""
"While _technically_, Rust does not have custom constructors, static methods "
@@ -3698,18 +3646,22 @@ msgstr "A veces, se utilizan macros como alternativa."
msgid "However, function parameters can be generic:"
msgstr "Sin embargo, los parámetros de función pueden ser genéricos:"
-#: src/basic-syntax/functions-interlude.md:14
-msgid ""
-"```rust,editable\n"
-"fn pick_one(a: T, b: T) -> T {\n"
-" if std::process::id() % 2 == 0 { a } else { b }\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" println!(\"coin toss: {}\", pick_one(\"heads\", \"tails\"));\n"
-" println!(\"cash prize: {}\", pick_one(500, 1000));\n"
-"}\n"
-"```"
+#: src/basic-syntax/functions-interlude.md:20
+msgid "\"coin toss: {}\""
+msgstr ""
+
+#: src/basic-syntax/functions-interlude.md:20
+#, fuzzy
+#| msgid "Threads"
+msgid "\"heads\""
+msgstr "Hilos"
+
+#: src/basic-syntax/functions-interlude.md:20
+msgid "\"tails\""
+msgstr ""
+
+#: src/basic-syntax/functions-interlude.md:21
+msgid "\"cash prize: {}\""
msgstr ""
#: src/basic-syntax/functions-interlude.md:27
@@ -3785,23 +3737,7 @@ msgstr ""
"implicit_conversion)). Puedes ver un ejemplo de esto en el siguiente "
"programa:"
-#: src/exercises/day-1/implicit-conversions.md:6
-msgid ""
-"```rust,editable,compile_fail\n"
-"fn multiply(x: i16, y: i16) -> i16 {\n"
-" x * y\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let x: i8 = 15;\n"
-" let y: i16 = 1000;\n"
-"\n"
-" println!(\"{x} * {y} = {}\", multiply(x, y));\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/exercises/day-1/implicit-conversions.md:19
+#: src/exercises/day-1/implicit-conversions.md:20
msgid ""
"The Rust integer types all implement the [`From`](https://doc.rust-lang."
"org/std/convert/trait.From.html) and [`Into`](https://doc.rust-lang.org/"
@@ -3818,7 +3754,7 @@ msgstr ""
"`into()`. Un tipo expresa que se puede convertir en otro tipo implementando "
"estos traits."
-#: src/exercises/day-1/implicit-conversions.md:25
+#: src/exercises/day-1/implicit-conversions.md:26
msgid ""
"The standard library has an implementation of `From for i16`, which "
"means that we can convert a variable `x` of type `i8` to an `i16` by "
@@ -3832,7 +3768,7 @@ msgstr ""
"`From for i16` crea automáticamente una implementación de `Into for "
"i8`."
-#: src/exercises/day-1/implicit-conversions.md:30
+#: src/exercises/day-1/implicit-conversions.md:31
msgid ""
"The same applies for your own `From` implementations for your own types, so "
"it is sufficient to only implement `From` to get a respective `Into` "
@@ -3842,16 +3778,16 @@ msgstr ""
"lo que basta con implementar `From` para obtener la respectiva "
"implementación `Into` de forma automática."
-#: src/exercises/day-1/implicit-conversions.md:33
+#: src/exercises/day-1/implicit-conversions.md:34
msgid "Execute the above program and look at the compiler error."
msgstr "Ejecuta el programa anterior y observa el error del compilador."
-#: src/exercises/day-1/implicit-conversions.md:35
+#: src/exercises/day-1/implicit-conversions.md:36
msgid "Update the code above to use `into()` to do the conversion."
msgstr ""
"Actualiza el código anterior para usar `into()` y realizar la conversión."
-#: src/exercises/day-1/implicit-conversions.md:37
+#: src/exercises/day-1/implicit-conversions.md:38
msgid ""
"Change the types of `x` and `y` to other things (such as `f32`, `bool`, "
"`i128`) to see which types you can convert to which other types. Try "
@@ -3874,13 +3810,6 @@ msgstr "Arrays y bucles`for`"
msgid "We saw that an array can be declared like this:"
msgstr "Hemos visto que un array se puede declarar de la siguiente manera:"
-#: src/exercises/day-1/for-loops.md:5
-msgid ""
-"```rust\n"
-"let array = [10, 20, 30];\n"
-"```"
-msgstr ""
-
#: src/exercises/day-1/for-loops.md:9
msgid ""
"You can print such an array by asking for its debug representation with `{:?}"
@@ -3889,17 +3818,7 @@ msgstr ""
"Puedes imprimir dicho array solicitando su representación de depuración con "
"`{:?}`:"
-#: src/exercises/day-1/for-loops.md:11
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let array = [10, 20, 30];\n"
-" println!(\"array: {array:?}\");\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/exercises/day-1/for-loops.md:18
+#: src/exercises/day-1/for-loops.md:19
msgid ""
"Rust lets you iterate over things like arrays and ranges using the `for` "
"keyword:"
@@ -3907,27 +3826,23 @@ msgstr ""
"Rust te permite iterar sobre elementos como arrays y rangos usando la "
"palabra clave `for`:"
-#: src/exercises/day-1/for-loops.md:21
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let array = [10, 20, 30];\n"
-" print!(\"Iterating over array:\");\n"
-" for n in &array {\n"
-" print!(\" {n}\");\n"
-" }\n"
-" println!();\n"
-"\n"
-" print!(\"Iterating over range:\");\n"
-" for i in 0..3 {\n"
-" print!(\" {}\", array[i]);\n"
-" }\n"
-" println!();\n"
-"}\n"
-"```"
+#: src/exercises/day-1/for-loops.md:25
+msgid "\"Iterating over array:\""
+msgstr ""
+
+#: src/exercises/day-1/for-loops.md:27
+msgid "\" {n}\""
+msgstr ""
+
+#: src/exercises/day-1/for-loops.md:31
+msgid "\"Iterating over range:\""
msgstr ""
-#: src/exercises/day-1/for-loops.md:38
+#: src/exercises/day-1/for-loops.md:33
+msgid "\" {}\""
+msgstr ""
+
+#: src/exercises/day-1/for-loops.md:39
msgid ""
"Use the above to write a function `pretty_print` which pretty-print a matrix "
"and a function `transpose` which will transpose a matrix (turn rows into "
@@ -3937,20 +3852,11 @@ msgstr ""
"para dar formato al texto de la matriz y una función `transpose` que "
"transponga una matriz (convertir filas en columnas):"
-#: src/exercises/day-1/for-loops.md:41
-msgid ""
-"```bob\n"
-" ⎛⎡1 2 3⎤⎞ ⎡1 4 7⎤\n"
-"\"transpose\"⎜⎢4 5 6⎥⎟ \"==\"⎢2 5 8⎥\n"
-" ⎝⎣7 8 9⎦⎠ ⎣3 6 9⎦\n"
-"```"
-msgstr ""
-
-#: src/exercises/day-1/for-loops.md:47
+#: src/exercises/day-1/for-loops.md:49
msgid "Hard-code both functions to operate on 3 × 3 matrices."
msgstr "Codifica ambas funciones para que operen con matrices de 3 × 3."
-#: src/exercises/day-1/for-loops.md:49
+#: src/exercises/day-1/for-loops.md:51
msgid ""
"Copy the code below to and implement the "
"functions:"
@@ -3958,42 +3864,45 @@ msgstr ""
"Copia el siguiente fragmento de código en e "
"implementa las funciones:"
-#: src/exercises/day-1/for-loops.md:52
-msgid ""
+#: src/exercises/day-1/for-loops.md:55 src/exercises/day-1/luhn.md:26
+#: src/exercises/day-2/health-statistics.md:14
+#: src/exercises/day-2/strings-iterators.md:13
+#: src/exercises/day-3/simple-gui.md:20
+#: src/exercises/day-3/points-polygons.md:8
+#: src/exercises/day-3/safe-ffi-wrapper.md:49
+#, fuzzy
+#| msgid ""
+#| "```rust,should_panic\n"
+#| "// TODO: remove this when you're done with your implementation.\n"
+#| "#![allow(unused_variables, dead_code)]\n"
+#| "```"
+msgid "// TODO: remove this when you're done with your implementation.\n"
+msgstr ""
"```rust,should_panic\n"
-"// TODO: remove this when you're done with your implementation.\n"
+"// TODO: borra esto cuando termines de implementarlo.\n"
"#![allow(unused_variables, dead_code)]\n"
-"\n"
-"fn transpose(matrix: [[i32; 3]; 3]) -> [[i32; 3]; 3] {\n"
-" unimplemented!()\n"
-"}\n"
-"\n"
-"fn pretty_print(matrix: &[[i32; 3]; 3]) {\n"
-" unimplemented!()\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let matrix = [\n"
-" [101, 102, 103], // <-- the comment makes rustfmt add a newline\n"
-" [201, 202, 203],\n"
-" [301, 302, 303],\n"
-" ];\n"
-"\n"
-" println!(\"matrix:\");\n"
-" pretty_print(&matrix);\n"
-"\n"
-" let transposed = transpose(matrix);\n"
-" println!(\"transposed:\");\n"
-" pretty_print(&transposed);\n"
-"}\n"
"```"
+
+#: src/exercises/day-1/for-loops.md:68
+#: src/exercises/day-1/solutions-morning.md:44
+msgid "// <-- the comment makes rustfmt add a newline\n"
+msgstr ""
+
+#: src/exercises/day-1/for-loops.md:73
+#: src/exercises/day-1/solutions-morning.md:49
+msgid "\"matrix:\""
+msgstr ""
+
+#: src/exercises/day-1/for-loops.md:77
+#: src/exercises/day-1/solutions-morning.md:53
+msgid "\"transposed:\""
msgstr ""
-#: src/exercises/day-1/for-loops.md:80
+#: src/exercises/day-1/for-loops.md:82
msgid "Bonus Question"
msgstr "Pregunta Extra"
-#: src/exercises/day-1/for-loops.md:82
+#: src/exercises/day-1/for-loops.md:84
msgid ""
"Could you use `&[i32]` slices instead of hard-coded 3 × 3 matrices for your "
"argument and return types? Something like `&[&[i32]]` for a two-dimensional "
@@ -4004,7 +3913,7 @@ msgstr ""
"ejemplo, `&[&[i32]]` para un slice de slices de dos dimensiones. ¿Por qué? "
"¿Por qué no?"
-#: src/exercises/day-1/for-loops.md:87
+#: src/exercises/day-1/for-loops.md:89
msgid ""
"See the [`ndarray` crate](https://docs.rs/ndarray/) for a production quality "
"implementation."
@@ -4012,7 +3921,7 @@ msgstr ""
"Consulta el [crate `ndarray`](https://docs.rs/ndarray/) para obtener una "
"implementación con calidad de producción."
-#: src/exercises/day-1/for-loops.md:92
+#: src/exercises/day-1/for-loops.md:94
msgid ""
"The solution and the answer to the bonus section are available in the "
"[Solution](solutions-morning.md#arrays-and-for-loops) section."
@@ -4020,7 +3929,7 @@ msgstr ""
"La solución y la respuesta a la pregunta extra están disponibles en la "
"sección [soluciones](solutions-morning.md#arrays-and-for-loops)."
-#: src/exercises/day-1/for-loops.md:95
+#: src/exercises/day-1/for-loops.md:97
msgid ""
"The use of the reference `&array` within `for n in &array` is a subtle "
"preview of issues of ownership that will come later in the afternoon."
@@ -4029,11 +3938,11 @@ msgstr ""
"previa sutil de los problemas de propiedad que se tratarán más tarde por la "
"tarde."
-#: src/exercises/day-1/for-loops.md:98
+#: src/exercises/day-1/for-loops.md:100
msgid "Without the `&`..."
msgstr "Sin el `&`..."
-#: src/exercises/day-1/for-loops.md:99
+#: src/exercises/day-1/for-loops.md:101
msgid ""
"The loop would have been one that consumes the array. This is a change "
"[introduced in the 2021 Edition](https://doc.rust-lang.org/edition-guide/"
@@ -4043,7 +3952,7 @@ msgstr ""
"[introducido en la edición de 2021](https://doc.rust-lang.org/edition-guide/"
"rust-2021/IntoIterator-for-arrays.html)."
-#: src/exercises/day-1/for-loops.md:102
+#: src/exercises/day-1/for-loops.md:104
msgid ""
"An implicit array copy would have occurred. Since `i32` is a copy type, "
"then `[i32; 3]` is also a copy type."
@@ -4071,29 +3980,7 @@ msgstr ""
"En Rust, un bloque contiene una secuencia de expresiones. Cada bloque tiene "
"un tipo y un valor, que son los de la última expresión del bloque:"
-#: src/control-flow/blocks.md:7
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let x = {\n"
-" let y = 10;\n"
-" println!(\"y: {y}\");\n"
-" let z = {\n"
-" let w = {\n"
-" 3 + 4\n"
-" };\n"
-" println!(\"w: {w}\");\n"
-" y * w\n"
-" };\n"
-" println!(\"z: {z}\");\n"
-" z - y\n"
-" };\n"
-" println!(\"x: {x}\");\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/control-flow/blocks.md:26
+#: src/control-flow/blocks.md:27
msgid ""
"If the last expression ends with `;`, then the resulting value and type is "
"`()`."
@@ -4101,7 +3988,7 @@ msgstr ""
"Si la última expresión termina con `;`, el tipo y el valor resultante será "
"`()`."
-#: src/control-flow/blocks.md:28
+#: src/control-flow/blocks.md:29
msgid ""
"The same rule is used for functions: the value of the function body is the "
"return value:"
@@ -4109,26 +3996,13 @@ msgstr ""
"Se utiliza la misma regla para las funciones: el valor del cuerpo de la "
"función es el valor devuelto:"
-#: src/control-flow/blocks.md:31
-msgid ""
-"```rust,editable\n"
-"fn double(x: i32) -> i32 {\n"
-" x + x\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" println!(\"doubled: {}\", double(7));\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/control-flow/blocks.md:43 src/enums.md:34 src/enums/sizes.md:28
+#: src/control-flow/blocks.md:45 src/enums.md:34 src/enums/sizes.md:28
#: src/pattern-matching.md:25 src/pattern-matching/match-guards.md:22
#: src/structs.md:31 src/methods.md:30 src/methods/example.md:46
msgid "Key Points:"
msgstr "Puntos Clave:"
-#: src/control-flow/blocks.md:44
+#: src/control-flow/blocks.md:46
msgid ""
"The point of this slide is to show that blocks have a type and value in "
"Rust. "
@@ -4136,7 +4010,7 @@ msgstr ""
"El objetivo de esta diapositiva es mostrar que los bloques tienen un tipo y "
"un valor en Rust. "
-#: src/control-flow/blocks.md:45
+#: src/control-flow/blocks.md:47
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`."
@@ -4157,20 +4031,6 @@ msgstr ""
"expressions/if-expr.html#if-expressions) de la misma forma que en otros "
"lenguajes:"
-#: src/control-flow/if-expressions.md:7
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let mut x = 10;\n"
-" if x % 2 == 0 {\n"
-" x = x / 2;\n"
-" } else {\n"
-" x = 3 * x + 1;\n"
-" }\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/control-flow/if-expressions.md:18
msgid ""
"In addition, you can use `if` as an expression. The last expression of each "
@@ -4179,20 +4039,6 @@ msgstr ""
"Además, puedes utilizar `if` como expresión. La última expresión de cada "
"bloque se convierte en el valor de la expresión `if`:"
-#: src/control-flow/if-expressions.md:22
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let mut x = 10;\n"
-" x = if x % 2 == 0 {\n"
-" x / 2\n"
-" } else {\n"
-" 3 * x + 1\n"
-" };\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/control-flow/if-expressions.md:35
msgid ""
"Because `if` is an expression and must have a particular type, both of its "
@@ -4219,37 +4065,20 @@ msgstr ""
"md). Llamará automáticamente a `into_iter()` en la expresión y después "
"iterará sobre ella:"
-#: src/control-flow/for-expressions.md:7
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let v = vec![10, 20, 30];\n"
-"\n"
-" for x in v {\n"
-" println!(\"x: {x}\");\n"
-" }\n"
-" \n"
-" for i in (0..10).step_by(2) {\n"
-" println!(\"i: {i}\");\n"
-" }\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/control-flow/for-expressions.md:21
+#: src/control-flow/for-expressions.md:22
msgid "You can use `break` and `continue` here as usual."
msgstr "Aquí puedes usar `break` y `continue` como de costumbre."
-#: src/control-flow/for-expressions.md:25
+#: src/control-flow/for-expressions.md:26
msgid "Index iteration is not a special syntax in Rust for just that case."
msgstr ""
"La iteración de índices no es una sintaxis especial en Rust para ese caso."
-#: src/control-flow/for-expressions.md:26
+#: src/control-flow/for-expressions.md:27
msgid "`(0..10)` is a range that implements an `Iterator` trait. "
msgstr "`(0..10)` es un rango que implementa un `Iterator` trait."
-#: src/control-flow/for-expressions.md:27
+#: src/control-flow/for-expressions.md:28
msgid ""
"`step_by` is a method that returns another `Iterator` that skips every other "
"element. "
@@ -4257,7 +4086,7 @@ msgstr ""
"`step_by` es un método que devuelve otro `Iterator` que salta cada otro "
"elemento."
-#: src/control-flow/for-expressions.md:28
+#: src/control-flow/for-expressions.md:29
msgid ""
"Modify the elements in the vector and explain the compiler errors. Change "
"vector `v` to be mutable and the for loop to `for x in v.iter_mut()`."
@@ -4277,23 +4106,6 @@ msgstr ""
"La [palabra clave `while`](https://doc.rust-lang.org/reference/expressions/"
"loop-expr.html#predicate-loops) es muy similar a otros lenguajes:"
-#: src/control-flow/while-expressions.md:6
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let mut x = 10;\n"
-" while x != 1 {\n"
-" x = if x % 2 == 0 {\n"
-" x / 2\n"
-" } else {\n"
-" 3 * x + 1\n"
-" };\n"
-" }\n"
-" println!(\"Final x: {x}\");\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/control-flow/break-continue.md:1
msgid "`break` and `continue`"
msgstr "`break` y `continue`"
@@ -4323,28 +4135,7 @@ msgstr ""
"De forma opcional, tanto `continue` como `break` pueden utilizar un "
"argumento de etiqueta para interrumpir los bucles anidados:"
-#: src/control-flow/break-continue.md:10
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let v = vec![10, 20, 30];\n"
-" let mut iter = v.into_iter();\n"
-" 'outer: while let Some(x) = iter.next() {\n"
-" println!(\"x: {x}\");\n"
-" let mut i = 0;\n"
-" while i < x {\n"
-" println!(\"x: {x}, i: {i}\");\n"
-" i += 1;\n"
-" if i == 3 {\n"
-" break 'outer;\n"
-" }\n"
-" }\n"
-" }\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/control-flow/break-continue.md:28
+#: src/control-flow/break-continue.md:29
msgid ""
"In this case we break the outer loop after 3 iterations of the inner loop."
msgstr ""
@@ -4367,31 +4158,11 @@ msgstr ""
msgid "Here you must either `break` or `return` to stop the loop:"
msgstr "Para detener el bucle, debes usar `break` o `return`:"
-#: src/control-flow/loop-expressions.md:8
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let mut x = 10;\n"
-" loop {\n"
-" x = if x % 2 == 0 {\n"
-" x / 2\n"
-" } else {\n"
-" 3 * x + 1\n"
-" };\n"
-" if x == 1 {\n"
-" break;\n"
-" }\n"
-" }\n"
-" println!(\"Final x: {x}\");\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/control-flow/loop-expressions.md:27
+#: src/control-flow/loop-expressions.md:28
msgid "Break the `loop` with a value (e.g. `break 8`) and print it out."
msgstr "Interrumpe `loop` con un valor (por ejemplo, `break 8`) e imprímelo."
-#: src/control-flow/loop-expressions.md:28
+#: src/control-flow/loop-expressions.md:29
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 "
@@ -4409,19 +4180,7 @@ msgstr ""
"Rust ofrece seguridad de tipos mediante tipado estático. De forma "
"predeterminada, los enlaces a variables son inmutables:"
-#: src/basic-syntax/variables.md:6
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let x: i32 = 10;\n"
-" println!(\"x: {x}\");\n"
-" // x = 20;\n"
-" // println!(\"x: {x}\");\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/basic-syntax/variables.md:17
+#: src/basic-syntax/variables.md:18
msgid ""
"Due to type inference the `i32` is optional. We will gradually show the "
"types less and less as the course progresses."
@@ -4433,29 +4192,7 @@ msgstr ""
msgid "Rust will look at how the variable is _used_ to determine the type:"
msgstr "Rust consultará cómo se _usa_ la variable para determinar el tipo:"
-#: src/basic-syntax/type-inference.md:5
-msgid ""
-"```rust,editable\n"
-"fn takes_u32(x: u32) {\n"
-" println!(\"u32: {x}\");\n"
-"}\n"
-"\n"
-"fn takes_i8(y: i8) {\n"
-" println!(\"i8: {y}\");\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let x = 10;\n"
-" let y = 20;\n"
-"\n"
-" takes_u32(x);\n"
-" takes_i8(y);\n"
-" // takes_u32(y);\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/basic-syntax/type-inference.md:26
+#: src/basic-syntax/type-inference.md:27
msgid ""
"This slide demonstrates how the Rust compiler infers types based on "
"constraints given by variable declarations and usages."
@@ -4463,7 +4200,7 @@ msgstr ""
"Esta diapositiva muestra cómo el compilador de Rust infiere tipos basándose "
"en restricciones proporcionadas por declaraciones y usos de variables."
-#: src/basic-syntax/type-inference.md:28
+#: src/basic-syntax/type-inference.md:29
msgid ""
"It is very important to emphasize that variables declared like this are not "
"of some sort of dynamic \"any type\" that can hold any data. The machine "
@@ -4477,7 +4214,7 @@ msgstr ""
"de un tipo. El compilador hace el trabajo por nosotros y nos ayuda a "
"escribir código más conciso."
-#: src/basic-syntax/type-inference.md:32
+#: src/basic-syntax/type-inference.md:33
msgid ""
"The following code tells the compiler to copy into a certain generic "
"container without the code ever explicitly specifying the contained type, "
@@ -4487,22 +4224,7 @@ msgstr ""
"determinado contenedor genérico sin que el código especifique explícitamente "
"el tipo contenido utilizando `_` como marcador de posición:"
-#: src/basic-syntax/type-inference.md:34
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let mut v = Vec::new();\n"
-" v.push((10, false));\n"
-" v.push((20, true));\n"
-" println!(\"v: {v:?}\");\n"
-"\n"
-" let vv = v.iter().collect::>();\n"
-" println!(\"vv: {vv:?}\");\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/basic-syntax/type-inference.md:46
+#: src/basic-syntax/type-inference.md:48
msgid ""
"[`collect`](https://doc.rust-lang.org/stable/std/iter/trait.Iterator."
"html#method.collect) relies on [`FromIterator`](https://doc.rust-lang.org/"
@@ -4542,29 +4264,7 @@ msgstr ""
"Las variables constantes se evalúan en tiempo de compilación y sus valores "
"se insertan dondequiera que se utilicen:"
-#: src/basic-syntax/static-and-const.md:11
-msgid ""
-"```rust,editable\n"
-"const DIGEST_SIZE: usize = 3;\n"
-"const ZERO: Option = Some(42);\n"
-"\n"
-"fn compute_digest(text: &str) -> [u8; DIGEST_SIZE] {\n"
-" let mut digest = [ZERO.unwrap_or(0); DIGEST_SIZE];\n"
-" for (idx, &b) in text.as_bytes().iter().enumerate() {\n"
-" digest[idx % DIGEST_SIZE] = digest[idx % DIGEST_SIZE]."
-"wrapping_add(b);\n"
-" }\n"
-" digest\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let digest = compute_digest(\"Hello\");\n"
-" println!(\"Digest: {digest:?}\");\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/basic-syntax/static-and-const.md:29
+#: src/basic-syntax/static-and-const.md:30
#, fuzzy
msgid ""
"According to the [Rust RFC Book](https://rust-lang.github.io/rfcs/0246-const-"
@@ -4573,7 +4273,7 @@ msgstr ""
"Según el libro [Rust RFC Book](https://rust-lang.github.io/rfcs/0246-const-"
"vs-static.html), se insertan cuando se utilizan."
-#: src/basic-syntax/static-and-const.md:31
+#: src/basic-syntax/static-and-const.md:32
msgid ""
"Only functions marked `const` can be called at compile time to generate "
"`const` values. `const` functions can however be called at runtime."
@@ -4582,11 +4282,11 @@ msgstr ""
"compilación para generar valores `const`. Sin embargo, las funciones `const` "
"se pueden llamar en _runtime_."
-#: src/basic-syntax/static-and-const.md:33
+#: src/basic-syntax/static-and-const.md:34
msgid "`static`"
msgstr "`static`"
-#: src/basic-syntax/static-and-const.md:35
+#: src/basic-syntax/static-and-const.md:36
msgid ""
"Static variables will live during the whole execution of the program, and "
"therefore will not move:"
@@ -4594,18 +4294,17 @@ msgstr ""
"Las variables estáticas vivirán durante toda la ejecución del programa y, "
"por lo tanto, no se moverán:"
-#: src/basic-syntax/static-and-const.md:37
-msgid ""
-"```rust,editable\n"
-"static BANNER: &str = \"Welcome to RustOS 3.14\";\n"
-"\n"
-"fn main() {\n"
-" println!(\"{BANNER}\");\n"
-"}\n"
-"```"
+#: src/basic-syntax/static-and-const.md:39
+#, fuzzy
+#| msgid "Welcome to Day 1"
+msgid "\"Welcome to RustOS 3.14\""
+msgstr "Te damos la bienvenida al Día 1"
+
+#: src/basic-syntax/static-and-const.md:42
+msgid "\"{BANNER}\""
msgstr ""
-#: src/basic-syntax/static-and-const.md:45
+#: src/basic-syntax/static-and-const.md:46
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 "
@@ -4621,7 +4320,7 @@ msgstr ""
"Cuando un valor de ámbito global no tiene ningún motivo para necesitar "
"identidad de objeto, se suele preferir `const`."
-#: src/basic-syntax/static-and-const.md:49
+#: src/basic-syntax/static-and-const.md:50
msgid ""
"Because `static` variables are accessible from any thread, they must be "
"`Sync`. Interior mutability is possible through a [`Mutex`](https://doc.rust-"
@@ -4636,13 +4335,13 @@ msgstr ""
"código `unsafe`. Veremos la [mutación de datos estáticos](../unsafe/mutable-"
"static-variables.md) en el capítulo sobre Rust inseguro."
-#: src/basic-syntax/static-and-const.md:57
+#: src/basic-syntax/static-and-const.md:58
msgid "Mention that `const` behaves semantically similar to C++'s `constexpr`."
msgstr ""
"Menciona que `const` se comporta semánticamente de forma similar a "
"`constexpr` de C++."
-#: src/basic-syntax/static-and-const.md:58
+#: src/basic-syntax/static-and-const.md:59
msgid ""
"`static`, on the other hand, is much more similar to a `const` or mutable "
"global variable in C++."
@@ -4650,7 +4349,7 @@ msgstr ""
"Por su parte, `static` se parece mucho más a `const` o a una variable global "
"mutable de C++."
-#: src/basic-syntax/static-and-const.md:59
+#: src/basic-syntax/static-and-const.md:60
msgid ""
"`static` provides object identity: an address in memory and state as "
"required by types with interior mutability such as `Mutex`."
@@ -4659,7 +4358,7 @@ msgstr ""
"en el estado que requieren los tipos con mutabilidad interior, como "
"`Mutex`."
-#: src/basic-syntax/static-and-const.md:60
+#: src/basic-syntax/static-and-const.md:61
msgid ""
"It isn't super common that one would need a runtime evaluated constant, but "
"it is helpful and safer than using a static."
@@ -4667,69 +4366,69 @@ msgstr ""
"No es muy habitual que se necesite una constante evaluada en _runtime_, pero "
"es útil y más seguro que usar una estática."
-#: src/basic-syntax/static-and-const.md:61
+#: src/basic-syntax/static-and-const.md:62
msgid "`thread_local` data can be created with the macro `std::thread_local`."
msgstr ""
"Datos del `thread_local` se pueden crear con la macro `std::thread_local`."
-#: src/basic-syntax/static-and-const.md:63
+#: src/basic-syntax/static-and-const.md:64
msgid "Properties table:"
msgstr "Tabla de Propiedades:"
-#: src/basic-syntax/static-and-const.md:65
+#: src/basic-syntax/static-and-const.md:66
msgid "Property"
msgstr "Propiedad"
-#: src/basic-syntax/static-and-const.md:65
+#: src/basic-syntax/static-and-const.md:66
msgid "Static"
msgstr "Estático"
-#: src/basic-syntax/static-and-const.md:65
+#: src/basic-syntax/static-and-const.md:66
msgid "Constant"
msgstr "Constante"
-#: src/basic-syntax/static-and-const.md:67
+#: src/basic-syntax/static-and-const.md:68
msgid "Has an address in memory"
msgstr "Tiene una dirección en la memoria"
-#: src/basic-syntax/static-and-const.md:67
#: src/basic-syntax/static-and-const.md:68
-#: src/basic-syntax/static-and-const.md:70
+#: src/basic-syntax/static-and-const.md:69
#: src/basic-syntax/static-and-const.md:71
+#: src/basic-syntax/static-and-const.md:72
msgid "Yes"
msgstr "Sí"
-#: src/basic-syntax/static-and-const.md:67
+#: src/basic-syntax/static-and-const.md:68
msgid "No (inlined)"
msgstr "No (insertado)"
-#: src/basic-syntax/static-and-const.md:68
+#: src/basic-syntax/static-and-const.md:69
msgid "Lives for the entire duration of the program"
msgstr "Vive durante toda la ejecución del programa"
-#: src/basic-syntax/static-and-const.md:68
#: src/basic-syntax/static-and-const.md:69
-#: src/basic-syntax/static-and-const.md:71
+#: src/basic-syntax/static-and-const.md:70
+#: src/basic-syntax/static-and-const.md:72
msgid "No"
msgstr "No"
-#: src/basic-syntax/static-and-const.md:69
+#: src/basic-syntax/static-and-const.md:70
msgid "Can be mutable"
msgstr "Puede ser mutable"
-#: src/basic-syntax/static-and-const.md:69
+#: src/basic-syntax/static-and-const.md:70
msgid "Yes (unsafe)"
msgstr "Sí (inseguro)"
-#: src/basic-syntax/static-and-const.md:70
+#: src/basic-syntax/static-and-const.md:71
msgid "Evaluated at compile time"
msgstr "Evaluado en tiempo de compilación"
-#: src/basic-syntax/static-and-const.md:70
+#: src/basic-syntax/static-and-const.md:71
msgid "Yes (initialised at compile time)"
msgstr "Sí (inicializado en tiempo de compilación)"
-#: src/basic-syntax/static-and-const.md:71
+#: src/basic-syntax/static-and-const.md:72
msgid "Inlined wherever it is used"
msgstr "Insertado dondequiera que se utilice"
@@ -4741,24 +4440,25 @@ msgstr ""
"Puedes sombrear variables, tanto las de ámbitos externos como las del propio "
"ámbito:"
-#: src/basic-syntax/scopes-shadowing.md:6
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let a = 10;\n"
-" println!(\"before: {a}\");\n"
-"\n"
-" {\n"
-" let a = \"hello\";\n"
-" println!(\"inner scope: {a}\");\n"
-"\n"
-" let a = true;\n"
-" println!(\"shadowed in inner scope: {a}\");\n"
-" }\n"
-"\n"
-" println!(\"after: {a}\");\n"
-"}\n"
-"```"
+#: src/basic-syntax/scopes-shadowing.md:9
+msgid "\"before: {a}\""
+msgstr ""
+
+#: src/basic-syntax/scopes-shadowing.md:12 src/traits/from-into.md:7
+#: src/traits/from-into.md:19
+msgid "\"hello\""
+msgstr ""
+
+#: src/basic-syntax/scopes-shadowing.md:13
+msgid "\"inner scope: {a}\""
+msgstr ""
+
+#: src/basic-syntax/scopes-shadowing.md:16
+msgid "\"shadowed in inner scope: {a}\""
+msgstr ""
+
+#: src/basic-syntax/scopes-shadowing.md:19
+msgid "\"after: {a}\""
msgstr ""
#: src/basic-syntax/scopes-shadowing.md:25
@@ -4794,18 +4494,6 @@ msgstr ""
"reutilizar ubicaciones de memoria cuando sombrea una variable inmutable en "
"un ámbito, incluso si el tipo no cambia."
-#: src/basic-syntax/scopes-shadowing.md:30
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let a = 1;\n"
-" let b = &a;\n"
-" let a = a + 1;\n"
-" println!(\"{a} {b}\");\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/enums.md:3
msgid ""
"The `enum` keyword allows the creation of a type which has a few different "
@@ -4813,59 +4501,17 @@ msgid ""
msgstr ""
"La palabra clave `enum` permite crear un tipo que tiene diferentes variantes:"
-#: src/enums.md:6
-msgid ""
-"```rust,editable\n"
-"fn generate_random_number() -> i32 {\n"
-" // Implementation based on https://xkcd.com/221/\n"
-" 4 // Chosen by fair dice roll. Guaranteed to be random.\n"
-"}\n"
-"\n"
-"#[derive(Debug)]\n"
-"enum CoinFlip {\n"
-" Heads,\n"
-" Tails,\n"
-"}\n"
-"\n"
-"fn flip_coin() -> CoinFlip {\n"
-" let random_number = generate_random_number();\n"
-" if random_number % 2 == 0 {\n"
-" return CoinFlip::Heads;\n"
-" } else {\n"
-" return CoinFlip::Tails;\n"
-" }\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" println!(\"You got: {:?}\", flip_coin());\n"
-"}\n"
-"```"
+#: src/enums.md:8
+msgid "// Implementation based on https://xkcd.com/221/\n"
+msgstr ""
+
+#: src/enums.md:9
+msgid "// Chosen by fair dice roll. Guaranteed to be random.\n"
+msgstr ""
+
+#: src/enums.md:28
+msgid "\"You got: {:?}\""
msgstr ""
-"```rust,editable\n"
-"fn generate_random_number() -> i32 {\n"
-" // Implementation based on https://xkcd.com/221/\n"
-" 4 // Chosen by fair dice roll. Guaranteed to be random.\n"
-"}\n"
-"\n"
-"#[derive(Debug)]\n"
-"enum CoinFlip {\n"
-" Heads,\n"
-" Tails,\n"
-"}\n"
-"\n"
-"fn flip_coin() -> CoinFlip {\n"
-" let random_number = generate_random_number();\n"
-" if random_number % 2 == 0 {\n"
-" return CoinFlip::Heads;\n"
-" } else {\n"
-" return CoinFlip::Tails;\n"
-" }\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" println!(\"You got: {:?}\", flip_coin());\n"
-"}\n"
-"```"
#: src/enums.md:36
msgid "Enumerations allow you to collect a set of values under one type"
@@ -4918,34 +4564,34 @@ msgstr ""
"contienen datos. Después, puedes usar la instrucción `match` para extraer "
"los datos de cada variante:"
-#: src/enums/variant-payloads.md:6
-msgid ""
-"```rust,editable\n"
-"enum WebEvent {\n"
-" PageLoad, // Variant without payload\n"
-" KeyPress(char), // Tuple struct variant\n"
-" Click { x: i64, y: i64 }, // Full struct variant\n"
-"}\n"
-"\n"
-"#[rustfmt::skip]\n"
-"fn inspect(event: WebEvent) {\n"
-" match event {\n"
-" WebEvent::PageLoad => println!(\"page loaded\"),\n"
-" WebEvent::KeyPress(c) => println!(\"pressed '{c}'\"),\n"
-" WebEvent::Click { x, y } => println!(\"clicked at x={x}, y={y}\"),\n"
-" }\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let load = WebEvent::PageLoad;\n"
-" let press = WebEvent::KeyPress('x');\n"
-" let click = WebEvent::Click { x: 20, y: 80 };\n"
-"\n"
-" inspect(load);\n"
-" inspect(press);\n"
-" inspect(click);\n"
-"}\n"
-"```"
+#: src/enums/variant-payloads.md:8
+#, fuzzy
+#| msgid "Variant Payloads"
+msgid "// Variant without payload\n"
+msgstr "Payloads Variantes"
+
+#: src/enums/variant-payloads.md:9
+msgid "// Tuple struct variant\n"
+msgstr ""
+
+#: src/enums/variant-payloads.md:10
+msgid "// Full struct variant\n"
+msgstr ""
+
+#: src/enums/variant-payloads.md:16
+msgid "\"page loaded\""
+msgstr ""
+
+#: src/enums/variant-payloads.md:17
+msgid "\"pressed '{c}'\""
+msgstr ""
+
+#: src/enums/variant-payloads.md:18
+msgid "\"clicked at x={x}, y={y}\""
+msgstr ""
+
+#: src/enums/variant-payloads.md:24 src/pattern-matching.md:10
+msgid "'x'"
msgstr ""
#: src/enums/variant-payloads.md:35
@@ -5029,27 +4675,11 @@ msgstr ""
"Las enumeraciones de Rust son densamente empaquetadas, ya que tienen en "
"cuenta las restricciones debidas a la alineación:"
-#: src/enums/sizes.md:5
-msgid ""
-"```rust,editable\n"
-"use std::any::type_name;\n"
-"use std::mem::{align_of, size_of};\n"
-"\n"
-"fn dbg_size() {\n"
-" println!(\"{}: size {} bytes, align: {} bytes\",\n"
-" type_name::(), size_of::(), align_of::());\n"
-"}\n"
-"\n"
-"enum Foo {\n"
-" A,\n"
-" B,\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" dbg_size::();\n"
-"}\n"
-"```"
-msgstr ""
+#: src/enums/sizes.md:10
+#, fuzzy
+#| msgid "`dbg_size!(bool)`: size 1 bytes, align: 1 bytes,"
+msgid "\"{}: size {} bytes, align: {} bytes\""
+msgstr "`dbg_size!(bool)`: tamaño de 1 byte, alineación de 1 byte,"
#: src/enums/sizes.md:24
msgid ""
@@ -5074,25 +4704,7 @@ msgstr ""
"Puedes controlar el discriminante si es necesario (por ejemplo, para "
"asegurar la compatibilidad con C):"
-#: src/enums/sizes.md:34
-msgid ""
-"```rust,editable\n"
-"#[repr(u32)]\n"
-"enum Bar {\n"
-" A, // 0\n"
-" B = 10000,\n"
-" C, // 10001\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" println!(\"A: {}\", Bar::A as u32);\n"
-" println!(\"B: {}\", Bar::B as u32);\n"
-" println!(\"C: {}\", Bar::C as u32);\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/enums/sizes.md:49
+#: src/enums/sizes.md:50
msgid ""
"Without `repr`, the discriminant type takes 2 bytes, because 10001 fits 2 "
"bytes."
@@ -5100,15 +4712,15 @@ msgstr ""
"Sin `repr`, el tipo discriminante ocupa 2 bytes, debido a que 10001 se cabe "
"en 2 bytes."
-#: src/enums/sizes.md:53
+#: src/enums/sizes.md:54
msgid "Try out other types such as"
msgstr "Prueba otros tipos, como"
-#: src/enums/sizes.md:55
+#: src/enums/sizes.md:56
msgid "`dbg_size!(bool)`: size 1 bytes, align: 1 bytes,"
msgstr "`dbg_size!(bool)`: tamaño de 1 byte, alineación de 1 byte,"
-#: src/enums/sizes.md:56
+#: src/enums/sizes.md:57
msgid ""
"`dbg_size!(Option)`: size 1 bytes, align: 1 bytes (niche optimization, "
"see below),"
@@ -5116,13 +4728,13 @@ msgstr ""
"`dbg_size!(Option)`: tamaño de 1 byte, alineación de 1 byte "
"(optimización de nichos, consulta más abajo),"
-#: src/enums/sizes.md:57
+#: src/enums/sizes.md:58
msgid "`dbg_size!(&i32)`: size 8 bytes, align: 8 bytes (on a 64-bit machine),"
msgstr ""
"`dbg_size!(&i32)`: tamaño de 8 bytes, alineación de 8 bytes (en una máquina "
"de 64 bits),"
-#: src/enums/sizes.md:58
+#: src/enums/sizes.md:59
msgid ""
"`dbg_size!(Option<&i32>)`: size 8 bytes, align: 8 bytes (null pointer "
"optimization, see below)."
@@ -5130,7 +4742,17 @@ msgstr ""
"`dbg_size!(Option<&i32>)`: tamaño de 8 bytes, alineación de 8 bytes "
"(optimización del puntero nulo, consulta más abajo)."
-#: src/enums/sizes.md:60
+#: src/enums/sizes.md:61 src/memory-management/stack.md:32
+msgid "More to Explore"
+msgstr ""
+
+#: src/enums/sizes.md:63
+msgid ""
+"Rust has several optimizations it can employ to make enums take up less "
+"space."
+msgstr ""
+
+#: src/enums/sizes.md:65
msgid ""
"Niche optimization: Rust will merge unused bit patterns for the enum "
"discriminant."
@@ -5138,7 +4760,7 @@ msgstr ""
"Optimización de nichos: Rust combina los patrones de bits no utilizados para "
"el discriminante de enumeración."
-#: src/enums/sizes.md:63
+#: src/enums/sizes.md:68
msgid ""
"Null pointer optimization: For [some types](https://doc.rust-lang.org/std/"
"option/#representation), Rust guarantees that `size_of::()` equals "
@@ -5148,7 +4770,7 @@ msgstr ""
"std/option/#representation), Rust asegura que `size_of::()` es igual a "
"`size_of:: >()`."
-#: src/enums/sizes.md:67
+#: src/enums/sizes.md:72
msgid ""
"Example code if you want to show how the bitwise representation _may_ look "
"like in practice. It's important to note that the compiler provides no "
@@ -5159,46 +4781,7 @@ msgstr ""
"el compilador no ofrece garantías con respecto a esta representación, por lo "
"tanto es totalmente inseguro. "
-#: src/enums/sizes.md:70
-msgid ""
-"```rust,editable\n"
-"use std::mem::transmute;\n"
-"\n"
-"macro_rules! dbg_bits {\n"
-" ($e:expr, $bit_type:ty) => {\n"
-" println!(\"- {}: {:#x}\", stringify!($e), transmute::<_, "
-"$bit_type>($e));\n"
-" };\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" // TOTALLY UNSAFE. Rust provides no guarantees about the bitwise\n"
-" // representation of types.\n"
-" unsafe {\n"
-" println!(\"Bitwise representation of bool\");\n"
-" dbg_bits!(false, u8);\n"
-" dbg_bits!(true, u8);\n"
-"\n"
-" println!(\"Bitwise representation of Option\");\n"
-" dbg_bits!(None::, u8);\n"
-" dbg_bits!(Some(false), u8);\n"
-" dbg_bits!(Some(true), u8);\n"
-"\n"
-" println!(\"Bitwise representation of Option>\");\n"
-" dbg_bits!(Some(Some(false)), u8);\n"
-" dbg_bits!(Some(Some(true)), u8);\n"
-" dbg_bits!(Some(None::), u8);\n"
-" dbg_bits!(None::>, u8);\n"
-"\n"
-" println!(\"Bitwise representation of Option<&i32>\");\n"
-" dbg_bits!(None::<&i32>, usize);\n"
-" dbg_bits!(Some(&0i32), usize);\n"
-" }\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/enums/sizes.md:105
+#: src/enums/sizes.md:109
msgid ""
"More complex example if you want to discuss what happens when we chain more "
"than 256 `Option`s together."
@@ -5206,60 +4789,7 @@ msgstr ""
"Ejemplo más complejo si quieres hablar de lo que pasa cuando encadenamos más "
"de 256 `Option`."
-#: src/enums/sizes.md:107
-msgid ""
-"```rust,editable\n"
-"#![recursion_limit = \"1000\"]\n"
-"\n"
-"use std::mem::transmute;\n"
-"\n"
-"macro_rules! dbg_bits {\n"
-" ($e:expr, $bit_type:ty) => {\n"
-" println!(\"- {}: {:#x}\", stringify!($e), transmute::<_, "
-"$bit_type>($e));\n"
-" };\n"
-"}\n"
-"\n"
-"// Macro to wrap a value in 2^n Some() where n is the number of \"@\" "
-"signs.\n"
-"// Increasing the recursion limit is required to evaluate this macro.\n"
-"macro_rules! many_options {\n"
-" ($value:expr) => { Some($value) };\n"
-" ($value:expr, @) => {\n"
-" Some(Some($value))\n"
-" };\n"
-" ($value:expr, @ $($more:tt)+) => {\n"
-" many_options!(many_options!($value, $($more)+), $($more)+)\n"
-" };\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" // TOTALLY UNSAFE. Rust provides no guarantees about the bitwise\n"
-" // representation of types.\n"
-" unsafe {\n"
-" assert_eq!(many_options!(false), Some(false));\n"
-" assert_eq!(many_options!(false, @), Some(Some(false)));\n"
-" assert_eq!(many_options!(false, @@), "
-"Some(Some(Some(Some(false)))));\n"
-"\n"
-" println!(\"Bitwise representation of a chain of 128 Option's.\");\n"
-" dbg_bits!(many_options!(false, @@@@@@@), u8);\n"
-" dbg_bits!(many_options!(true, @@@@@@@), u8);\n"
-"\n"
-" println!(\"Bitwise representation of a chain of 256 Option's.\");\n"
-" dbg_bits!(many_options!(false, @@@@@@@@), u16);\n"
-" dbg_bits!(many_options!(true, @@@@@@@@), u16);\n"
-"\n"
-" println!(\"Bitwise representation of a chain of 257 Option's.\");\n"
-" dbg_bits!(many_options!(Some(false), @@@@@@@@), u16);\n"
-" dbg_bits!(many_options!(Some(true), @@@@@@@@), u16);\n"
-" dbg_bits!(many_options!(None::, @@@@@@@@), u16);\n"
-" }\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/control-flow/novel.md:3
+#: src/control-flow/novel.md:3
msgid ""
"Rust has a few control flow constructs which differ from other languages. "
"They are used for pattern matching:"
@@ -5289,22 +4819,16 @@ msgstr ""
"expr.html#if-let-expressions) te permite ejecutar código diferente en "
"función de si un valor coincide con un patrón:"
-#: src/control-flow/if-let-expressions.md:7
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let arg = std::env::args().next();\n"
-" if let Some(value) = arg {\n"
-" println!(\"Program name: {value}\");\n"
-" } else {\n"
-" println!(\"Missing name?\");\n"
-" }\n"
-"}\n"
-"```"
+#: src/control-flow/if-let-expressions.md:11
+msgid "\"Program name: {value}\""
+msgstr ""
+
+#: src/control-flow/if-let-expressions.md:13
+msgid "\"Missing name?\""
msgstr ""
#: src/control-flow/if-let-expressions.md:18
-#: src/control-flow/while-let-expressions.md:21
+#: src/control-flow/while-let-expressions.md:22
#: src/control-flow/match-expressions.md:23
msgid ""
"See [pattern matching](../pattern-matching.md) for more details on patterns "
@@ -5347,24 +4871,6 @@ msgstr ""
"necesario para anular el flujo de control normal (con `panic`/`return`/"
"`break`/`continue`)::"
-#: src/control-flow/if-let-expressions.md:28
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" println!(\"{:?}\", second_word_to_upper(\"foo bar\"));\n"
-"}\n"
-" \n"
-"fn second_word_to_upper(s: &str) -> Option {\n"
-" let mut it = s.split(' ');\n"
-" let (Some(_), Some(item)) = (it.next(), it.next()) else {\n"
-" return None;\n"
-" };\n"
-" Some(item.to_uppercase())\n"
-"}\n"
-"\n"
-"```"
-msgstr ""
-
#: src/control-flow/while-let-expressions.md:1
msgid "`while let` loops"
msgstr "Bucles `while let`"
@@ -5379,21 +4885,7 @@ msgstr ""
"lang.org/reference/expressions/loop-expr.html#predicate-pattern-loops) que "
"prueba repetidamente un valor con respecto a un patrón:"
-#: src/control-flow/while-let-expressions.md:6
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let v = vec![10, 20, 30];\n"
-" let mut iter = v.into_iter();\n"
-"\n"
-" while let Some(x) = iter.next() {\n"
-" println!(\"x: {x}\");\n"
-" }\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/control-flow/while-let-expressions.md:17
+#: src/control-flow/while-let-expressions.md:18
msgid ""
"Here the iterator returned by `v.into_iter()` will return a `Option` on "
"every call to `next()`. It returns `Some(x)` until it is done, after which "
@@ -5405,7 +4897,7 @@ msgstr ""
"continuación, devuelve `None`. `while let` nos permite seguir iterando a "
"través de todos los elementos."
-#: src/control-flow/while-let-expressions.md:26
+#: src/control-flow/while-let-expressions.md:27
msgid ""
"Point out that the `while let` loop will keep going as long as the value "
"matches the pattern."
@@ -5413,7 +4905,7 @@ msgstr ""
"Señala que el bucle `while let` seguirá funcionando siempre que el valor "
"coincida con el patrón."
-#: src/control-flow/while-let-expressions.md:27
+#: src/control-flow/while-let-expressions.md:28
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 `iter.next()`. "
@@ -5435,20 +4927,46 @@ msgstr ""
"o varios patrones. En ese sentido, funciona como una serie de expresiones "
"`if let`:"
-#: src/control-flow/match-expressions.md:7
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" match std::env::args().next().as_deref() {\n"
-" Some(\"cat\") => println!(\"Will do cat things\"),\n"
-" Some(\"ls\") => println!(\"Will ls some files\"),\n"
-" Some(\"mv\") => println!(\"Let's move some files\"),\n"
-" Some(\"rm\") => println!(\"Uh, dangerous!\"),\n"
-" None => println!(\"Hmm, no program name?\"),\n"
-" _ => println!(\"Unknown program name!\"),\n"
-" }\n"
-"}\n"
-"```"
+#: src/control-flow/match-expressions.md:10
+msgid "\"cat\""
+msgstr ""
+
+#: src/control-flow/match-expressions.md:10
+#, fuzzy
+#| msgid "We will look at two things:"
+msgid "\"Will do cat things\""
+msgstr "Veremos todas estas cosas:"
+
+#: src/control-flow/match-expressions.md:11
+msgid "\"ls\""
+msgstr ""
+
+#: src/control-flow/match-expressions.md:11
+msgid "\"Will ls some files\""
+msgstr ""
+
+#: src/control-flow/match-expressions.md:12
+msgid "\"mv\""
+msgstr ""
+
+#: src/control-flow/match-expressions.md:12
+msgid "\"Let's move some files\""
+msgstr ""
+
+#: src/control-flow/match-expressions.md:13
+msgid "\"rm\""
+msgstr ""
+
+#: src/control-flow/match-expressions.md:13
+msgid "\"Uh, dangerous!\""
+msgstr ""
+
+#: src/control-flow/match-expressions.md:14
+msgid "\"Hmm, no program name?\""
+msgstr ""
+
+#: src/control-flow/match-expressions.md:15
+msgid "\"Unknown program name!\""
msgstr ""
#: src/control-flow/match-expressions.md:20
@@ -5492,8 +5010,12 @@ msgstr ""
"con `&str` dentro de `Option`."
#: src/pattern-matching.md:3
+#, fuzzy
+#| msgid ""
+#| "The `match` keyword let you match a value against one or more _patterns_. "
+#| "The comparisons are done from top to bottom and the first match wins."
msgid ""
-"The `match` keyword let you match a value against one or more _patterns_. "
+"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 ""
"La palabra clave `match` te permite comparar un valor con uno o varios "
@@ -5506,20 +5028,48 @@ msgstr ""
"Los patrones pueden ser valores simples, del mismo modo que `switch` en C y "
"C++:"
-#: src/pattern-matching.md:8
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let input = 'x';\n"
-"\n"
-" match input {\n"
-" 'q' => println!(\"Quitting\"),\n"
-" 'a' | 's' | 'w' | 'd' => println!(\"Moving around\"),\n"
-" '0'..='9' => println!(\"Number input\"),\n"
-" _ => println!(\"Something else\"),\n"
-" }\n"
-"}\n"
-"```"
+#: src/pattern-matching.md:13
+msgid "'q'"
+msgstr ""
+
+#: src/pattern-matching.md:13
+msgid "\"Quitting\""
+msgstr ""
+
+#: src/pattern-matching.md:14
+msgid "'a'"
+msgstr ""
+
+#: src/pattern-matching.md:14
+msgid "'s'"
+msgstr ""
+
+#: src/pattern-matching.md:14
+msgid "'w'"
+msgstr ""
+
+#: src/pattern-matching.md:14
+msgid "'d'"
+msgstr ""
+
+#: src/pattern-matching.md:14
+msgid "\"Moving around\""
+msgstr ""
+
+#: src/pattern-matching.md:15
+msgid "'0'"
+msgstr ""
+
+#: src/pattern-matching.md:15
+msgid "'9'"
+msgstr ""
+
+#: src/pattern-matching.md:15
+msgid "\"Number input\""
+msgstr ""
+
+#: src/pattern-matching.md:16
+msgid "\"Something else\""
msgstr ""
#: src/pattern-matching.md:21
@@ -5579,30 +5129,16 @@ msgstr ""
"valores. Así es como se inspecciona la estructura de tus tipos. Empecemos "
"con un tipo `enum` sencillo:"
-#: src/pattern-matching/destructuring-enums.md:6
-msgid ""
-"```rust,editable\n"
-"enum Result {\n"
-" Ok(i32),\n"
-" Err(String),\n"
-"}\n"
-"\n"
-"fn divide_in_two(n: i32) -> Result {\n"
-" if n % 2 == 0 {\n"
-" Result::Ok(n / 2)\n"
-" } else {\n"
-" Result::Err(format!(\"cannot divide {n} into two equal parts\"))\n"
-" }\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let n = 100;\n"
-" match divide_in_two(n) {\n"
-" Result::Ok(half) => println!(\"{n} divided in two is {half}\"),\n"
-" Result::Err(msg) => println!(\"sorry, an error happened: {msg}\"),\n"
-" }\n"
-"}\n"
-"```"
+#: src/pattern-matching/destructuring-enums.md:16
+msgid "\"cannot divide {n} into two equal parts\""
+msgstr ""
+
+#: src/pattern-matching/destructuring-enums.md:23
+msgid "\"{n} divided in two is {half}\""
+msgstr ""
+
+#: src/pattern-matching/destructuring-enums.md:24
+msgid "\"sorry, an error happened: {msg}\""
msgstr ""
#: src/pattern-matching/destructuring-enums.md:29
@@ -5638,25 +5174,16 @@ msgstr ""
msgid "You can also destructure `structs`:"
msgstr "También puedes desestructurar `structs`:"
-#: src/pattern-matching/destructuring-structs.md:5
-msgid ""
-"```rust,editable\n"
-"struct Foo {\n"
-" x: (u32, u32),\n"
-" y: u32,\n"
-"}\n"
-"\n"
-"#[rustfmt::skip]\n"
-"fn main() {\n"
-" let foo = Foo { x: (1, 2), y: 3 };\n"
-" match foo {\n"
-" Foo { x: (1, b), y } => println!(\"x.0 = 1, b = {b}, y = {y}\"),\n"
-" Foo { y: 2, x: i } => println!(\"y = 2, x = {i:?}\"),\n"
-" Foo { y, .. } => println!(\"y = {y}, other fields were "
-"ignored\"),\n"
-" }\n"
-"}\n"
-"```"
+#: src/pattern-matching/destructuring-structs.md:15
+msgid "\"x.0 = 1, b = {b}, y = {y}\""
+msgstr ""
+
+#: src/pattern-matching/destructuring-structs.md:16
+msgid "\"y = 2, x = {i:?}\""
+msgstr ""
+
+#: src/pattern-matching/destructuring-structs.md:17
+msgid "\"y = {y}, other fields were ignored\""
msgstr ""
#: src/pattern-matching/destructuring-structs.md:23
@@ -5687,20 +5214,23 @@ msgstr ""
"Puedes desestructurar arrays, tuplas y slices haciendo coincidir sus "
"elementos:"
-#: src/pattern-matching/destructuring-arrays.md:5
-msgid ""
-"```rust,editable\n"
-"#[rustfmt::skip]\n"
-"fn main() {\n"
-" let triple = [0, -2, 3];\n"
-" println!(\"Tell me about {triple:?}\");\n"
-" match triple {\n"
-" [0, y, z] => println!(\"First is 0, y = {y}, and z = {z}\"),\n"
-" [1, ..] => println!(\"First is 1 and the rest were ignored\"),\n"
-" _ => println!(\"All elements were ignored\"),\n"
-" }\n"
-"}\n"
-"```"
+#: src/pattern-matching/destructuring-arrays.md:9
+msgid "\"Tell me about {triple:?}\""
+msgstr ""
+
+#: src/pattern-matching/destructuring-arrays.md:11
+#: src/pattern-matching/destructuring-arrays.md:34
+msgid "\"First is 0, y = {y}, and z = {z}\""
+msgstr ""
+
+#: src/pattern-matching/destructuring-arrays.md:12
+#: src/pattern-matching/destructuring-arrays.md:35
+msgid "\"First is 1 and the rest were ignored\""
+msgstr ""
+
+#: src/pattern-matching/destructuring-arrays.md:13
+#: src/pattern-matching/destructuring-arrays.md:36
+msgid "\"All elements were ignored\""
msgstr ""
#: src/pattern-matching/destructuring-arrays.md:21
@@ -5711,24 +5241,8 @@ msgstr ""
"La desestructuración de slices de longitud desconocida también funciona con "
"patrones de longitud fija."
-#: src/pattern-matching/destructuring-arrays.md:24
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" inspect(&[0, -2, 3]);\n"
-" inspect(&[0, -2, 3, 4]);\n"
-"}\n"
-"\n"
-"#[rustfmt::skip]\n"
-"fn inspect(slice: &[i32]) {\n"
-" println!(\"Tell me about {slice:?}\");\n"
-" match slice {\n"
-" &[0, y, z] => println!(\"First is 0, y = {y}, and z = {z}\"),\n"
-" &[1, ..] => println!(\"First is 1 and the rest were ignored\"),\n"
-" _ => println!(\"All elements were ignored\"),\n"
-" }\n"
-"}\n"
-"```"
+#: src/pattern-matching/destructuring-arrays.md:32
+msgid "\"Tell me about {slice:?}\""
msgstr ""
#: src/pattern-matching/destructuring-arrays.md:41
@@ -5761,21 +5275,26 @@ msgstr ""
"trata de una expresión booleana arbitraria que se ejecutará si el patrón "
"coincide:"
-#: src/pattern-matching/match-guards.md:6
-msgid ""
-"```rust,editable\n"
-"#[rustfmt::skip]\n"
-"fn main() {\n"
-" let pair = (2, -2);\n"
-" println!(\"Tell me about {pair:?}\");\n"
-" match pair {\n"
-" (x, y) if x == y => println!(\"These are twins\"),\n"
-" (x, y) if x + y == 0 => println!(\"Antimatter, kaboom!\"),\n"
-" (x, _) if x % 2 == 1 => println!(\"The first one is odd\"),\n"
-" _ => println!(\"No correlation...\"),\n"
-" }\n"
-"}\n"
-"```"
+#: src/pattern-matching/match-guards.md:10
+msgid "\"Tell me about {pair:?}\""
+msgstr ""
+
+#: src/pattern-matching/match-guards.md:12
+#, fuzzy
+#| msgid "There are no exceptions."
+msgid "\"These are twins\""
+msgstr "No hay excepciones."
+
+#: src/pattern-matching/match-guards.md:13
+msgid "\"Antimatter, kaboom!\""
+msgstr ""
+
+#: src/pattern-matching/match-guards.md:14
+msgid "\"The first one is odd\""
+msgstr ""
+
+#: src/pattern-matching/match-guards.md:15
+msgid "\"No correlation...\""
msgstr ""
#: src/pattern-matching/match-guards.md:23
@@ -5899,57 +5418,154 @@ msgstr ""
"`for` e enteros. Luego, vuelve a la solución e intenta implementarla con "
"iteradores."
-#: src/exercises/day-1/luhn.md:25
+#: src/exercises/day-1/luhn.md:35
+#: src/exercises/day-2/iterators-and-ownership.md:75
+#: src/exercises/day-2/iterators-and-ownership.md:91
+#: src/traits/trait-bounds.md:22 src/traits/impl-trait.md:14
+#: src/exercises/day-3/simple-gui.md:148 src/exercises/day-3/simple-gui.md:149
+#: src/exercises/day-3/simple-gui.md:150 src/testing/test-modules.md:21
+#: src/exercises/day-1/solutions-afternoon.md:49
+msgid "\"foo\""
+msgstr ""
+
+#: src/exercises/day-1/luhn.md:36 src/exercises/day-1/solutions-afternoon.md:50
+msgid "\"foo 0 0\""
+msgstr ""
+
+#: src/exercises/day-1/luhn.md:41 src/testing/unit-tests.md:15
+#: src/exercises/day-1/solutions-afternoon.md:55
+#: src/exercises/day-3/solutions-morning.md:90
+#: src/exercises/day-3/solutions-morning.md:92
+#: src/exercises/day-3/solutions-morning.md:96
+#: src/exercises/day-3/solutions-morning.md:110
+#: src/exercises/day-3/solutions-morning.md:114
+msgid "\"\""
+msgstr ""
+
+#: src/exercises/day-1/luhn.md:42 src/exercises/day-1/solutions-afternoon.md:56
+msgid "\" \""
+msgstr ""
+
+#: src/exercises/day-1/luhn.md:43 src/exercises/day-1/solutions-afternoon.md:57
+msgid "\" \""
+msgstr ""
+
+#: src/exercises/day-1/luhn.md:44 src/exercises/day-1/solutions-afternoon.md:58
+msgid "\" \""
+msgstr ""
+
+#: src/exercises/day-1/luhn.md:49 src/exercises/day-1/solutions-afternoon.md:63
+msgid "\"0\""
+msgstr ""
+
+#: src/exercises/day-1/luhn.md:54 src/exercises/day-1/solutions-afternoon.md:68
+msgid "\" 0 0 \""
+msgstr ""
+
+#: src/exercises/day-1/luhn.md:59 src/exercises/day-1/solutions-afternoon.md:73
+msgid "\"4263 9826 4026 9299\""
+msgstr ""
+
+#: src/exercises/day-1/luhn.md:60 src/exercises/day-1/solutions-afternoon.md:74
+msgid "\"4539 3195 0343 6467\""
+msgstr ""
+
+#: src/exercises/day-1/luhn.md:61 src/exercises/day-1/solutions-afternoon.md:75
+msgid "\"7992 7398 713\""
+msgstr ""
+
+#: src/exercises/day-1/luhn.md:66 src/exercises/day-1/solutions-afternoon.md:80
+msgid "\"4223 9826 4026 9299\""
+msgstr ""
+
+#: src/exercises/day-1/luhn.md:67 src/exercises/day-1/solutions-afternoon.md:81
+msgid "\"4539 3195 0343 6476\""
+msgstr ""
+
+#: src/exercises/day-1/luhn.md:68 src/exercises/day-1/solutions-afternoon.md:82
+msgid "\"8273 1232 7352 0569\""
+msgstr ""
+
+#: src/exercises/day-1/pattern-matching.md:1
+msgid "Exercise: Expression Evaluation"
+msgstr ""
+
+#: src/exercises/day-1/pattern-matching.md:3
+msgid "Let's write a simple recursive evaluator for arithmetic expressions. "
+msgstr ""
+
+#: src/exercises/day-1/pattern-matching.md:6
+#: src/exercises/day-1/solutions-afternoon.md:89
+msgid "/// An operation to perform on two subexpressions.\n"
+msgstr ""
+
+#: src/exercises/day-1/pattern-matching.md:14
+#: src/exercises/day-1/solutions-afternoon.md:97
+msgid "/// An expression, in tree form.\n"
+msgstr ""
+
+#: src/exercises/day-1/pattern-matching.md:18
+#: src/exercises/day-1/solutions-afternoon.md:101
+msgid "/// An operation on two subexpressions.\n"
+msgstr ""
+
+#: src/exercises/day-1/pattern-matching.md:25
+#: src/exercises/day-1/solutions-afternoon.md:108
+msgid "/// A literal value\n"
+msgstr ""
+
+#: src/exercises/day-1/pattern-matching.md:28
+#: src/exercises/day-1/solutions-afternoon.md:111
+msgid "/// The result of evaluating an expression.\n"
+msgstr ""
+
+#: src/exercises/day-1/pattern-matching.md:32
+#: src/exercises/day-1/solutions-afternoon.md:115
+msgid "/// Evaluation was successful, with the given result.\n"
+msgstr ""
+
+#: src/exercises/day-1/pattern-matching.md:34
+#: src/exercises/day-1/solutions-afternoon.md:117
+msgid "/// Evaluation failed, with the given error message.\n"
+msgstr ""
+
+#: src/exercises/day-1/pattern-matching.md:36
+#: src/exercises/day-1/solutions-afternoon.md:119
+msgid "// Allow `Ok` and `Err` as shorthands for `Res::Ok` and `Res::Err`.\n"
+msgstr ""
+
+#: src/exercises/day-1/pattern-matching.md:95
+#: src/exercises/day-1/solutions-afternoon.md:140
+#: src/exercises/day-1/solutions-afternoon.md:202
+msgid "\"division by zero\""
+msgstr ""
+
+#: src/exercises/day-1/pattern-matching.md:100
msgid ""
-"```rust\n"
-"// TODO: remove this when you're done with your implementation.\n"
-"#![allow(unused_variables, dead_code)]\n"
-"\n"
-"pub fn luhn(cc_number: &str) -> bool {\n"
-" unimplemented!()\n"
-"}\n"
-"\n"
-"#[test]\n"
-"fn test_non_digit_cc_number() {\n"
-" assert!(!luhn(\"foo\"));\n"
-" assert!(!luhn(\"foo 0 0\"));\n"
-"}\n"
-"\n"
-"#[test]\n"
-"fn test_empty_cc_number() {\n"
-" assert!(!luhn(\"\"));\n"
-" assert!(!luhn(\" \"));\n"
-" assert!(!luhn(\" \"));\n"
-" assert!(!luhn(\" \"));\n"
-"}\n"
-"\n"
-"#[test]\n"
-"fn test_single_digit_cc_number() {\n"
-" assert!(!luhn(\"0\"));\n"
-"}\n"
-"\n"
-"#[test]\n"
-"fn test_two_digit_cc_number() {\n"
-" assert!(luhn(\" 0 0 \"));\n"
-"}\n"
-"\n"
-"#[test]\n"
-"fn test_valid_cc_number() {\n"
-" assert!(luhn(\"4263 9826 4026 9299\"));\n"
-" assert!(luhn(\"4539 3195 0343 6467\"));\n"
-" assert!(luhn(\"7992 7398 713\"));\n"
-"}\n"
-"\n"
-"#[test]\n"
-"fn test_invalid_cc_number() {\n"
-" assert!(!luhn(\"4223 9826 4026 9299\"));\n"
-" assert!(!luhn(\"4539 3195 0343 6476\"));\n"
-" assert!(!luhn(\"8273 1232 7352 0569\"));\n"
-"}\n"
-"\n"
-"#[allow(dead_code)]\n"
-"fn main() {}\n"
-"```"
+"The `Box` type here is a smart pointer, and will be covered in detail later "
+"in the course. An expression can be \"boxed\" with `Box::new` as seen in the "
+"tests. To evaluate a boxed expression, use the deref operator to \"unbox\" "
+"it: `eval(*boxed_expr)`."
+msgstr ""
+
+#: src/exercises/day-1/pattern-matching.md:105
+msgid ""
+"Some expressions cannot be evaluated and will return an error. The `Res` "
+"type represents either a successful value or an error with a message. This "
+"is very similar to the standard-library `Result` which we will see later."
+msgstr ""
+
+#: src/exercises/day-1/pattern-matching.md:109
+msgid ""
+"Copy and paste the code into the Rust playground, and begin implementing "
+"`eval`. The final product should pass the tests. It may be helpful to use "
+"`todo!()` and get the tests to pass one-by-one."
+msgstr ""
+
+#: src/exercises/day-1/pattern-matching.md:113
+msgid ""
+"If you finish early, try writing a test that results in an integer overflow. "
+"How could you handle this with `Res::Err` instead of a panic?"
msgstr ""
#: src/welcome-day-2.md:1
@@ -6084,30 +5700,11 @@ msgstr ""
"Al crear un `String`, los metadatos de tamaño fijo se colocan en la _stack_ "
"y los datos de tamaño dinámico (la cadena real) en el _heap_:"
-#: src/memory-management/stack.md:6
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let s1 = String::from(\"Hello\");\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/memory-management/stack.md:12
-msgid ""
-"```bob\n"
-" Stack Heap\n"
-".- - - - - - - - - - - - - -. .- - - - - - - - - - - - - - - -.\n"
-": : : :\n"
-": s1 : : :\n"
-": +-----------+-------+ : : +----+----+----+----+----+ :\n"
-": | ptr | o---+---+-----+-->| H | e | l | l | o | :\n"
-": | len | 5 | : : +----+----+----+----+----+ :\n"
-": | capacity | 5 | : : :\n"
-": +-----------+-------+ : : :\n"
-": : `- - - - - - - - - - - - - - - -'\n"
-"`- - - - - - - - - - - - - -'\n"
-"```"
+#: src/memory-management/stack.md:8 src/memory-management/stack.md:39
+#: src/std/string.md:8 src/traits/read-write.md:35 src/testing/unit-tests.md:20
+#: src/testing/unit-tests.md:25 src/testing/test-modules.md:12
+#: src/concurrency/scoped-threads.md:9 src/concurrency/scoped-threads.md:26
+msgid "\"Hello\""
msgstr ""
#: src/memory-management/stack.md:28
@@ -6132,32 +5729,37 @@ msgstr ""
"asignadores personalizados mediante el [_Allocator API_](https://doc.rust-"
"lang.org/std/alloc/index.html)."
-#: src/memory-management/stack.md:32
+#: src/memory-management/stack.md:34
+#, fuzzy
+#| msgid ""
+#| "We can inspect the memory layout with `unsafe` code. However, you should "
+#| "point out that this is rightfully unsafe!"
msgid ""
-"We can inspect the memory layout with `unsafe` code. However, you should "
+"We can inspect the memory layout with `unsafe` Rust. However, you should "
"point out that this is rightfully unsafe!"
msgstr ""
"Podemos inspeccionar la disposición de la memoria con código `unsafe`. Sin "
"embargo, debes señalar que esto no es seguro."
-#: src/memory-management/stack.md:34
+#: src/memory-management/stack.md:40 src/testing/unit-tests.md:7
+#: src/exercises/day-1/solutions-afternoon.md:13
+msgid "' '"
+msgstr ""
+
+#: src/memory-management/stack.md:41
+msgid "\"world\""
+msgstr ""
+
+#: src/memory-management/stack.md:42
msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let mut s1 = String::from(\"Hello\");\n"
-" s1.push(' ');\n"
-" s1.push_str(\"world\");\n"
-" // DON'T DO THIS AT HOME! For educational purposes only.\n"
+"// 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"
-" unsafe {\n"
-" let (ptr, capacity, len): (usize, usize, usize) = std::mem::"
-"transmute(s1);\n"
-" println!(\"ptr = {ptr:#x}, len = {len}, capacity = {capacity}\");\n"
-" }\n"
-"}\n"
-"```"
+msgstr ""
+
+#: src/memory-management/stack.md:47
+msgid "\"ptr = {ptr:#x}, len = {len}, capacity = {capacity}\""
msgstr ""
#: src/memory-management/manual.md:3
@@ -6180,17 +5782,11 @@ msgstr "Ejemplo en C"
msgid "You must call `free` on every pointer you allocate with `malloc`:"
msgstr "Debes llamar a `free` en cada puntero que asignes con `malloc`:"
-#: src/memory-management/manual.md:11
+#: src/memory-management/manual.md:14
msgid ""
-"```c\n"
-"void foo(size_t n) {\n"
-" int* int_array = malloc(n * sizeof(int));\n"
-" //\n"
+"//\n"
" // ... lots of code\n"
" //\n"
-" free(int_array);\n"
-"}\n"
-"```"
msgstr ""
#: src/memory-management/manual.md:21
@@ -6235,20 +5831,6 @@ msgstr ""
msgid "C++ Example"
msgstr "Ejemplo en C++"
-#: src/memory-management/scope-based.md:14
-msgid ""
-"```c++\n"
-"void say_hello(std::unique_ptr person) {\n"
-" std::cout << \"Hello \" << person->name << std::endl;\n"
-"}\n"
-"```"
-msgstr ""
-"```c++\n"
-"void say_hello(std::unique_ptr person) {\n"
-" std::cout << \"Hola \" << person->name << std::endl;\n"
-"}\n"
-"```"
-
#: src/memory-management/scope-based.md:20
msgid ""
"The `std::unique_ptr` object is allocated on the stack, and points to memory "
@@ -6272,14 +5854,6 @@ msgstr ""
"Los constructores de movimiento especiales se utilizan cuando se pasa el "
"_ownership_ a una función:"
-#: src/memory-management/scope-based.md:27
-msgid ""
-"```c++\n"
-"std::unique_ptr person = find_person(\"Carla\");\n"
-"say_hello(std::move(person));\n"
-"```"
-msgstr ""
-
#: src/memory-management/garbage-collection.md:1
msgid "Automatic Memory Management"
msgstr "Gestión Automática de la Memoria"
@@ -6315,20 +5889,6 @@ msgstr ""
"El objeto `person` no se libera después de que `sayHello` devuelva el "
"siguiente resultado:"
-#: src/memory-management/garbage-collection.md:13
-msgid ""
-"```java\n"
-"void sayHello(Person person) {\n"
-" System.out.println(\"Hello \" + person.getName());\n"
-"}\n"
-"```"
-msgstr ""
-"```java\n"
-"void sayHello(Person person) {\n"
-" System.out.println(\"Hola \" + person.getName());\n"
-"}\n"
-"```"
-
#: src/memory-management/rust.md:1
msgid "Memory Management in Rust"
msgstr "Gestión de la Memoria en Rust"
@@ -6394,31 +5954,16 @@ msgstr ""
"Todos los enlaces a variables tienen un _ámbito_ donde son válidos y se "
"produce un error cuando se usan fuera de él:"
-#: src/ownership.md:6
-msgid ""
-"```rust,editable,compile_fail\n"
-"struct Point(i32, i32);\n"
-"\n"
-"fn main() {\n"
-" {\n"
-" let p = Point(3, 4);\n"
-" println!(\"x: {}\", p.0);\n"
-" }\n"
-" println!(\"y: {}\", p.1);\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/ownership.md:18
+#: src/ownership.md:19
msgid ""
"At the end of the scope, the variable is _dropped_ and the data is freed."
msgstr "Al final del ámbito, la variable _se elimina_ y los datos se liberan."
-#: src/ownership.md:19
+#: src/ownership.md:20
msgid "A destructor can run here to free up resources."
msgstr "Se puede ejecutar un destructor para liberar recursos."
-#: src/ownership.md:20
+#: src/ownership.md:21
msgid "We say that the variable _owns_ the value."
msgstr "Decimos que el valor _pertenece_ a la variable."
@@ -6426,25 +5971,15 @@ msgstr "Decimos que el valor _pertenece_ a la variable."
msgid "An assignment will transfer _ownership_ between variables:"
msgstr "Una asignación transferirá su _ownership_ entre variables:"
-#: src/ownership/move-semantics.md:5
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let s1: String = String::from(\"Hello!\");\n"
-" let s2: String = s1;\n"
-" println!(\"s2: {s2}\");\n"
-" // println!(\"s1: {s1}\");\n"
-"}\n"
-"```"
+#: src/ownership/move-semantics.md:7
+#, fuzzy
+#| msgid "Hello World!"
+msgid "\"Hello!\""
+msgstr "¡Hola, mundo!"
+
+#: src/ownership/move-semantics.md:10
+msgid "// println!(\"s1: {s1}\");\n"
msgstr ""
-"```rust,editable\n"
-"fn main() {\n"
-" let s1: String = String::from(\"Hola!\");\n"
-" let s2: String = s1;\n"
-" println!(\"s2: {s2}\");\n"
-" // println!(\"s1: {s1}\");\n"
-"}\n"
-"```"
#: src/ownership/move-semantics.md:14
msgid "The assignment of `s1` to `s2` transfers ownership."
@@ -6493,51 +6028,23 @@ msgstr ""
msgid "In Rust, clones are explicit (by using `clone`)."
msgstr "En Rust, la clonación es explícita (usando `clone`)."
-#: src/ownership/moved-strings-rust.md:3
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let s1: String = String::from(\"Rust\");\n"
-" let s2: String = s1;\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/ownership/moved-strings-rust.md:10
+#: src/ownership/moved-strings-rust.md:11
msgid "The heap data from `s1` is reused for `s2`."
msgstr "Los datos del _heap_ de `s1` se reutilizan en `s2`."
-#: src/ownership/moved-strings-rust.md:11
+#: src/ownership/moved-strings-rust.md:12
msgid "When `s1` goes out of scope, nothing happens (it has been moved from)."
msgstr "Cuando `s1` sale del ámbito, no ocurre nada (ha sido movida)."
-#: src/ownership/moved-strings-rust.md:13
+#: src/ownership/moved-strings-rust.md:14
msgid "Before move to `s2`:"
msgstr "Antes de mover a `s2`:"
-#: src/ownership/moved-strings-rust.md:15
-msgid ""
-"```bob\n"
-" Stack Heap\n"
-".- - - - - - - - - - - - - -. .- - - - - - - - - - - - - -.\n"
-": : : :\n"
-": s1 : : :\n"
-": +-----------+-------+ : : +----+----+----+----+ :\n"
-": | ptr | o---+---+-----+-->| R | u | s | t | :\n"
-": | len | 4 | : : +----+----+----+----+ :\n"
-": | capacity | 4 | : : :\n"
-": +-----------+-------+ : : :\n"
-": : `- - - - - - - - - - - - - -'\n"
-": :\n"
-"`- - - - - - - - - - - - - -'\n"
-"```"
-msgstr ""
-
-#: src/ownership/moved-strings-rust.md:30
+#: src/ownership/moved-strings-rust.md:31
msgid "After move to `s2`:"
msgstr "Después de mover a `s2`:"
-#: src/ownership/moved-strings-rust.md:32
+#: src/ownership/moved-strings-rust.md:33
msgid ""
"```bob\n"
" Stack Heap\n"
@@ -6590,17 +6097,13 @@ msgstr "Double free en código C++ moderno"
msgid "Modern C++ solves this differently:"
msgstr "La versión moderna de C++ soluciona este problema de forma diferente:"
-#: src/ownership/double-free-modern-cpp.md:5
-msgid ""
-"```c++\n"
-"std::string s1 = \"Cpp\";\n"
-"std::string s2 = s1; // Duplicate the data in s1.\n"
-"```"
+#: src/ownership/double-free-modern-cpp.md:6
+msgid "\"Cpp\""
+msgstr ""
+
+#: src/ownership/double-free-modern-cpp.md:7
+msgid "// Duplicate the data in s1.\n"
msgstr ""
-"```c++\n"
-"std::string s1 = \"Cpp\";\n"
-"std::string s2 = s1; // Duplicar datos en s1.\n"
-"```"
#: src/ownership/double-free-modern-cpp.md:10
msgid ""
@@ -6618,84 +6121,10 @@ msgstr ""
msgid "Before copy-assignment:"
msgstr "Antes de la asignación de copias:"
-#: src/ownership/double-free-modern-cpp.md:16
-msgid ""
-"```bob\n"
-" Stack Heap\n"
-".- - - - - - - - - - - - - -. .- - - - - - - - - - - -.\n"
-": : : :\n"
-": s1 : : :\n"
-": +-----------+-------+ : : +----+----+----+ :\n"
-": | ptr | o---+---+--+--+-->| C | p | p | :\n"
-": | len | 3 | : : +----+----+----+ :\n"
-": | capacity | 3 | : : :\n"
-": +-----------+-------+ : : :\n"
-": : `- - - - - - - - - - - -'\n"
-"`- - - - - - - - - - - - - -'\n"
-"```"
-msgstr ""
-"```bob\n"
-" _Stack_ _Heap_\n"
-".- - - - - - - - - - - - - -. .- - - - - - - - - - - -.\n"
-": : : :\n"
-": s1 : : :\n"
-": +-----------+-------+ : : +----+----+----+ :\n"
-": | ptr | o---+---+--+--+-->| C | p | p | :\n"
-": | len | 3 | : : +----+----+----+ :\n"
-": | capacity | 3 | : : :\n"
-": +-----------+-------+ : : :\n"
-": : `- - - - - - - - - - - -'\n"
-"`- - - - - - - - - - - - - -'\n"
-"```"
-
#: src/ownership/double-free-modern-cpp.md:30
msgid "After copy-assignment:"
msgstr "Después de la asignación de copia:"
-#: src/ownership/double-free-modern-cpp.md:32
-msgid ""
-"```bob\n"
-" Stack Heap\n"
-".- - - - - - - - - - - - - -. .- - - - - - - - - - - -.\n"
-": : : :\n"
-": s1 : : :\n"
-": +-----------+-------+ : : +----+----+----+ :\n"
-": | ptr | o---+---+--+--+-->| C | p | p | :\n"
-": | len | 3 | : : +----+----+----+ :\n"
-": | capacity | 3 | : : :\n"
-": +-----------+-------+ : : :\n"
-": : : :\n"
-": s2 : : :\n"
-": +-----------+-------+ : : +----+----+----+ :\n"
-": | ptr | o---+---+-----+-->| C | p | p | :\n"
-": | len | 3 | : : +----+----+----+ :\n"
-": | capacity | 3 | : : :\n"
-": +-----------+-------+ : : :\n"
-": : `- - - - - - - - - - - -'\n"
-"`- - - - - - - - - - - - - -'\n"
-"```"
-msgstr ""
-"```bob\n"
-" _Stack_ _Heap_\n"
-".- - - - - - - - - - - - - -. .- - - - - - - - - - - -.\n"
-": : : :\n"
-": s1 : : :\n"
-": +-----------+-------+ : : +----+----+----+ :\n"
-": | ptr | o---+---+--+--+-->| C | p | p | :\n"
-": | len | 3 | : : +----+----+----+ :\n"
-": | capacity | 3 | : : :\n"
-": +-----------+-------+ : : :\n"
-": : : :\n"
-": s2 : : :\n"
-": +-----------+-------+ : : +----+----+----+ :\n"
-": | ptr | o---+---+-----+-->| C | p | p | :\n"
-": | len | 3 | : : +----+----+----+ :\n"
-": | capacity | 3 | : : :\n"
-": +-----------+-------+ : : :\n"
-": : `- - - - - - - - - - - -'\n"
-"`- - - - - - - - - - - - - -'\n"
-"```"
-
#: src/ownership/double-free-modern-cpp.md:57
msgid ""
"C++ has made a slightly different choice than Rust. Because `=` copies data, "
@@ -6726,19 +6155,19 @@ msgstr ""
"Cuando pasas un valor a una función, el valor se asigna al parámetro de la "
"función. Esta acción transfiere el _ownership_:"
-#: src/ownership/moves-function-calls.md:6
-msgid ""
-"```rust,editable\n"
-"fn say_hello(name: String) {\n"
-" println!(\"Hello {name}\")\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let name = String::from(\"Alice\");\n"
-" say_hello(name);\n"
-" // say_hello(name);\n"
-"}\n"
-"```"
+#: src/ownership/moves-function-calls.md:8 src/traits/impl-trait.md:10
+msgid "\"Hello {name}\""
+msgstr ""
+
+#: src/ownership/moves-function-calls.md:12
+#: src/android/interoperability/java.md:56
+#, fuzzy
+#| msgid "Slices"
+msgid "\"Alice\""
+msgstr "Slices"
+
+#: src/ownership/moves-function-calls.md:14
+msgid "// say_hello(name);\n"
msgstr ""
#: src/ownership/moves-function-calls.md:20
@@ -6789,58 +6218,31 @@ msgstr ""
"Aunque la semántica de movimiento es la opción predeterminada, algunos tipos "
"se copian de forma predeterminada:"
-#: src/ownership/copy-clone.md:5
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let x = 42;\n"
-" let y = x;\n"
-" println!(\"x: {x}\");\n"
-" println!(\"y: {y}\");\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/ownership/copy-clone.md:14
+#: src/ownership/copy-clone.md:15
msgid "These types implement the `Copy` trait."
msgstr "Estos tipos implementan el trait `Copy`."
-#: src/ownership/copy-clone.md:16
+#: src/ownership/copy-clone.md:17
msgid "You can opt-in your own types to use copy semantics:"
msgstr ""
"Puedes habilitar tus propios tipos para que usen la semántica de copia:"
-#: src/ownership/copy-clone.md:18
-msgid ""
-"```rust,editable\n"
-"#[derive(Copy, Clone, Debug)]\n"
-"struct Point(i32, i32);\n"
-"\n"
-"fn main() {\n"
-" let p1 = Point(3, 4);\n"
-" let p2 = p1;\n"
-" println!(\"p1: {p1:?}\");\n"
-" println!(\"p2: {p2:?}\");\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/ownership/copy-clone.md:30
+#: src/ownership/copy-clone.md:32
msgid "After the assignment, both `p1` and `p2` own their own data."
msgstr ""
"Después de la asignación, tanto `p1` como `p2` tienen sus propios datos."
-#: src/ownership/copy-clone.md:31
+#: src/ownership/copy-clone.md:33
msgid "We can also use `p1.clone()` to explicitly copy the data."
msgstr ""
"También podemos utilizar `p1.clone()` para copiar los datos de forma "
"explícita."
-#: src/ownership/copy-clone.md:35
+#: src/ownership/copy-clone.md:37
msgid "Copying and cloning are not the same thing:"
msgstr "Copiar y clonar no es lo mismo:"
-#: src/ownership/copy-clone.md:37
+#: src/ownership/copy-clone.md:39
msgid ""
"Copying refers to bitwise copies of memory regions and does not work on "
"arbitrary objects."
@@ -6848,14 +6250,14 @@ msgstr ""
"Copiar hace referencia a las copias bit a bit de regiones de memoria y no "
"funciona en cualquier objeto."
-#: src/ownership/copy-clone.md:38
+#: src/ownership/copy-clone.md:40
msgid ""
"Copying does not allow for custom logic (unlike copy constructors in C++)."
msgstr ""
"Copiar no permite lógica personalizada (a diferencia de los constructores de "
"copias de C++)."
-#: src/ownership/copy-clone.md:39
+#: src/ownership/copy-clone.md:41
msgid ""
"Cloning is a more general operation and also allows for custom behavior by "
"implementing the `Clone` trait."
@@ -6863,15 +6265,15 @@ msgstr ""
"Clonar es una operación más general y que permite un comportamiento "
"personalizado implementando el trait `Clone`."
-#: src/ownership/copy-clone.md:40
+#: src/ownership/copy-clone.md:42
msgid "Copying does not work on types that implement the `Drop` trait."
msgstr "Copiar no funciona en los tipos que implementan el trait `Drop`."
-#: src/ownership/copy-clone.md:42 src/ownership/lifetimes-function-calls.md:29
+#: src/ownership/copy-clone.md:44 src/ownership/lifetimes-function-calls.md:30
msgid "In the above example, try the following:"
msgstr "En el ejemplo anterior, prueba lo siguiente:"
-#: src/ownership/copy-clone.md:44
+#: src/ownership/copy-clone.md:46
msgid ""
"Add a `String` field to `struct Point`. It will not compile because `String` "
"is not a `Copy` type."
@@ -6879,7 +6281,7 @@ msgstr ""
"Añade un campo `String` a `struct Point`. No se compilará porque `String` no "
"es de tipo `Copy`."
-#: src/ownership/copy-clone.md:45
+#: src/ownership/copy-clone.md:47
msgid ""
"Remove `Copy` from the `derive` attribute. The compiler error is now in the "
"`println!` for `p1`."
@@ -6887,11 +6289,11 @@ msgstr ""
"Elimina `Copy` del atributo `derive`. El error del compilador se encuentra "
"ahora en `println!` para `p1`."
-#: src/ownership/copy-clone.md:46
+#: src/ownership/copy-clone.md:48
msgid "Show that it works if you clone `p1` instead."
msgstr "Demuestra que funciona si clonas `p1`."
-#: src/ownership/copy-clone.md:48
+#: src/ownership/copy-clone.md:50
msgid ""
"If students ask about `derive`, it is sufficient to say that this is a way "
"to generate code in Rust at compile time. In this case the default "
@@ -6910,38 +6312,19 @@ msgstr ""
"En lugar de transferir el _ownership_ al llamar a una función, puedes "
"permitir que una función _tome prestado_ el valor:"
-#: src/ownership/borrowing.md:6
-msgid ""
-"```rust,editable\n"
-"#[derive(Debug)]\n"
-"struct Point(i32, i32);\n"
-"\n"
-"fn add(p1: &Point, p2: &Point) -> Point {\n"
-" Point(p1.0 + p2.0, p1.1 + p2.1)\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let p1 = Point(3, 4);\n"
-" let p2 = Point(10, 20);\n"
-" let p3 = add(&p1, &p2);\n"
-" println!(\"{p1:?} + {p2:?} = {p3:?}\");\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/ownership/borrowing.md:22
+#: src/ownership/borrowing.md:23
msgid "The `add` function _borrows_ two points and returns a new point."
msgstr "La función `add` _toma prestados_ dos puntos y devuelve uno nuevo."
-#: src/ownership/borrowing.md:23
+#: src/ownership/borrowing.md:24
msgid "The caller retains ownership of the inputs."
msgstr "El llamador conserva el _ownership_ de las entradas."
-#: src/ownership/borrowing.md:27
+#: src/ownership/borrowing.md:28
msgid "Notes on stack returns:"
msgstr "Notas sobre la devolución de resultados de la _stack_:"
-#: src/ownership/borrowing.md:28
+#: src/ownership/borrowing.md:29
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 "
@@ -6958,34 +6341,12 @@ msgstr ""
"deberían cambiar. Sin embargo, deberían mantenerse igual modificar la "
"configuración \"RELEASE\":"
-#: src/ownership/borrowing.md:30
-msgid ""
-"```rust,editable\n"
-"#[derive(Debug)]\n"
-"struct Point(i32, i32);\n"
-"\n"
-"fn add(p1: &Point, p2: &Point) -> Point {\n"
-" let p = Point(p1.0 + p2.0, p1.1 + p2.1);\n"
-" println!(\"&p.0: {:p}\", &p.0);\n"
-" p\n"
-"}\n"
-"\n"
-"pub fn main() {\n"
-" let p1 = Point(3, 4);\n"
-" let p2 = Point(10, 20);\n"
-" let p3 = add(&p1, &p2);\n"
-" println!(\"&p3.0: {:p}\", &p3.0);\n"
-" println!(\"{p1:?} + {p2:?} = {p3:?}\");\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/ownership/borrowing.md:48
+#: src/ownership/borrowing.md:50
msgid "The Rust compiler can do return value optimization (RVO)."
msgstr ""
"El compilador de Rust puede hacer la optimización del valor devuelto (RVO)."
-#: src/ownership/borrowing.md:49
+#: src/ownership/borrowing.md:51
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 "
@@ -7009,25 +6370,7 @@ msgstr "Puedes tener uno o varios valores `&T` en un momento dado, _o_"
msgid "You can have exactly one `&mut T` value."
msgstr "puedes tener exactamente un valor `&mut T`."
-#: src/ownership/shared-unique-borrows.md:8
-msgid ""
-"```rust,editable,compile_fail\n"
-"fn main() {\n"
-" let mut a: i32 = 10;\n"
-" let b: &i32 = &a;\n"
-"\n"
-" {\n"
-" let c: &mut i32 = &mut a;\n"
-" *c = 20;\n"
-" }\n"
-"\n"
-" println!(\"a: {a}\");\n"
-" println!(\"b: {b}\");\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/ownership/shared-unique-borrows.md:25
+#: src/ownership/shared-unique-borrows.md:26
msgid ""
"The above code does not compile because `a` is borrowed as mutable (through "
"`c`) and as immutable (through `b`) at the same time."
@@ -7035,7 +6378,7 @@ msgstr ""
"El código anterior no se compila porque `a` se toma prestada como mutable (a "
"través de `c`) y como inmutable (a través de `b`) al mismo tiempo."
-#: src/ownership/shared-unique-borrows.md:26
+#: src/ownership/shared-unique-borrows.md:27
msgid ""
"Move the `println!` statement for `b` before the scope that introduces `c` "
"to make the code compile."
@@ -7043,7 +6386,7 @@ msgstr ""
"Mueve la instrucción `println!` de `b` antes del ámbito que introduce `c` "
"para que el código compile."
-#: src/ownership/shared-unique-borrows.md:27
+#: src/ownership/shared-unique-borrows.md:28
msgid ""
"After that change, the compiler realizes that `b` is only ever used before "
"the new mutable borrow of `a` through `c`. This is a feature of the borrow "
@@ -7068,7 +6411,7 @@ msgid "Lifetimes can also be explicit: `&'a Point`, `&'document str`."
msgstr ""
"Tiempo de vida también puede ser explícito: `&'a Point`, `&'document str`."
-#: src/ownership/lifetimes.md:7 src/ownership/lifetimes-function-calls.md:23
+#: src/ownership/lifetimes.md:7 src/ownership/lifetimes-function-calls.md:24
msgid ""
"Read `&'a Point` as \"a borrowed `Point` which is valid for at least the "
"lifetime `a`\"."
@@ -7110,43 +6453,24 @@ msgstr ""
"Además de tomar prestados sus argumentos, una función puede devolver un "
"valor que se ha tomado prestado:"
-#: src/ownership/lifetimes-function-calls.md:5
-msgid ""
-"```rust,editable\n"
-"#[derive(Debug)]\n"
-"struct Point(i32, i32);\n"
-"\n"
-"fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point {\n"
-" if p1.0 < p2.0 { p1 } else { p2 }\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let p1: Point = Point(10, 10);\n"
-" let p2: Point = Point(20, 20);\n"
-" let p3: &Point = left_most(&p1, &p2);\n"
-" println!(\"left-most point: {:?}\", p3);\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/ownership/lifetimes-function-calls.md:21
+#: src/ownership/lifetimes-function-calls.md:22
msgid "`'a` is a generic parameter, it is inferred by the compiler."
msgstr "`'a` es un parámetro genérico que infiere el compilador."
-#: src/ownership/lifetimes-function-calls.md:22
+#: src/ownership/lifetimes-function-calls.md:23
msgid "Lifetimes start with `'` and `'a` is a typical default name."
msgstr ""
"Los tiempos de vida comienzan por `'` y `'a` suele ser un nombre "
"predeterminado habitual."
-#: src/ownership/lifetimes-function-calls.md:25
+#: src/ownership/lifetimes-function-calls.md:26
msgid ""
"The _at least_ part is important when parameters are in different scopes."
msgstr ""
"La parte _al menos_ es importante cuando los parámetros están en ámbitos "
"distintos."
-#: src/ownership/lifetimes-function-calls.md:31
+#: src/ownership/lifetimes-function-calls.md:32
msgid ""
"Move the declaration of `p2` and `p3` into a new scope (`{ ... }`), "
"resulting in the following code:"
@@ -7154,34 +6478,12 @@ msgstr ""
"Mueve la declaración de `p2` y `p3` a un nuevo ámbito (`{ ... }`), lo que "
"dará como resultado el siguiente código:"
-#: src/ownership/lifetimes-function-calls.md:32
-msgid ""
-"```rust,ignore\n"
-"#[derive(Debug)]\n"
-"struct Point(i32, i32);\n"
-"\n"
-"fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point {\n"
-" if p1.0 < p2.0 { p1 } else { p2 }\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let p1: Point = Point(10, 10);\n"
-" let p3: &Point;\n"
-" {\n"
-" let p2: Point = Point(20, 20);\n"
-" p3 = left_most(&p1, &p2);\n"
-" }\n"
-" println!(\"left-most point: {:?}\", p3);\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/ownership/lifetimes-function-calls.md:50
+#: src/ownership/lifetimes-function-calls.md:52
msgid "Note how this does not compile since `p3` outlives `p2`."
msgstr ""
"Ten en cuenta que no se puede compilar, ya que `p3` dura más tiempo que `p2`."
-#: src/ownership/lifetimes-function-calls.md:52
+#: src/ownership/lifetimes-function-calls.md:54
msgid ""
"Reset the workspace and change the function signature to `fn left_most<'a, "
"'b>(p1: &'a Point, p2: &'a Point) -> &'b Point`. This will not compile "
@@ -7192,11 +6494,11 @@ msgstr ""
"compilará porque la relación entre los tiempos de vida de `'a` y `'b` no "
"está clara."
-#: src/ownership/lifetimes-function-calls.md:53
+#: src/ownership/lifetimes-function-calls.md:55
msgid "Another way to explain it:"
msgstr "Otra forma de explicarlo:"
-#: src/ownership/lifetimes-function-calls.md:54
+#: src/ownership/lifetimes-function-calls.md:56
msgid ""
"Two references to two values are borrowed by a function and the function "
"returns another reference."
@@ -7204,13 +6506,13 @@ msgstr ""
"Una función toma prestadas dos referencias a dos valores y devuelve otra "
"referencia."
-#: src/ownership/lifetimes-function-calls.md:56
+#: src/ownership/lifetimes-function-calls.md:58
msgid ""
"It must have come from one of those two inputs (or from a global variable)."
msgstr ""
"Esta debe proceder de una de esas dos entradas (o de una variable global)."
-#: src/ownership/lifetimes-function-calls.md:57
+#: src/ownership/lifetimes-function-calls.md:59
msgid ""
"Which one is it? The compiler needs to know, so at the call site the "
"returned reference is not used for longer than a variable from where the "
@@ -7227,26 +6529,24 @@ msgstr ""
"Si un tipo de datos almacena datos prestados, se debe anotar con tiempo de "
"vida:"
-#: src/ownership/lifetimes-data-structures.md:5
-msgid ""
-"```rust,editable\n"
-"#[derive(Debug)]\n"
-"struct Highlight<'doc>(&'doc str);\n"
-"\n"
-"fn erase(text: String) {\n"
-" println!(\"Bye {text}!\");\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let text = String::from(\"The quick brown fox jumps over the lazy dog."
-"\");\n"
-" let fox = Highlight(&text[4..19]);\n"
-" let dog = Highlight(&text[35..43]);\n"
-" // erase(text);\n"
-" println!(\"{fox:?}\");\n"
-" println!(\"{dog:?}\");\n"
-"}\n"
-"```"
+#: src/ownership/lifetimes-data-structures.md:10
+msgid "\"Bye {text}!\""
+msgstr ""
+
+#: src/ownership/lifetimes-data-structures.md:14
+msgid "\"The quick brown fox jumps over the lazy dog.\""
+msgstr ""
+
+#: src/ownership/lifetimes-data-structures.md:17
+msgid "// erase(text);\n"
+msgstr ""
+
+#: src/ownership/lifetimes-data-structures.md:18
+msgid "\"{fox:?}\""
+msgstr ""
+
+#: src/ownership/lifetimes-data-structures.md:19
+msgid "\"{dog:?}\""
msgstr ""
#: src/ownership/lifetimes-data-structures.md:25
@@ -7300,31 +6600,17 @@ msgstr ""
msgid "Like C and C++, Rust has support for custom structs:"
msgstr "Al igual que C y C++, Rust admite estructuras (struct) personalizadas:"
-#: src/structs.md:5
-msgid ""
-"```rust,editable\n"
-"struct Person {\n"
-" name: String,\n"
-" age: u8,\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let mut peter = Person {\n"
-" name: String::from(\"Peter\"),\n"
-" age: 27,\n"
-" };\n"
-" println!(\"{} is {} years old\", peter.name, peter.age);\n"
-" \n"
-" peter.age = 28;\n"
-" println!(\"{} is {} years old\", peter.name, peter.age);\n"
-" \n"
-" let jackie = Person {\n"
-" name: String::from(\"Jackie\"),\n"
-" ..peter\n"
-" };\n"
-" println!(\"{} is {} years old\", jackie.name, jackie.age);\n"
-"}\n"
-"```"
+#: src/structs.md:13 src/structs/field-shorthand.md:20 src/methods.md:21
+#: src/android/interoperability/with-c/bindgen.md:87
+msgid "\"Peter\""
+msgstr ""
+
+#: src/structs.md:16 src/structs.md:19 src/structs.md:25
+msgid "\"{} is {} years old\""
+msgstr ""
+
+#: src/structs.md:22
+msgid "\"Jackie\""
msgstr ""
#: src/structs.md:33
@@ -7358,8 +6644,13 @@ msgstr ""
"diferentes tipos de estructuras. "
#: src/structs.md:38
+#, fuzzy
+#| msgid ""
+#| "Zero-sized structs `e.g., struct Foo;` might be used when implementing a "
+#| "trait on some type but don’t have any data that you want to store in the "
+#| "value itself. "
msgid ""
-"Zero-sized structs `e.g., struct Foo;` might be used when implementing a "
+"Zero-sized structs (e.g. `struct Foo;`) might be used when implementing a "
"trait on some type but don’t have any data that you want to store in the "
"value itself. "
msgstr ""
@@ -7391,16 +6682,8 @@ msgstr ""
"Si los nombres de los campos no son importantes, puedes utilizar una "
"estructura de tuplas:"
-#: src/structs/tuple-structs.md:5
-msgid ""
-"```rust,editable\n"
-"struct Point(i32, i32);\n"
-"\n"
-"fn main() {\n"
-" let p = Point(17, 23);\n"
-" println!(\"({}, {})\", p.0, p.1);\n"
-"}\n"
-"```"
+#: src/structs/tuple-structs.md:10
+msgid "\"({}, {})\""
msgstr ""
#: src/structs/tuple-structs.md:14
@@ -7409,26 +6692,14 @@ msgstr ""
"Esto se suele utilizar para envoltorios de campo único (denominados "
"newtypes):"
-#: src/structs/tuple-structs.md:16
-msgid ""
-"```rust,editable,compile_fail\n"
-"struct PoundsOfForce(f64);\n"
-"struct Newtons(f64);\n"
-"\n"
-"fn compute_thruster_force() -> PoundsOfForce {\n"
-" todo!(\"Ask a rocket scientist at NASA\")\n"
-"}\n"
-"\n"
-"fn set_thruster_force(force: Newtons) {\n"
-" // ...\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let force = compute_thruster_force();\n"
-" set_thruster_force(force);\n"
-"}\n"
-"\n"
-"```"
+#: src/structs/tuple-structs.md:21
+msgid "\"Ask a rocket scientist at NASA\""
+msgstr ""
+
+#: src/structs/tuple-structs.md:25
+#: src/bare-metal/microcontrollers/type-state.md:14
+#: src/async/pitfalls/cancellation.md:96 src/async/pitfalls/cancellation.md:99
+msgid "// ...\n"
msgstr ""
#: src/structs/tuple-structs.md:37
@@ -7445,9 +6716,14 @@ msgstr ""
"El número se mide en algunas unidades: `Newtons` en el ejemplo anterior."
#: src/structs/tuple-structs.md:39
+#, fuzzy
+#| msgid ""
+#| "The value passed some validation when it was created, so you no longer "
+#| "have to validate it again at every use: "
+#| "'PhoneNumber(String)`or`OddNumber(u32)\\`."
msgid ""
"The value passed some validation when it was created, so you no longer have "
-"to validate it again at every use: 'PhoneNumber(String)`or`OddNumber(u32)\\`."
+"to validate it again at every use: `PhoneNumber(String)` or `OddNumber(u32)`."
msgstr ""
"El valor ha pasado alguna validación cuando se ha creado, por lo que ya no "
"tendrás que volver a validarlo cada vez que lo uses: `PhoneNumber(String)` u "
@@ -7489,26 +6765,8 @@ msgstr ""
"Si ya dispones de variables con los nombres adecuados, puedes crear la "
"estructura con un método abreviado:"
-#: src/structs/field-shorthand.md:6
-msgid ""
-"```rust,editable\n"
-"#[derive(Debug)]\n"
-"struct Person {\n"
-" name: String,\n"
-" age: u8,\n"
-"}\n"
-"\n"
-"impl Person {\n"
-" fn new(name: String, age: u8) -> Person {\n"
-" Person { name, age }\n"
-" }\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let peter = Person::new(String::from(\"Peter\"), 27);\n"
-" println!(\"{peter:?}\");\n"
-"}\n"
-"```"
+#: src/structs/field-shorthand.md:21
+msgid "\"{peter:?}\""
msgstr ""
#: src/structs/field-shorthand.md:27
@@ -7519,22 +6777,6 @@ msgstr ""
"La función `new` se podría escribir utilizando `Self` como tipo, ya que es "
"intercambiable con el nombre de tipo de estructura."
-#: src/structs/field-shorthand.md:29
-msgid ""
-"```rust,editable\n"
-"#[derive(Debug)]\n"
-"struct Person {\n"
-" name: String,\n"
-" age: u8,\n"
-"}\n"
-"impl Person {\n"
-" fn new(name: String, age: u8) -> Self {\n"
-" Self { name, age }\n"
-" }\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/structs/field-shorthand.md:41
msgid ""
"Implement the `Default` trait for the struct. Define some fields and use the "
@@ -7543,32 +6785,12 @@ msgstr ""
"Implementa el trait `Default` en la estructura. Define algunos campos y usa "
"los valores predeterminados para el resto de los campos."
-#: src/structs/field-shorthand.md:43
-msgid ""
-"```rust,editable\n"
-"#[derive(Debug)]\n"
-"struct Person {\n"
-" name: String,\n"
-" age: u8,\n"
-"}\n"
-"impl Default for Person {\n"
-" fn default() -> Person {\n"
-" Person {\n"
-" name: \"Bot\".to_string(),\n"
-" age: 0,\n"
-" }\n"
-" }\n"
-"}\n"
-"fn create_default() {\n"
-" let tmp = Person {\n"
-" ..Person::default()\n"
-" };\n"
-" let tmp = Person {\n"
-" name: \"Sam\".to_string(),\n"
-" ..Person::default()\n"
-" };\n"
-"}\n"
-"```"
+#: src/structs/field-shorthand.md:52
+msgid "\"Bot\""
+msgstr ""
+
+#: src/structs/field-shorthand.md:62
+msgid "\"Sam\""
msgstr ""
#: src/structs/field-shorthand.md:68
@@ -7599,29 +6821,8 @@ msgstr ""
"Rust te permite asociar funciones a los nuevos tipos. Para ello, usa un "
"bloque `impl`:"
-#: src/methods.md:6
-msgid ""
-"```rust,editable\n"
-"#[derive(Debug)]\n"
-"struct Person {\n"
-" name: String,\n"
-" age: u8,\n"
-"}\n"
-"\n"
-"impl Person {\n"
-" fn say_hello(&self) {\n"
-" println!(\"Hello, my name is {}\", self.name);\n"
-" }\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let peter = Person {\n"
-" name: String::from(\"Peter\"),\n"
-" age: 27,\n"
-" };\n"
-" peter.say_hello();\n"
-"}\n"
-"```"
+#: src/methods.md:15
+msgid "\"Hello, my name is {}\""
msgstr ""
#: src/methods.md:31
@@ -7761,50 +6962,40 @@ msgstr ""
"referenciar una estructura desde varias ubicaciones y llamar a un método "
"mutable (`&mut self`) en ella."
-#: src/methods/example.md:3
-msgid ""
-"```rust,editable\n"
-"#[derive(Debug)]\n"
-"struct Race {\n"
-" name: String,\n"
-" laps: Vec,\n"
-"}\n"
-"\n"
-"impl Race {\n"
-" fn new(name: &str) -> Race { // No receiver, a static method\n"
-" Race { name: String::from(name), laps: Vec::new() }\n"
-" }\n"
-"\n"
-" fn add_lap(&mut self, lap: i32) { // Exclusive borrowed read-write "
-"access to self\n"
-" self.laps.push(lap);\n"
-" }\n"
-"\n"
-" fn print_laps(&self) { // Shared and read-only borrowed access to self\n"
-" println!(\"Recorded {} laps for {}:\", self.laps.len(), self.name);\n"
-" for (idx, lap) in self.laps.iter().enumerate() {\n"
-" println!(\"Lap {idx}: {lap} sec\");\n"
-" }\n"
-" }\n"
-"\n"
-" fn finish(self) { // Exclusive ownership of self\n"
-" let total = self.laps.iter().sum::();\n"
-" println!(\"Race {} is finished, total lap time: {}\", self.name, "
-"total);\n"
-" }\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let mut race = Race::new(\"Monaco Grand Prix\");\n"
-" race.add_lap(70);\n"
-" race.add_lap(68);\n"
-" race.print_laps();\n"
-" race.add_lap(71);\n"
-" race.print_laps();\n"
-" race.finish();\n"
-" // race.add_lap(42);\n"
-"}\n"
-"```"
+#: src/methods/example.md:11
+msgid "// No receiver, a static method\n"
+msgstr ""
+
+#: src/methods/example.md:15
+msgid "// Exclusive borrowed read-write access to self\n"
+msgstr ""
+
+#: src/methods/example.md:19
+msgid "// Shared and read-only borrowed access to self\n"
+msgstr ""
+
+#: src/methods/example.md:20
+msgid "\"Recorded {} laps for {}:\""
+msgstr ""
+
+#: src/methods/example.md:22
+msgid "\"Lap {idx}: {lap} sec\""
+msgstr ""
+
+#: src/methods/example.md:26
+msgid "// Exclusive ownership of self\n"
+msgstr ""
+
+#: src/methods/example.md:28
+msgid "\"Race {} is finished, total lap time: {}\""
+msgstr ""
+
+#: src/methods/example.md:33
+msgid "\"Monaco Grand Prix\""
+msgstr ""
+
+#: src/methods/example.md:40
+msgid "// race.add_lap(42);\n"
msgstr ""
#: src/methods/example.md:47
@@ -7872,19 +7063,12 @@ msgstr ""
"Mañana conoceremos mucho mejor _structs_ y el tipo `Vec`. Por ahora, solo "
"debes conocer parte de su API:"
-#: src/exercises/day-2/book-library.md:6
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let mut vec = vec![10, 20];\n"
-" vec.push(30);\n"
-" let midpoint = vec.len() / 2;\n"
-" println!(\"middle value: {}\", vec[midpoint]);\n"
-" for item in &vec {\n"
-" println!(\"item: {item}\");\n"
-" }\n"
-"}\n"
-"```"
+#: src/exercises/day-2/book-library.md:11
+msgid "\"middle value: {}\""
+msgstr ""
+
+#: src/exercises/day-2/book-library.md:13
+msgid "\"item: {item}\""
msgstr ""
#: src/exercises/day-2/book-library.md:18
@@ -7896,98 +7080,93 @@ msgstr ""
"Copia el código que aparece abajo en y "
"actualiza los tipos para que compile:"
-#: src/exercises/day-2/book-library.md:21
+#: src/exercises/day-2/book-library.md:32
+#: src/exercises/day-2/solutions-morning.md:18
+msgid "// This is a constructor, used below.\n"
+msgstr ""
+
+#: src/exercises/day-2/book-library.md:40
+#: src/exercises/day-2/solutions-morning.md:26
msgid ""
-"```rust,should_panic\n"
-"struct Library {\n"
-" books: Vec,\n"
-"}\n"
-"\n"
-"struct Book {\n"
-" title: String,\n"
-" year: u16,\n"
-"}\n"
-"\n"
-"impl Book {\n"
-" // This is a constructor, used below.\n"
-" fn new(title: &str, year: u16) -> Book {\n"
-" Book {\n"
-" title: String::from(title),\n"
-" year,\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"// Implement the methods below. Update the `self` parameter to\n"
-"// indicate the method's required level of ownership over the object:\n"
+"// Implement the methods below. Notice how the `self` parameter\n"
+"// changes type to indicate the method's required level of ownership\n"
+"// over the object:\n"
"//\n"
"// - `&self` for shared read-only access,\n"
"// - `&mut self` for unique and mutable access,\n"
"// - `self` for unique access by value.\n"
-"impl Library {\n"
-" fn new() -> Library {\n"
-" todo!(\"Initialize and return a `Library` value\")\n"
-" }\n"
-"\n"
-" //fn len(self) -> usize {\n"
-" // todo!(\"Return the length of `self.books`\")\n"
-" //}\n"
-"\n"
-" //fn is_empty(self) -> bool {\n"
-" // todo!(\"Return `true` if `self.books` is empty\")\n"
-" //}\n"
-"\n"
-" //fn add_book(self, book: Book) {\n"
-" // todo!(\"Add a new book to `self.books`\")\n"
-" //}\n"
-"\n"
-" //fn print_books(self) {\n"
-" // todo!(\"Iterate over `self.books` and each book's title and "
-"year\")\n"
-" //}\n"
-"\n"
-" //fn oldest_book(self) -> Option<&Book> {\n"
-" // todo!(\"Return a reference to the oldest book (if any)\")\n"
-" //}\n"
-"}\n"
-"\n"
-"// This shows the desired behavior. Uncomment the code below and\n"
-"// implement the missing methods. You will need to update the\n"
-"// method signatures, including the \"self\" parameter! You may\n"
-"// also need to update the variable bindings within main.\n"
-"fn main() {\n"
-" let library = Library::new();\n"
-"\n"
-" //println!(\"The library is empty: library.is_empty() -> {}\", library."
-"is_empty());\n"
-" //\n"
-" //library.add_book(Book::new(\"Lord of the Rings\", 1954));\n"
-" //library.add_book(Book::new(\"Alice's Adventures in Wonderland\", "
-"1865));\n"
-" //\n"
-" //println!(\"The library is no longer empty: library.is_empty() -> {}\", "
-"library.is_empty());\n"
-" //\n"
-" //\n"
-" //library.print_books();\n"
-" //\n"
-" //match library.oldest_book() {\n"
-" // Some(book) => println!(\"The oldest book is {}\", book.title),\n"
-" // None => println!(\"The library is empty!\"),\n"
-" //}\n"
-" //\n"
-" //println!(\"The library has {} books\", library.len());\n"
-" //library.print_books();\n"
-"}\n"
-"```"
msgstr ""
-#: src/exercises/day-2/book-library.md:102
-msgid "[Solution](solutions-afternoon.md#designing-a-library)"
-msgstr "[Soluciones](solutions-afternoon.md#designing-a-library)"
+#: src/exercises/day-2/book-library.md:50
+msgid "\"Initialize and return a `Library` value\""
+msgstr ""
-#: src/exercises/day-2/health-statistics.md:3
-msgid ""
+#: src/exercises/day-2/book-library.md:54
+msgid "\"Return the length of `self.books`\""
+msgstr ""
+
+#: src/exercises/day-2/book-library.md:58
+msgid "\"Return `true` if `self.books` is empty\""
+msgstr ""
+
+#: src/exercises/day-2/book-library.md:62
+msgid "\"Add a new book to `self.books`\""
+msgstr ""
+
+#: src/exercises/day-2/book-library.md:66
+msgid "\"Iterate over `self.books` and print each book's title and year\""
+msgstr ""
+
+#: src/exercises/day-2/book-library.md:70
+msgid "\"Return a reference to the oldest book (if any)\""
+msgstr ""
+
+#: src/exercises/day-2/book-library.md:78
+#: src/exercises/day-2/solutions-morning.md:78
+msgid "\"The library is empty: library.is_empty() -> {}\""
+msgstr ""
+
+#: src/exercises/day-2/book-library.md:82
+#: src/exercises/day-2/solutions-morning.md:82
+#: src/exercises/day-2/solutions-morning.md:107
+#: src/exercises/day-2/solutions-morning.md:118
+#: src/exercises/day-2/solutions-morning.md:125
+#: src/exercises/day-2/solutions-morning.md:137
+#: src/exercises/day-2/solutions-morning.md:140
+msgid "\"Lord of the Rings\""
+msgstr ""
+
+#: src/exercises/day-2/book-library.md:83
+#: src/exercises/day-2/solutions-morning.md:83
+#: src/exercises/day-2/solutions-morning.md:108
+#: src/exercises/day-2/solutions-morning.md:126
+#: src/exercises/day-2/solutions-morning.md:143
+#: src/exercises/day-2/solutions-morning.md:146
+msgid "\"Alice's Adventures in Wonderland\""
+msgstr ""
+
+#: src/exercises/day-2/book-library.md:86
+#: src/exercises/day-2/solutions-morning.md:86
+msgid "\"The library is no longer empty: library.is_empty() -> {}\""
+msgstr ""
+
+#: src/exercises/day-2/book-library.md:93
+#: src/exercises/day-2/solutions-morning.md:93
+msgid "\"The oldest book is {}\""
+msgstr ""
+
+#: src/exercises/day-2/book-library.md:94
+#: src/exercises/day-2/solutions-morning.md:94
+msgid "\"The library is empty!\""
+msgstr ""
+
+#: src/exercises/day-2/book-library.md:97
+#: src/exercises/day-2/solutions-morning.md:97
+msgid "\"The library has {} books\""
+msgstr ""
+
+#: src/exercises/day-2/health-statistics.md:3
+msgid ""
"You're working on implementing a health-monitoring system. As part of that, "
"you need to keep track of users' health statistics."
msgstr ""
@@ -8013,113 +7192,70 @@ msgstr ""
"Copia el fragmento de código que aparece más abajo en la página y rellena los métodos que faltan:"
-#: src/exercises/day-2/health-statistics.md:13
+#: src/exercises/day-2/health-statistics.md:39
+msgid "\"Create a new User instance\""
+msgstr ""
+
+#: src/exercises/day-2/health-statistics.md:43
+msgid "\"Return the user's name\""
+msgstr ""
+
+#: src/exercises/day-2/health-statistics.md:47
+msgid "\"Return the user's age\""
+msgstr ""
+
+#: src/exercises/day-2/health-statistics.md:51
+#, fuzzy
+#| msgid "Run the server with:"
+msgid "\"Return the user's height\""
+msgstr "Ejecuta el servidor con:"
+
+#: src/exercises/day-2/health-statistics.md:55
+msgid "\"Return the number of time the user has visited the doctor\""
+msgstr ""
+
+#: src/exercises/day-2/health-statistics.md:59
+msgid "\"Set the user's age\""
+msgstr ""
+
+#: src/exercises/day-2/health-statistics.md:63
+msgid "\"Set the user's height\""
+msgstr ""
+
+#: src/exercises/day-2/health-statistics.md:67
msgid ""
-"```rust,should_panic\n"
-"// TODO: remove this when you're done with your implementation.\n"
-"#![allow(unused_variables, dead_code)]\n"
-"\n"
-"pub struct User {\n"
-" name: String,\n"
-" age: u32,\n"
-" height: f32,\n"
-" visit_count: usize,\n"
-" last_blood_pressure: Option<(u32, u32)>,\n"
-"}\n"
-"\n"
-"pub struct Measurements {\n"
-" height: f32,\n"
-" blood_pressure: (u32, u32),\n"
-"}\n"
-"\n"
-"pub struct HealthReport<'a> {\n"
-" patient_name: &'a str,\n"
-" visit_count: u32,\n"
-" height_change: f32,\n"
-" blood_pressure_change: Option<(i32, i32)>,\n"
-"}\n"
-"\n"
-"impl User {\n"
-" pub fn new(name: String, age: u32, height: f32) -> Self {\n"
-" unimplemented!()\n"
-" }\n"
-"\n"
-" pub fn name(&self) -> &str {\n"
-" unimplemented!()\n"
-" }\n"
-"\n"
-" pub fn age(&self) -> u32 {\n"
-" unimplemented!()\n"
-" }\n"
-"\n"
-" pub fn height(&self) -> f32 {\n"
-" unimplemented!()\n"
-" }\n"
-"\n"
-" pub fn doctor_visits(&self) -> u32 {\n"
-" unimplemented!()\n"
-" }\n"
-"\n"
-" pub fn set_age(&mut self, new_age: u32) {\n"
-" unimplemented!()\n"
-" }\n"
-"\n"
-" pub fn set_height(&mut self, new_height: f32) {\n"
-" unimplemented!()\n"
-" }\n"
-"\n"
-" pub fn visit_doctor(&mut self, measurements: Measurements) -> "
-"HealthReport {\n"
-" unimplemented!()\n"
-" }\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let bob = User::new(String::from(\"Bob\"), 32, 155.2);\n"
-" println!(\"I'm {} and my age is {}\", bob.name(), bob.age());\n"
-"}\n"
-"\n"
-"#[test]\n"
-"fn test_height() {\n"
-" let bob = User::new(String::from(\"Bob\"), 32, 155.2);\n"
-" assert_eq!(bob.height(), 155.2);\n"
-"}\n"
-"\n"
-"#[test]\n"
-"fn test_set_age() {\n"
-" let mut bob = User::new(String::from(\"Bob\"), 32, 155.2);\n"
-" assert_eq!(bob.age(), 32);\n"
-" bob.set_age(33);\n"
-" assert_eq!(bob.age(), 33);\n"
-"}\n"
-"\n"
-"#[test]\n"
-"fn test_visit() {\n"
-" let mut bob = User::new(String::from(\"Bob\"), 32, 155.2);\n"
-" assert_eq!(bob.doctor_visits(), 0);\n"
-" let report = bob.visit_doctor(Measurements {\n"
-" height: 156.1,\n"
-" blood_pressure: (120, 80),\n"
-" });\n"
-" assert_eq!(report.patient_name, \"Bob\");\n"
-" assert_eq!(report.visit_count, 1);\n"
-" assert_eq!(report.blood_pressure_change, None);\n"
-"\n"
-" let report = bob.visit_doctor(Measurements {\n"
-" height: 156.1,\n"
-" blood_pressure: (115, 76),\n"
-" });\n"
-"\n"
-" assert_eq!(report.visit_count, 2);\n"
-" assert_eq!(report.blood_pressure_change, Some((-5, -4)));\n"
-"}\n"
-"```"
+"\"Update a user's statistics based on measurements from a visit to the "
+"doctor\""
+msgstr ""
+
+#: src/exercises/day-2/health-statistics.md:72
+#: src/exercises/day-2/health-statistics.md:78
+#: src/exercises/day-2/health-statistics.md:84
+#: src/exercises/day-2/health-statistics.md:92
+#: src/exercises/day-2/health-statistics.md:98
+#: src/android/build-rules/library.md:44 src/android/aidl/client.md:23
+#: src/exercises/day-2/solutions-morning.md:233
+#: src/exercises/day-2/solutions-morning.md:239
+#: src/exercises/day-2/solutions-morning.md:245
+#: src/exercises/day-2/solutions-morning.md:253
+#: src/exercises/day-2/solutions-morning.md:259
+msgid "\"Bob\""
+msgstr ""
+
+#: src/exercises/day-2/health-statistics.md:73
+#: src/exercises/day-2/solutions-morning.md:234
+msgid "\"I'm {} and my age is {}\""
msgstr ""
#: src/std.md:3
+#, fuzzy
+#| msgid ""
+#| "Rust comes with a standard library which helps establish a set of common "
+#| "types used by Rust library and programs. This way, two libraries can work "
+#| "together smoothly because they both use the same `String` type."
msgid ""
"Rust comes with a standard library which helps establish a set of common "
-"types used by Rust library and programs. This way, two libraries can work "
+"types used by Rust libraries and programs. This way, two libraries can work "
"together smoothly because they both use the same `String` type."
msgstr ""
"Rust viene con una biblioteca estándar que ayuda a establecer un conjunto de "
@@ -8210,18 +7346,12 @@ msgstr "`Option` y `Result`"
msgid "The types represent optional data:"
msgstr "Los tipos representan datos opcionales:"
-#: src/std/option-result.md:5
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let numbers = vec![10, 20, 30];\n"
-" let first: Option<&i8> = numbers.first();\n"
-" println!(\"first: {first:?}\");\n"
-"\n"
-" let idx: Result = numbers.binary_search(&10);\n"
-" println!(\"idx: {idx:?}\");\n"
-"}\n"
-"```"
+#: src/std/option-result.md:9
+msgid "\"first: {first:?}\""
+msgstr ""
+
+#: src/std/option-result.md:12
+msgid "\"arr: {arr:?}\""
msgstr ""
#: src/std/option-result.md:18
@@ -8241,21 +7371,19 @@ msgstr ""
"como veremos el día 3."
#: src/std/option-result.md:21
-msgid "`binary_search` returns `Result`."
-msgstr "`binary_search` devuelve `Result`."
+msgid ""
+"`try_into` attempts to convert the vector into a fixed-sized array. This can "
+"fail:"
+msgstr ""
#: src/std/option-result.md:22
-msgid "If found, `Result::Ok` holds the index where the element is found."
+msgid ""
+"If the vector has the right size, `Result::Ok` is returned with the array."
msgstr ""
-"Si se encuentra, `Result::Ok` contiene el índice donde se halla el elemento."
#: src/std/option-result.md:23
-msgid ""
-"Otherwise, `Result::Err` contains the index where such an element should be "
-"inserted."
+msgid "Otherwise, `Result::Err` is returned with the original vector."
msgstr ""
-"De lo contrario, `Result::Err` contendrá el índice donde se debe insertar "
-"dicho elemento."
#: src/std/string.md:3
msgid ""
@@ -8265,24 +7393,24 @@ msgstr ""
"[`String`](https://doc.rust-lang.org/std/string/struct.String.html) es el "
"búfer de cadena UTF-8 estándar, ampliable y asignado a un _heap_:"
-#: src/std/string.md:5
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let mut s1 = String::new();\n"
-" s1.push_str(\"Hello\");\n"
-" println!(\"s1: len = {}, capacity = {}\", s1.len(), s1.capacity());\n"
-"\n"
-" let mut s2 = String::with_capacity(s1.len() + 1);\n"
-" s2.push_str(&s1);\n"
-" s2.push('!');\n"
-" println!(\"s2: len = {}, capacity = {}\", s2.len(), s2.capacity());\n"
-"\n"
-" let s3 = String::from(\"🇨🇭\");\n"
-" println!(\"s3: len = {}, number of chars = {}\", s3.len(),\n"
-" s3.chars().count());\n"
-"}\n"
-"```"
+#: src/std/string.md:9
+msgid "\"s1: len = {}, capacity = {}\""
+msgstr ""
+
+#: src/std/string.md:13
+msgid "'!'"
+msgstr ""
+
+#: src/std/string.md:14
+msgid "\"s2: len = {}, capacity = {}\""
+msgstr ""
+
+#: src/std/string.md:16
+msgid "\"🇨🇭\""
+msgstr ""
+
+#: src/std/string.md:17
+msgid "\"s3: len = {}, number of chars = {}\""
msgstr ""
#: src/std/string.md:22
@@ -8347,7 +7475,9 @@ msgstr ""
"transparente a los métodos de `str`."
#: src/std/string.md:36
-msgid "Write and compare `let s3 = s1.deref();` and `let s3 = &*s1`;."
+#, fuzzy
+#| msgid "Write and compare `let s3 = s1.deref();` and `let s3 = &*s1`;."
+msgid "Write and compare `let s3 = s1.deref();` and `let s3 = &*s1;`."
msgstr "Escribe y compara `let s3 = s1.deref();` y `let s3 = &*s1`;."
#: src/std/string.md:37
@@ -8392,31 +7522,28 @@ msgstr ""
"[`Vec`](https://doc.rust-lang.org/std/vec/struct.Vec.html) es el búfer "
"estándar redimensionable asignado al _heap_:"
-#: src/std/vec.md:5
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let mut v1 = Vec::new();\n"
-" v1.push(42);\n"
-" println!(\"v1: len = {}, capacity = {}\", v1.len(), v1.capacity());\n"
-"\n"
-" let mut v2 = Vec::with_capacity(v1.len() + 1);\n"
-" v2.extend(v1.iter());\n"
-" v2.push(9999);\n"
-" println!(\"v2: len = {}, capacity = {}\", v2.len(), v2.capacity());\n"
-"\n"
-" // Canonical macro to initialize a vector with elements.\n"
-" let mut v3 = vec![0, 0, 1, 2, 3, 4];\n"
-"\n"
-" // Retain only the even elements.\n"
-" v3.retain(|x| x % 2 == 0);\n"
-" println!(\"{v3:?}\");\n"
-"\n"
-" // Remove consecutive duplicates.\n"
-" v3.dedup();\n"
-" println!(\"{v3:?}\");\n"
-"}\n"
-"```"
+#: src/std/vec.md:9
+msgid "\"v1: len = {}, capacity = {}\""
+msgstr ""
+
+#: src/std/vec.md:14
+msgid "\"v2: len = {}, capacity = {}\""
+msgstr ""
+
+#: src/std/vec.md:16
+msgid "// Canonical macro to initialize a vector with elements.\n"
+msgstr ""
+
+#: src/std/vec.md:19
+msgid "// Retain only the even elements.\n"
+msgstr ""
+
+#: src/std/vec.md:21 src/std/vec.md:25
+msgid "\"{v3:?}\""
+msgstr ""
+
+#: src/std/vec.md:23
+msgid "// Remove consecutive duplicates.\n"
msgstr ""
#: src/std/vec.md:29
@@ -8484,42 +7611,44 @@ msgstr "`HashMap`"
msgid "Standard hash map with protection against HashDoS attacks:"
msgstr "Mapa hash estándar con protección frente a ataques HashDoS:"
-#: src/std/hashmap.md:5
-msgid ""
-"```rust,editable\n"
-"use std::collections::HashMap;\n"
-"\n"
-"fn main() {\n"
-" let mut page_counts = HashMap::new();\n"
-" page_counts.insert(\"Adventures of Huckleberry Finn\".to_string(), "
-"207);\n"
-" page_counts.insert(\"Grimms' Fairy Tales\".to_string(), 751);\n"
-" page_counts.insert(\"Pride and Prejudice\".to_string(), 303);\n"
-"\n"
-" if !page_counts.contains_key(\"Les Misérables\") {\n"
-" println!(\"We know about {} books, but not Les Misérables.\",\n"
-" page_counts.len());\n"
-" }\n"
-"\n"
-" for book in [\"Pride and Prejudice\", \"Alice's Adventure in "
-"Wonderland\"] {\n"
-" match page_counts.get(book) {\n"
-" Some(count) => println!(\"{book}: {count} pages\"),\n"
-" None => println!(\"{book} is unknown.\")\n"
-" }\n"
-" }\n"
-"\n"
-" // Use the .entry() method to insert a value if nothing is found.\n"
-" for book in [\"Pride and Prejudice\", \"Alice's Adventure in "
-"Wonderland\"] {\n"
-" let page_count: &mut i32 = page_counts.entry(book.to_string())."
-"or_insert(0);\n"
-" *page_count += 1;\n"
-" }\n"
-"\n"
-" println!(\"{page_counts:#?}\");\n"
-"}\n"
-"```"
+#: src/std/hashmap.md:10
+msgid "\"Adventures of Huckleberry Finn\""
+msgstr ""
+
+#: src/std/hashmap.md:11
+msgid "\"Grimms' Fairy Tales\""
+msgstr ""
+
+#: src/std/hashmap.md:12 src/std/hashmap.md:19 src/std/hashmap.md:27
+msgid "\"Pride and Prejudice\""
+msgstr ""
+
+#: src/std/hashmap.md:14
+msgid "\"Les Misérables\""
+msgstr ""
+
+#: src/std/hashmap.md:15
+msgid "\"We know about {} books, but not Les Misérables.\""
+msgstr ""
+
+#: src/std/hashmap.md:19 src/std/hashmap.md:27
+msgid "\"Alice's Adventure in Wonderland\""
+msgstr ""
+
+#: src/std/hashmap.md:21
+msgid "\"{book}: {count} pages\""
+msgstr ""
+
+#: src/std/hashmap.md:22
+msgid "\"{book} is unknown.\""
+msgstr ""
+
+#: src/std/hashmap.md:26
+msgid "// Use the .entry() method to insert a value if nothing is found.\n"
+msgstr ""
+
+#: src/std/hashmap.md:32
+msgid "\"{page_counts:#?}\""
msgstr ""
#: src/std/hashmap.md:38
@@ -8538,16 +7667,12 @@ msgstr ""
"La segunda línea insertará el valor alternativo en el hashmap si el libro no "
"se encuentra."
-#: src/std/hashmap.md:41
-msgid ""
-"```rust,ignore\n"
-" let pc1 = page_counts\n"
-" .get(\"Harry Potter and the Sorcerer's Stone \")\n"
-" .unwrap_or(&336);\n"
-" let pc2 = page_counts\n"
-" .entry(\"The Hunger Games\".to_string())\n"
-" .or_insert(374);\n"
-"```"
+#: src/std/hashmap.md:43
+msgid "\"Harry Potter and the Sorcerer's Stone \""
+msgstr ""
+
+#: src/std/hashmap.md:46 src/std/hashmap.md:55
+msgid "\"The Hunger Games\""
msgstr ""
#: src/std/hashmap.md:49
@@ -8569,14 +7694,8 @@ msgstr ""
"nos permite inicializar fácilmente un mapa hash a partir de un _array_ "
"literal:"
-#: src/std/hashmap.md:52
-msgid ""
-"```rust,ignore\n"
-" let page_counts = HashMap::from([\n"
-" (\"Harry Potter and the Sorcerer's Stone\".to_string(), 336),\n"
-" (\"The Hunger Games\".to_string(), 374),\n"
-" ]);\n"
-"```"
+#: src/std/hashmap.md:54
+msgid "\"Harry Potter and the Sorcerer's Stone\""
msgstr ""
#: src/std/hashmap.md:59
@@ -8629,43 +7748,9 @@ msgstr ""
"[`Box`](https://doc.rust-lang.org/std/boxed/struct.Box.html) es un puntero "
"propio de datos en el _heap_:"
-#: src/std/box.md:5
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let five = Box::new(5);\n"
-" println!(\"five: {}\", *five);\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/std/box.md:13
-msgid ""
-"```bob\n"
-" Stack Heap\n"
-".- - - - - - -. .- - - - - - -.\n"
-": : : :\n"
-": five : : :\n"
-": +-----+ : : +-----+ :\n"
-": | o---|---+-----+-->| 5 | :\n"
-": +-----+ : : +-----+ :\n"
-": : : :\n"
-": : : :\n"
-"`- - - - - - -' `- - - - - - -'\n"
-"```"
+#: src/std/box.md:8
+msgid "\"five: {}\""
msgstr ""
-"```bob\n"
-" _Stack_ _Heap_\n"
-".- - - - - - -. .- - - - - - -.\n"
-": : : :\n"
-": five : : :\n"
-": +-----+ : : +-----+ :\n"
-": | o---|---+-----+-->| 5 | :\n"
-": +-----+ : : +-----+ :\n"
-": : : :\n"
-": : : :\n"
-"`- - - - - - -' `- - - - - - -'\n"
-"```"
#: src/std/box.md:26
msgid ""
@@ -8726,21 +7811,8 @@ msgstr ""
"Los tipos de datos recursivos o los tipos de datos con tamaños dinámicos "
"deben utilizar un `Box`:"
-#: src/std/box-recursive.md:5 src/std/box-niche.md:3
-msgid ""
-"```rust,editable\n"
-"#[derive(Debug)]\n"
-"enum List {\n"
-" Cons(T, Box>),\n"
-" Nil,\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let list: List = List::Cons(1, Box::new(List::Cons(2, Box::"
-"new(List::Nil))));\n"
-" println!(\"{list:?}\");\n"
-"}\n"
-"```"
+#: src/std/box-recursive.md:14 src/std/box-niche.md:12
+msgid "\"{list:?}\""
msgstr ""
#: src/std/box-recursive.md:18
@@ -8874,19 +7946,12 @@ msgstr ""
"compartido de referencia contada. Utilízalo cuando necesites hacer "
"referencia a los mismos datos desde varios lugares:"
-#: src/std/rc.md:6
-msgid ""
-"```rust,editable\n"
-"use std::rc::Rc;\n"
-"\n"
-"fn main() {\n"
-" let mut a = Rc::new(10);\n"
-" let mut b = Rc::clone(&a);\n"
-"\n"
-" println!(\"a: {a}\");\n"
-" println!(\"b: {b}\");\n"
-"}\n"
-"```"
+#: src/std/rc.md:13
+msgid "\"a: {a}\""
+msgstr ""
+
+#: src/std/rc.md:14
+msgid "\"b: {b}\""
msgstr ""
#: src/std/rc.md:18
@@ -8978,41 +8043,12 @@ msgstr ""
"exclusivas en tiempo de ejecución y entra en pánico si se utilizan de forma "
"incorrecta."
-#: src/std/cell.md:12
-msgid ""
-"```rust,editable\n"
-"use std::cell::RefCell;\n"
-"use std::rc::Rc;\n"
-"\n"
-"#[derive(Debug, Default)]\n"
-"struct Node {\n"
-" value: i64,\n"
-" children: Vec>>,\n"
-"}\n"
-"\n"
-"impl Node {\n"
-" fn new(value: i64) -> Rc> {\n"
-" Rc::new(RefCell::new(Node { value, ..Node::default() }))\n"
-" }\n"
-"\n"
-" fn sum(&self) -> i64 {\n"
-" self.value + self.children.iter().map(|c| c.borrow().sum()).sum::"
-"()\n"
-" }\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let root = Node::new(1);\n"
-" root.borrow_mut().children.push(Node::new(5));\n"
-" let subtree = Node::new(10);\n"
-" subtree.borrow_mut().children.push(Node::new(11));\n"
-" subtree.borrow_mut().children.push(Node::new(12));\n"
-" root.borrow_mut().children.push(subtree);\n"
-"\n"
-" println!(\"graph: {root:#?}\");\n"
-" println!(\"graph sum: {}\", root.borrow().sum());\n"
-"}\n"
-"```"
+#: src/std/cell.md:40
+msgid "\"graph: {root:#?}\""
+msgstr ""
+
+#: src/std/cell.md:41
+msgid "\"graph sum: {}\""
msgstr ""
#: src/std/cell.md:47
@@ -9067,26 +8103,12 @@ msgstr ""
"Del mismo modo, `mod` nos permite asignar espacios de nombres a funciones y "
"tipos:"
-#: src/modules.md:7
-msgid ""
-"```rust,editable\n"
-"mod foo {\n"
-" pub fn do_something() {\n"
-" println!(\"In the foo module\");\n"
-" }\n"
-"}\n"
-"\n"
-"mod bar {\n"
-" pub fn do_something() {\n"
-" println!(\"In the bar module\");\n"
-" }\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" foo::do_something();\n"
-" bar::do_something();\n"
-"}\n"
-"```"
+#: src/modules.md:10
+msgid "\"In the foo module\""
+msgstr ""
+
+#: src/modules.md:16
+msgid "\"In the bar module\""
msgstr ""
#: src/modules.md:28
@@ -9133,34 +8155,20 @@ msgstr ""
"Es decir, si un elemento está visible en el módulo `foo`, se verá en todos "
"los elementos descendientes de `foo`."
-#: src/modules/visibility.md:10
-msgid ""
-"```rust,editable\n"
-"mod outer {\n"
-" fn private() {\n"
-" println!(\"outer::private\");\n"
-" }\n"
-"\n"
-" pub fn public() {\n"
-" println!(\"outer::public\");\n"
-" }\n"
-"\n"
-" mod inner {\n"
-" fn private() {\n"
-" println!(\"outer::inner::private\");\n"
-" }\n"
-"\n"
-" pub fn public() {\n"
-" println!(\"outer::inner::public\");\n"
-" super::private();\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" outer::public();\n"
-"}\n"
-"```"
+#: src/modules/visibility.md:13
+msgid "\"outer::private\""
+msgstr ""
+
+#: src/modules/visibility.md:17
+msgid "\"outer::public\""
+msgstr ""
+
+#: src/modules/visibility.md:22
+msgid "\"outer::inner::private\""
+msgstr ""
+
+#: src/modules/visibility.md:26
+msgid "\"outer::inner::public\""
msgstr ""
#: src/modules/visibility.md:39
@@ -9236,27 +8244,12 @@ msgstr ""
"Un módulo puede incluir símbolos de otro módulo en el ámbito con `use`. "
"Normalmente, se ve algo como esto en la parte superior de cada módulo:"
-#: src/modules/paths.md:16
-msgid ""
-"```rust,editable\n"
-"use std::collections::HashSet;\n"
-"use std::mem::transmute;\n"
-"```"
-msgstr ""
-
#: src/modules/filesystem.md:3
msgid ""
"Omitting the module content will tell Rust to look for it in another file:"
msgstr ""
"Omitir el contenido del módulo hará que Rust lo busque en otro archivo:"
-#: src/modules/filesystem.md:5
-msgid ""
-"```rust,editable,compile_fail\n"
-"mod garden;\n"
-"```"
-msgstr ""
-
#: src/modules/filesystem.md:9
msgid ""
"This tells rust that the `garden` module content is found at `src/garden."
@@ -9289,23 +8282,23 @@ msgstr ""
"\"comentarios internos del documento\". En ellos se indica el elemento que "
"los contiene, en este caso, un módulo."
-#: src/modules/filesystem.md:20
+#: src/modules/filesystem.md:21
msgid ""
-"```rust,editable,compile_fail\n"
"//! This module implements the garden, including a highly performant "
"germination\n"
"//! implementation.\n"
-"\n"
-"// Re-export types from this module.\n"
-"pub use seeds::SeedPacket;\n"
-"pub use garden::Garden;\n"
-"\n"
-"/// Sow the given seed packets.\n"
-"pub fn sow(seeds: Vec) { todo!() }\n"
-"\n"
-"/// Harvest the produce in the garden that is ready.\n"
-"pub fn harvest(garden: &mut Garden) { todo!() }\n"
-"```"
+msgstr ""
+
+#: src/modules/filesystem.md:23
+msgid "// Re-export types from this module.\n"
+msgstr ""
+
+#: src/modules/filesystem.md:27
+msgid "/// Sow the given seed packets.\n"
+msgstr ""
+
+#: src/modules/filesystem.md:30
+msgid "/// Harvest the produce in the garden that is ready.\n"
msgstr ""
#: src/modules/filesystem.md:37
@@ -9332,17 +8325,6 @@ msgstr ""
"Un anidamiento más profundo puede usar carpetas, incluso si el módulo "
"principal es un archivo:"
-#: src/modules/filesystem.md:44
-msgid ""
-"```ignore\n"
-"src/\n"
-"├── main.rs\n"
-"├── top_module.rs\n"
-"└── top_module/\n"
-" └── sub_module.rs\n"
-"```"
-msgstr ""
-
#: src/modules/filesystem.md:52
msgid ""
"The place rust will look for modules can be changed with a compiler "
@@ -9351,12 +8333,8 @@ msgstr ""
"El lugar donde Rust buscará los módulos se puede cambiar con una directiva "
"del compilador:"
-#: src/modules/filesystem.md:54
-msgid ""
-"```rust,ignore\n"
-"#[path = \"some/path.rs\"]\n"
-"mod some_module;\n"
-"```"
+#: src/modules/filesystem.md:55
+msgid "\"some/path.rs\""
msgstr ""
#: src/modules/filesystem.md:59
@@ -9402,50 +8380,33 @@ msgstr ""
"de un tipo. El trait `Iterator` indica que se puede llamar a `next` hasta "
"que se obtenga `None`:"
-#: src/exercises/day-2/iterators-and-ownership.md:13
-msgid ""
-"```rust\n"
-"pub trait Iterator {\n"
-" type Item;\n"
-" fn next(&mut self) -> Option;\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/exercises/day-2/iterators-and-ownership.md:20
msgid "You use this trait like this:"
msgstr "Utiliza este trait de la siguiente forma:"
-#: src/exercises/day-2/iterators-and-ownership.md:22
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let v: Vec = vec![10, 20, 30];\n"
-" let mut iter = v.iter();\n"
-"\n"
-" println!(\"v[0]: {:?}\", iter.next());\n"
-" println!(\"v[1]: {:?}\", iter.next());\n"
-" println!(\"v[2]: {:?}\", iter.next());\n"
-" println!(\"No more items: {:?}\", iter.next());\n"
-"}\n"
-"```"
+#: src/exercises/day-2/iterators-and-ownership.md:27
+msgid "\"v[0]: {:?}\""
+msgstr ""
+
+#: src/exercises/day-2/iterators-and-ownership.md:28
+msgid "\"v[1]: {:?}\""
+msgstr ""
+
+#: src/exercises/day-2/iterators-and-ownership.md:29
+msgid "\"v[2]: {:?}\""
+msgstr ""
+
+#: src/exercises/day-2/iterators-and-ownership.md:30
+msgid "\"No more items: {:?}\""
msgstr ""
#: src/exercises/day-2/iterators-and-ownership.md:34
msgid "What is the type returned by the iterator? Test your answer here:"
msgstr "¿Qué tipo devuelve el iterador? Prueba tu respuesta aquí:"
-#: src/exercises/day-2/iterators-and-ownership.md:36
-msgid ""
-"```rust,editable,compile_fail\n"
-"fn main() {\n"
-" let v: Vec = vec![10, 20, 30];\n"
-" let mut iter = v.iter();\n"
-"\n"
-" let v0: Option<..> = iter.next();\n"
-" println!(\"v0: {v0:?}\");\n"
-"}\n"
-"```"
+#: src/exercises/day-2/iterators-and-ownership.md:42
+#: src/exercises/day-2/iterators-and-ownership.md:79
+msgid "\"v0: {v0:?}\""
msgstr ""
#: src/exercises/day-2/iterators-and-ownership.md:46
@@ -9465,18 +8426,6 @@ msgstr ""
"El trait `Iterator` te indica cómo _iterar_ una vez que has creado un "
"iterador. El trait relacionado `IntoIterator` indica cómo crear el iterador:"
-#: src/exercises/day-2/iterators-and-ownership.md:53
-msgid ""
-"```rust\n"
-"pub trait IntoIterator {\n"
-" type Item;\n"
-" type IntoIter: Iterator- ;\n"
-"\n"
-" fn into_iter(self) -> Self::IntoIter;\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/exercises/day-2/iterators-and-ownership.md:62
msgid ""
"The syntax here means that every implementation of `IntoIterator` must "
@@ -9505,18 +8454,10 @@ msgstr ""
msgid "Like before, what is the type returned by the iterator?"
msgstr "Al igual que antes, ¿qué tipo devuelve el iterador?"
-#: src/exercises/day-2/iterators-and-ownership.md:73
-msgid ""
-"```rust,editable,compile_fail\n"
-"fn main() {\n"
-" let v: Vec
= vec![String::from(\"foo\"), String::"
-"from(\"bar\")];\n"
-" let mut iter = v.into_iter();\n"
-"\n"
-" let v0: Option<..> = iter.next();\n"
-" println!(\"v0: {v0:?}\");\n"
-"}\n"
-"```"
+#: src/exercises/day-2/iterators-and-ownership.md:75
+#: src/exercises/day-2/iterators-and-ownership.md:91
+#: src/testing/test-modules.md:21
+msgid "\"bar\""
msgstr ""
#: src/exercises/day-2/iterators-and-ownership.md:83
@@ -9533,22 +8474,9 @@ msgstr ""
"Llaman a `into_iter()` sobre una expresión e iteran sobre el iterador "
"resultante:"
-#: src/exercises/day-2/iterators-and-ownership.md:89
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let v: Vec = vec![String::from(\"foo\"), String::"
-"from(\"bar\")];\n"
-"\n"
-" for word in &v {\n"
-" println!(\"word: {word}\");\n"
-" }\n"
-"\n"
-" for word in v {\n"
-" println!(\"word: {word}\");\n"
-" }\n"
-"}\n"
-"```"
+#: src/exercises/day-2/iterators-and-ownership.md:94
+#: src/exercises/day-2/iterators-and-ownership.md:98
+msgid "\"word: {word}\""
msgstr ""
#: src/exercises/day-2/iterators-and-ownership.md:103
@@ -9591,53 +8519,79 @@ msgstr ""
"org/> para hacer la prueba. Prueba a no asignar un `Vec` a los resultados "
"intermedios:"
-#: src/exercises/day-2/strings-iterators.md:12
-msgid ""
-"```rust\n"
-"// TODO: remove this when you're done with your implementation.\n"
-"#![allow(unused_variables, dead_code)]\n"
-"\n"
-"pub fn prefix_matches(prefix: &str, request_path: &str) -> bool {\n"
-" unimplemented!()\n"
-"}\n"
-"\n"
-"#[test]\n"
-"fn test_matches_without_wildcard() {\n"
-" assert!(prefix_matches(\"/v1/publishers\", \"/v1/publishers\"));\n"
-" assert!(prefix_matches(\"/v1/publishers\", \"/v1/publishers/"
-"abc-123\"));\n"
-" assert!(prefix_matches(\"/v1/publishers\", \"/v1/publishers/abc/"
-"books\"));\n"
-"\n"
-" assert!(!prefix_matches(\"/v1/publishers\", \"/v1\"));\n"
-" assert!(!prefix_matches(\"/v1/publishers\", \"/v1/publishersBooks\"));\n"
-" assert!(!prefix_matches(\"/v1/publishers\", \"/v1/parent/"
-"publishers\"));\n"
-"}\n"
-"\n"
-"#[test]\n"
-"fn test_matches_with_wildcard() {\n"
-" assert!(prefix_matches(\n"
-" \"/v1/publishers/*/books\",\n"
-" \"/v1/publishers/foo/books\"\n"
-" ));\n"
-" assert!(prefix_matches(\n"
-" \"/v1/publishers/*/books\",\n"
-" \"/v1/publishers/bar/books\"\n"
-" ));\n"
-" assert!(prefix_matches(\n"
-" \"/v1/publishers/*/books\",\n"
-" \"/v1/publishers/foo/books/book1\"\n"
-" ));\n"
-"\n"
-" assert!(!prefix_matches(\"/v1/publishers/*/books\", \"/v1/"
-"publishers\"));\n"
-" assert!(!prefix_matches(\n"
-" \"/v1/publishers/*/books\",\n"
-" \"/v1/publishers/foo/booksByAuthor\"\n"
-" ));\n"
-"}\n"
-"```"
+#: src/exercises/day-2/strings-iterators.md:22
+#: src/exercises/day-2/strings-iterators.md:23
+#: src/exercises/day-2/strings-iterators.md:24
+#: src/exercises/day-2/strings-iterators.md:26
+#: src/exercises/day-2/strings-iterators.md:27
+#: src/exercises/day-2/strings-iterators.md:28
+#: src/exercises/day-2/strings-iterators.md:46
+#: src/exercises/day-2/solutions-afternoon.md:32
+#: src/exercises/day-2/solutions-afternoon.md:33
+#: src/exercises/day-2/solutions-afternoon.md:34
+#: src/exercises/day-2/solutions-afternoon.md:36
+#: src/exercises/day-2/solutions-afternoon.md:37
+#: src/exercises/day-2/solutions-afternoon.md:38
+#: src/exercises/day-2/solutions-afternoon.md:56
+msgid "\"/v1/publishers\""
+msgstr ""
+
+#: src/exercises/day-2/strings-iterators.md:23
+#: src/exercises/day-2/solutions-afternoon.md:33
+msgid "\"/v1/publishers/abc-123\""
+msgstr ""
+
+#: src/exercises/day-2/strings-iterators.md:24
+#: src/exercises/day-2/solutions-afternoon.md:34
+msgid "\"/v1/publishers/abc/books\""
+msgstr ""
+
+#: src/exercises/day-2/strings-iterators.md:26
+#: src/exercises/day-2/solutions-afternoon.md:36
+msgid "\"/v1\""
+msgstr ""
+
+#: src/exercises/day-2/strings-iterators.md:27
+#: src/exercises/day-2/solutions-afternoon.md:37
+msgid "\"/v1/publishersBooks\""
+msgstr ""
+
+#: src/exercises/day-2/strings-iterators.md:28
+#: src/exercises/day-2/solutions-afternoon.md:38
+msgid "\"/v1/parent/publishers\""
+msgstr ""
+
+#: src/exercises/day-2/strings-iterators.md:34
+#: src/exercises/day-2/strings-iterators.md:38
+#: src/exercises/day-2/strings-iterators.md:42
+#: src/exercises/day-2/strings-iterators.md:46
+#: src/exercises/day-2/strings-iterators.md:48
+#: src/exercises/day-2/solutions-afternoon.md:44
+#: src/exercises/day-2/solutions-afternoon.md:48
+#: src/exercises/day-2/solutions-afternoon.md:52
+#: src/exercises/day-2/solutions-afternoon.md:56
+#: src/exercises/day-2/solutions-afternoon.md:58
+msgid "\"/v1/publishers/*/books\""
+msgstr ""
+
+#: src/exercises/day-2/strings-iterators.md:35
+#: src/exercises/day-2/solutions-afternoon.md:45
+msgid "\"/v1/publishers/foo/books\""
+msgstr ""
+
+#: src/exercises/day-2/strings-iterators.md:39
+#: src/exercises/day-2/solutions-afternoon.md:49
+msgid "\"/v1/publishers/bar/books\""
+msgstr ""
+
+#: src/exercises/day-2/strings-iterators.md:43
+#: src/exercises/day-2/solutions-afternoon.md:53
+msgid "\"/v1/publishers/foo/books/book1\""
+msgstr ""
+
+#: src/exercises/day-2/strings-iterators.md:49
+#: src/exercises/day-2/solutions-afternoon.md:59
+msgid "\"/v1/publishers/foo/booksByAuthor\""
msgstr ""
#: src/welcome-day-3.md:1
@@ -9696,21 +8650,8 @@ msgstr ""
msgid "You can use generics to abstract over the concrete field type:"
msgstr "Puedes usar genéricos para abstraer el tipo de campo concreto:"
-#: src/generics/data-types.md:5
-msgid ""
-"```rust,editable\n"
-"#[derive(Debug)]\n"
-"struct Point {\n"
-" x: T,\n"
-" y: T,\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let integer = Point { x: 5, y: 10 };\n"
-" let float = Point { x: 1.0, y: 4.0 };\n"
-" println!(\"{integer:?} and {float:?}\");\n"
-"}\n"
-"```"
+#: src/generics/data-types.md:15
+msgid "\"{integer:?} and {float:?}\""
msgstr ""
#: src/generics/data-types.md:21
@@ -9728,25 +8669,16 @@ msgstr ""
msgid "You can declare a generic type on your `impl` block:"
msgstr "Puedes declarar un tipo genérico en tu bloque `impl`:"
-#: src/generics/methods.md:5
-msgid ""
-"```rust,editable\n"
-"#[derive(Debug)]\n"
-"struct Point(T, T);\n"
-"\n"
-"impl Point {\n"
-" fn x(&self) -> &T {\n"
-" &self.0 // + 10\n"
-" }\n"
-"\n"
-" // fn set_x(&mut self, x: T)\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let p = Point(5, 10);\n"
-" println!(\"p.x = {}\", p.x());\n"
-"}\n"
-"```"
+#: src/generics/methods.md:11
+msgid "// + 10\n"
+msgstr ""
+
+#: src/generics/methods.md:14
+msgid "// fn set_x(&mut self, x: T)\n"
+msgstr ""
+
+#: src/generics/methods.md:19
+msgid "\"p.x = {}\""
msgstr ""
#: src/generics/methods.md:25
@@ -9787,40 +8719,10 @@ msgstr ""
"El código genérico se convierte en código no genérico en función de los "
"sitios de llamada:"
-#: src/generics/monomorphization.md:5
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let integer = Some(5);\n"
-" let float = Some(5.0);\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/generics/monomorphization.md:12
msgid "behaves as if you wrote"
msgstr "se comporta como si se hubiera escrito"
-#: src/generics/monomorphization.md:14
-msgid ""
-"```rust,editable\n"
-"enum Option_i32 {\n"
-" Some(i32),\n"
-" None,\n"
-"}\n"
-"\n"
-"enum Option_f64 {\n"
-" Some(f64),\n"
-" None,\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let integer = Option_i32::Some(5);\n"
-" let float = Option_f64::Some(5.0);\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/generics/monomorphization.md:31
msgid ""
"This is a zero-cost abstraction: you get exactly the same result as if you "
@@ -9837,44 +8739,24 @@ msgstr ""
"Rust te permite abstraer sobre tipos con _traits_. Son similares a las "
"interfaces:"
-#: src/traits.md:5
-msgid ""
-"```rust,editable\n"
-"trait Pet {\n"
-" fn name(&self) -> String;\n"
-"}\n"
-"\n"
-"struct Dog {\n"
-" name: String,\n"
-"}\n"
-"\n"
-"struct Cat;\n"
-"\n"
-"impl Pet for Dog {\n"
-" fn name(&self) -> String {\n"
-" self.name.clone()\n"
-" }\n"
-"}\n"
-"\n"
-"impl Pet for Cat {\n"
-" fn name(&self) -> String {\n"
-" String::from(\"The cat\") // No name, cats won't respond to it "
-"anyway.\n"
-" }\n"
-"}\n"
-"\n"
-"fn greet(pet: &P) {\n"
-" println!(\"Who's a cutie? {} is!\", pet.name());\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let fido = Dog { name: \"Fido\".into() };\n"
-" greet(&fido);\n"
-"\n"
-" let captain_floof = Cat;\n"
-" greet(&captain_floof);\n"
-"}\n"
-"```"
+#: src/traits.md:7 src/traits/trait-objects.md:7
+msgid "// No name needed, cats won't respond anyway.\n"
+msgstr ""
+
+#: src/traits.md:14 src/traits/trait-objects.md:14
+msgid "\"Woof, my name is {}!\""
+msgstr ""
+
+#: src/traits.md:18 src/traits/trait-objects.md:18
+msgid "\"Miau!\""
+msgstr ""
+
+#: src/traits.md:22
+msgid "\"Oh you're a cutie! What's your name? {}\""
+msgstr ""
+
+#: src/traits.md:27 src/traits/trait-objects.md:24
+msgid "\"Fido\""
msgstr ""
#: src/traits/trait-objects.md:3
@@ -9885,97 +8767,122 @@ msgstr ""
"Los objetos de _traits_ permiten valores de diferentes tipos, por ejemplo, "
"en una colección:"
-#: src/traits/trait-objects.md:5
-msgid ""
-"```rust,editable\n"
-"trait Pet {\n"
-" fn name(&self) -> String;\n"
-"}\n"
-"\n"
-"struct Dog {\n"
-" name: String,\n"
-"}\n"
-"\n"
-"struct Cat;\n"
-"\n"
-"impl Pet for Dog {\n"
-" fn name(&self) -> String {\n"
-" self.name.clone()\n"
-" }\n"
-"}\n"
-"\n"
-"impl Pet for Cat {\n"
-" fn name(&self) -> String {\n"
-" String::from(\"The cat\") // No name, cats won't respond to it "
-"anyway.\n"
-" }\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let pets: Vec> = vec![\n"
-" Box::new(Cat),\n"
-" Box::new(Dog { name: String::from(\"Fido\") }),\n"
-" ];\n"
-" for pet in pets {\n"
-" println!(\"Hello {}!\", pet.name());\n"
-" }\n"
-"}\n"
-"```"
+#: src/traits/trait-objects.md:27
+msgid "\"Hello, who are you? {}\""
msgstr ""
-#: src/traits/trait-objects.md:40
+#: src/traits/trait-objects.md:32
msgid "Memory layout after allocating `pets`:"
msgstr "Diseño de la memoria después de asignar `pets`:"
-#: src/traits/trait-objects.md:42
+#: src/traits/trait-objects.md:34
+#, fuzzy
+#| msgid ""
+#| "```bob\n"
+#| " Stack Heap\n"
+#| ".- - - - - - - - - - - - - -. .- - - - - - - - - - - - - - - - - - - "
+#| "- - - -.\n"
+#| ": : : :\n"
+#| ": "
+#| "pets : : :\n"
+#| ": +-----------+-------+ : : +-----+-----"
+#| "+ :\n"
+#| ": | ptr | o---+---+-----+-->| o o | o o "
+#| "| :\n"
+#| ": | len | 2 | : : +-|-|-+-|-|-"
+#| "+ :\n"
+#| ": | capacity | 2 | : : | | | | +---------------"
+#| "+ :\n"
+#| ": +-----------+-------+ : : | | | '-->| name: \"Fido\" "
+#| "| :\n"
+#| ": : : | | | +---------------"
+#| "+ :\n"
+#| "`- - - - - - - - - - - - - -' : | | "
+#| "| :\n"
+#| " : | | | "
+#| "+----------------------+ : \n"
+#| " : | | '---->| \"::"
+#| "name\" | :\n"
+#| " : | | "
+#| "+----------------------+ : \n"
+#| " : | "
+#| "| : \n"
+#| " : | | +-"
+#| "+ : \n"
+#| " : | '-->|"
+#| "\\| : \n"
+#| " : | +-"
+#| "+ : \n"
+#| " : "
+#| "| : \n"
+#| " : | +----------------------"
+#| "+ : \n"
+#| " : '---->| \"::name\" "
+#| "| : \n"
+#| " : +----------------------"
+#| "+ :\n"
+#| " : :\n"
+#| " '- - - - - - - - - - - - - - - - - - - "
+#| "- - - -'\n"
+#| "\n"
+#| "```"
msgid ""
"```bob\n"
" Stack Heap\n"
".- - - - - - - - - - - - - -. .- - - - - - - - - - - - - - - - - - - - - "
"- -.\n"
": : : :\n"
-": "
-"pets : : :\n"
-": +-----------+-------+ : : +-----+-----"
-"+ :\n"
-": | ptr | o---+---+-----+-->| o o | o o "
-"| :\n"
-": | len | 2 | : : +-|-|-+-|-|-"
-"+ :\n"
-": | capacity | 2 | : : | | | | +---------------"
-"+ :\n"
-": +-----------+-------+ : : | | | '-->| name: \"Fido\" "
-"| :\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"
+" : | | | "
+"vtable :\n"
" : | | | +----------------------"
-"+ : \n"
-" : | | '---->| \"::name\" "
+"+ :\n"
+" : | | '---->| \"::talk\" "
"| :\n"
" : | | +----------------------"
-"+ : \n"
+"+ :\n"
" : | "
-"| : \n"
-" : | | +-"
-"+ : \n"
-" : | '-->|"
-"\\| : \n"
-" : | +-"
-"+ : \n"
+"| :\n"
+" : | | "
+"data :\n"
+" : | | +-------+-------"
+"+ :\n"
+" : | '-->| lives | 9 "
+"| :\n"
+" : | +-------+-------"
+"+ :\n"
" : "
-"| : \n"
+"| :\n"
+" : | "
+"vtable :\n"
" : | +----------------------"
-"+ : \n"
-" : '---->| \"::name\" "
-"| : \n"
+"+ :\n"
+" : '---->| \"::talk\" "
+"| :\n"
" : +----------------------"
"+ :\n"
" : :\n"
" '- - - - - - - - - - - - - - - - - - - - - "
"- -'\n"
-"\n"
"```"
msgstr ""
"```bob\n"
@@ -10027,16 +8934,20 @@ msgstr ""
"\n"
"```"
-#: src/traits/trait-objects.md:72
+#: src/traits/trait-objects.md:68
+#, fuzzy
+#| msgid ""
+#| "Types that implement a given trait may be of different sizes. This makes "
+#| "it impossible to have things like `Vec` in the example above."
msgid ""
"Types that implement a given trait may be of different sizes. This makes it "
-"impossible to have things like `Vec` in the example above."
+"impossible to have things like `Vec` in the example above."
msgstr ""
"Los tipos que implementan un trait determinado pueden tener diferentes "
"tamaños. Esto hace imposible tener elementos como `Vec` en el ejemplo "
"anterior."
-#: src/traits/trait-objects.md:73
+#: src/traits/trait-objects.md:70
msgid ""
"`dyn Pet` is a way to tell the compiler about a dynamically sized type that "
"implements `Pet`."
@@ -10044,32 +8955,50 @@ msgstr ""
"`dyn Pet` es una forma de indicar al compilador un tipo de tamaño dinámico "
"que implementa `Pet`."
+#: src/traits/trait-objects.md:72
+msgid ""
+"In the example, `pets` is allocated on the stack and the vector data is on "
+"the heap. The two vector elements are _fat pointers_:"
+msgstr ""
+
#: src/traits/trait-objects.md:74
+#, fuzzy
+#| msgid ""
+#| "In the example, `pets` holds _fat pointers_ to objects that implement "
+#| "`Pet`. The fat pointer consists of two components, a pointer to the "
+#| "actual object and a pointer to the virtual method table for the `Pet` "
+#| "implementation of that particular object."
msgid ""
-"In the example, `pets` holds _fat pointers_ to objects that implement `Pet`. "
-"The fat pointer consists of two components, a pointer to the actual object "
-"and a pointer to the virtual method table for the `Pet` implementation of "
-"that particular object."
+"A fat pointer is a double-width pointer. It has two components: a pointer to "
+"the actual object and a pointer to the [virtual method table](https://en."
+"wikipedia.org/wiki/Virtual_method_table) (vtable) for the `Pet` "
+"implementation of that particular object."
msgstr ""
"En el ejemplo, `pets` contiene _punteros grandes_ en los objetos que "
"implementan `Pet`. El puntero grande consta de dos componentes: un puntero "
"al objeto real y un puntero a la tabla de métodos virtuales para la "
"implementación de `Pet` en ese objeto concreto."
-#: src/traits/trait-objects.md:75
+#: src/traits/trait-objects.md:77
+msgid ""
+"The data for the `Dog` named Fido is the `name` and `age` fields. The `Cat` "
+"has a `lives` field."
+msgstr ""
+
+#: src/traits/trait-objects.md:79
msgid "Compare these outputs in the above example:"
msgstr "Compara estas salidas en el ejemplo anterior:"
-#: src/traits/trait-objects.md:76
-msgid ""
-"```rust,ignore\n"
-" println!(\"{} {}\", std::mem::size_of::(), std::mem::size_of::"
-"());\n"
-" println!(\"{} {}\", std::mem::size_of::<&Dog>(), std::mem::size_of::"
-"<&Cat>());\n"
-" println!(\"{}\", std::mem::size_of::<&dyn Pet>());\n"
-" println!(\"{}\", std::mem::size_of::>());\n"
-"```"
+#: src/traits/trait-objects.md:81 src/traits/trait-objects.md:82
+#: src/traits/closures.md:54
+msgid "\"{} {}\""
+msgstr ""
+
+#: src/traits/trait-objects.md:83 src/traits/trait-objects.md:84
+#: src/testing/test-modules.md:12 src/android/build-rules/library.md:44
+#: src/async/pitfalls/cancellation.md:59
+#: src/exercises/day-3/solutions-morning.md:128
+msgid "\"{}\""
msgstr ""
#: src/traits/deriving-traits.md:3
@@ -10086,23 +9015,18 @@ msgstr ""
"Puedes dejar que el compilador derive una serie de _traits_ de la siguiente "
"manera:"
-#: src/traits/deriving-traits.md:7
-msgid ""
-"```rust,editable\n"
-"#[derive(Debug, Clone, PartialEq, Eq, Default)]\n"
-"struct Player {\n"
-" name: String,\n"
-" strength: u8,\n"
-" hit_points: u8,\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let p1 = Player::default();\n"
-" let p2 = p1.clone();\n"
-" println!(\"Is {:?}\\nequal to {:?}?\\nThe answer is {}!\", &p1, &p2,\n"
-" if p1 == p2 { \"yes\" } else { \"no\" });\n"
-"}\n"
-"```"
+#: src/traits/deriving-traits.md:18
+msgid "\"Is {:?}\\nequal to {:?}?\\nThe answer is {}!\""
+msgstr ""
+
+#: src/traits/deriving-traits.md:19
+#: src/exercises/day-1/solutions-afternoon.md:43
+msgid "\"yes\""
+msgstr ""
+
+#: src/traits/deriving-traits.md:19
+#: src/exercises/day-1/solutions-afternoon.md:43
+msgid "\"no\""
msgstr ""
#: src/traits/default-methods.md:3
@@ -10111,32 +9035,12 @@ msgstr ""
"Los _traits_ pueden implementar comportamientos en función de otros métodos "
"de _traits_:"
-#: src/traits/default-methods.md:5
-msgid ""
-"```rust,editable\n"
-"trait Equals {\n"
-" fn equals(&self, other: &Self) -> bool;\n"
-" fn not_equals(&self, other: &Self) -> bool {\n"
-" !self.equals(other)\n"
-" }\n"
-"}\n"
-"\n"
-"#[derive(Debug)]\n"
-"struct Centimeter(i16);\n"
-"\n"
-"impl Equals for Centimeter {\n"
-" fn equals(&self, other: &Centimeter) -> bool {\n"
-" self.0 == other.0\n"
-" }\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let a = Centimeter(10);\n"
-" let b = Centimeter(20);\n"
-" println!(\"{a:?} equals {b:?}: {}\", a.equals(&b));\n"
-" println!(\"{a:?} not_equals {b:?}: {}\", a.not_equals(&b));\n"
-"}\n"
-"```"
+#: src/traits/default-methods.md:25
+msgid "\"{a:?} equals {b:?}: {}\""
+msgstr ""
+
+#: src/traits/default-methods.md:26
+msgid "\"{a:?} not_equals {b:?}: {}\""
msgstr ""
#: src/traits/default-methods.md:32
@@ -10158,43 +9062,10 @@ msgstr "Mueve el método `not_equals` a un nuevo trait `NotEquals`."
msgid "Make `Equals` a super trait for `NotEquals`."
msgstr "Haz que `Equals` sea un supertrait para `NotEquals`."
-#: src/traits/default-methods.md:38
-msgid ""
-"```rust,editable,compile_fail\n"
-"trait NotEquals: Equals {\n"
-" fn not_equals(&self, other: &Self) -> bool {\n"
-" !self.equals(other)\n"
-" }\n"
-"}\n"
-"```"
-msgstr ""
-"```rust,editable,compile_fail\n"
-"trait NotEquals: Equals {\n"
-" fn not_equals(&self, other: &Self) -> bool {\n"
-" !self.equals(other)\n"
-" }\n"
-"}\n"
-"```"
-
#: src/traits/default-methods.md:46
msgid "Provide a blanket implementation of `NotEquals` for `Equals`."
msgstr "Proporciona una implementación general de `NotEquals` para `Equals`."
-#: src/traits/default-methods.md:47
-msgid ""
-"```rust,editable,compile_fail\n"
-"trait NotEquals {\n"
-" fn not_equals(&self, other: &Self) -> bool;\n"
-"}\n"
-"\n"
-"impl NotEquals for T where T: Equals {\n"
-" fn not_equals(&self, other: &Self) -> bool {\n"
-" !self.equals(other)\n"
-" }\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/traits/default-methods.md:58
msgid ""
"With the blanket implementation, you no longer need `Equals` as a super "
@@ -10216,32 +9087,26 @@ msgstr ""
msgid "You can do this with `T: Trait` or `impl Trait`:"
msgstr "Puedes hacerlo con `T: Trait` o `impl Trait`:"
-#: src/traits/trait-bounds.md:8
+#: src/traits/trait-bounds.md:12
msgid ""
-"```rust,editable\n"
-"fn duplicate(a: T) -> (T, T) {\n"
-" (a.clone(), a.clone())\n"
-"}\n"
-"\n"
"// Syntactic sugar for:\n"
"// fn add_42_millions>(x: T) -> i32 {\n"
-"fn add_42_millions(x: impl Into) -> i32 {\n"
-" x.into() + 42_000_000\n"
-"}\n"
-"\n"
-"// struct NotClonable;\n"
-"\n"
-"fn main() {\n"
-" let foo = String::from(\"foo\");\n"
-" let pair = duplicate(foo);\n"
-" println!(\"{pair:?}\");\n"
-"\n"
-" let many = add_42_millions(42_i8);\n"
-" println!(\"{many}\");\n"
-" let many_more = add_42_millions(10_000_000);\n"
-" println!(\"{many_more}\");\n"
-"}\n"
-"```"
+msgstr ""
+
+#: src/traits/trait-bounds.md:18
+msgid "// struct NotClonable;\n"
+msgstr ""
+
+#: src/traits/trait-bounds.md:24
+msgid "\"{pair:?}\""
+msgstr ""
+
+#: src/traits/trait-bounds.md:27
+msgid "\"{many}\""
+msgstr ""
+
+#: src/traits/trait-bounds.md:29
+msgid "\"{many_more}\""
msgstr ""
#: src/traits/trait-bounds.md:35
@@ -10250,18 +9115,6 @@ msgstr ""
"Muestra una cláusula `where` para que los alumnos la encuentren al leer el "
"código."
-#: src/traits/trait-bounds.md:37
-msgid ""
-"```rust,ignore\n"
-"fn duplicate(a: T) -> (T, T)\n"
-"where\n"
-" T: Clone,\n"
-"{\n"
-" (a.clone(), a.clone())\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/traits/trait-bounds.md:46
msgid "It declutters the function signature if you have many parameters."
msgstr "Despeja la firma de la función si tienes muchos parámetros."
@@ -10290,22 +9143,6 @@ msgstr ""
"De forma similar a los límites de _traits_, se puede usar la sintaxis `impl "
"Trait` en argumentos de funciones y valores devueltos:"
-#: src/traits/impl-trait.md:6
-msgid ""
-"```rust,editable\n"
-"use std::fmt::Display;\n"
-"\n"
-"fn get_x(name: impl Display) -> impl Display {\n"
-" format!(\"Hello {name}\")\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let x = get_x(\"foo\");\n"
-" println!(\"{x}\");\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/traits/impl-trait.md:19
msgid "`impl Trait` allows you to work with types which you cannot name."
msgstr ""
@@ -10444,32 +9281,8 @@ msgstr ""
"Se puede implementar el trait [`Iterator`](https://doc.rust-lang.org/std/"
"iter/trait.Iterator.html) en tus propios tipos:"
-#: src/traits/iterator.md:5
-msgid ""
-"```rust,editable\n"
-"struct Fibonacci {\n"
-" curr: u32,\n"
-" next: u32,\n"
-"}\n"
-"\n"
-"impl Iterator for Fibonacci {\n"
-" type Item = u32;\n"
-"\n"
-" fn next(&mut self) -> Option {\n"
-" let new_next = self.curr + self.next;\n"
-" self.curr = self.next;\n"
-" self.next = new_next;\n"
-" Some(self.curr)\n"
-" }\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let fib = Fibonacci { curr: 0, next: 1 };\n"
-" for (i, n) in fib.enumerate().take(5) {\n"
-" println!(\"fib({i}): {n}\");\n"
-" }\n"
-"}\n"
-"```"
+#: src/traits/iterator.md:25
+msgid "\"fib({i}): {n}\""
msgstr ""
#: src/traits/iterator.md:32
@@ -10509,20 +9322,11 @@ msgstr ""
"permite construir una colección a partir de un [`Iterator`](https://doc.rust-"
"lang.org/std/iter/trait.Iterator.html)."
-#: src/traits/from-iterator.md:5
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let primes = vec![2, 3, 5, 7];\n"
-" let prime_squares = primes\n"
-" .into_iter()\n"
-" .map(|prime| prime * prime)\n"
-" .collect::>();\n"
-"}\n"
-"```"
+#: src/traits/from-iterator.md:12
+msgid "\"prime_squares: {prime_squares:?}\""
msgstr ""
-#: src/traits/from-iterator.md:17
+#: src/traits/from-iterator.md:18
msgid ""
"`Iterator` implements `fn collect(self) -> B where B: FromIterator, Self: Sized`"
@@ -10530,7 +9334,7 @@ msgstr ""
"`Iterator` implementa `fn collect(self) -> B where B: FromIterator, Self: Sized`."
-#: src/traits/from-iterator.md:23
+#: src/traits/from-iterator.md:24
msgid ""
"There are also implementations which let you do cool things like convert an "
"`Iterator- >` into a `Result
, E>`."
@@ -10552,17 +9356,8 @@ msgstr ""
"From.html) y [`Into`](https://doc.rust-lang.org/std/convert/trait.Into.html) "
"para facilitar las conversiones de tipos:"
-#: src/traits/from-into.md:5
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let s = String::from(\"hello\");\n"
-" let addr = std::net::Ipv4Addr::from([127, 0, 0, 1]);\n"
-" let one = i16::from(true);\n"
-" let bigger = i32::from(123i16);\n"
-" println!(\"{s}, {addr}, {one}, {bigger}\");\n"
-"}\n"
-"```"
+#: src/traits/from-into.md:11 src/traits/from-into.md:23
+msgid "\"{s}, {addr}, {one}, {bigger}\""
msgstr ""
#: src/traits/from-into.md:15
@@ -10575,19 +9370,6 @@ msgstr ""
"implementa automáticamente cuando se implementa [`From`](https://doc.rust-"
"lang.org/std/convert/trait.From.html):"
-#: src/traits/from-into.md:17
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let s: String = \"hello\".into();\n"
-" let addr: std::net::Ipv4Addr = [127, 0, 0, 1].into();\n"
-" let one: i16 = true.into();\n"
-" let bigger: i32 = 123i16.into();\n"
-" println!(\"{s}, {addr}, {one}, {bigger}\");\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/traits/from-into.md:29
msgid ""
"That's why it is common to only implement `From`, as your type will get "
@@ -10622,25 +9404,16 @@ msgstr ""
"[`BufRead`](https://doc.rust-lang.org/std/io/trait.BufRead.html), se puede "
"abstraer sobre fuentes `u8`:"
-#: src/traits/read-write.md:5
-msgid ""
-"```rust,editable\n"
-"use std::io::{BufRead, BufReader, Read, Result};\n"
-"\n"
-"fn count_lines(reader: R) -> usize {\n"
-" let buf_reader = BufReader::new(reader);\n"
-" buf_reader.lines().count()\n"
-"}\n"
-"\n"
-"fn main() -> Result<()> {\n"
-" let slice: &[u8] = b\"foo\\nbar\\nbaz\\n\";\n"
-" println!(\"lines in slice: {}\", count_lines(slice));\n"
-"\n"
-" let file = std::fs::File::open(std::env::current_exe()?)?;\n"
-" println!(\"lines in file: {}\", count_lines(file));\n"
-" Ok(())\n"
-"}\n"
-"```"
+#: src/traits/read-write.md:14
+msgid "b\"foo\\nbar\\nbaz\\n\""
+msgstr ""
+
+#: src/traits/read-write.md:15
+msgid "\"lines in slice: {}\""
+msgstr ""
+
+#: src/traits/read-write.md:18
+msgid "\"lines in file: {}\""
msgstr ""
#: src/traits/read-write.md:23
@@ -10651,24 +9424,12 @@ msgstr ""
"De forma similar, [`Write`](https://doc.rust-lang.org/std/io/trait.Write."
"html) te permite abstraer sobre fuentes `u8`:"
-#: src/traits/read-write.md:25
-msgid ""
-"```rust,editable\n"
-"use std::io::{Result, Write};\n"
-"\n"
-"fn log(writer: &mut W, msg: &str) -> Result<()> {\n"
-" writer.write_all(msg.as_bytes())?;\n"
-" writer.write_all(\"\\n\".as_bytes())\n"
-"}\n"
-"\n"
-"fn main() -> Result<()> {\n"
-" let mut buffer = Vec::new();\n"
-" log(&mut buffer, \"Hello\")?;\n"
-" log(&mut buffer, \"World\")?;\n"
-" println!(\"Logged: {:?}\", buffer);\n"
-" Ok(())\n"
-"}\n"
-"```"
+#: src/traits/read-write.md:30
+msgid "\"\\n\""
+msgstr ""
+
+#: src/traits/read-write.md:37
+msgid "\"Logged: {:?}\""
msgstr ""
#: src/traits/drop.md:1
@@ -10684,45 +9445,82 @@ msgstr ""
"Drop.html) pueden especificar el código que se ejecutará cuando salgan del "
"ámbito:"
-#: src/traits/drop.md:5
-msgid ""
-"```rust,editable\n"
-"struct Droppable {\n"
-" name: &'static str,\n"
-"}\n"
-"\n"
-"impl Drop for Droppable {\n"
-" fn drop(&mut self) {\n"
-" println!(\"Dropping {}\", self.name);\n"
-" }\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let a = Droppable { name: \"a\" };\n"
-" {\n"
-" let b = Droppable { name: \"b\" };\n"
-" {\n"
-" let c = Droppable { name: \"c\" };\n"
-" let d = Droppable { name: \"d\" };\n"
-" println!(\"Exiting block B\");\n"
-" }\n"
-" println!(\"Exiting block A\");\n"
-" }\n"
-" drop(a);\n"
-" println!(\"Exiting main\");\n"
-"}\n"
-"```"
+#: src/traits/drop.md:12
+msgid "\"Dropping {}\""
+msgstr ""
+
+#: src/traits/drop.md:17 src/exercises/concurrency/link-checker.md:92
+#: src/exercises/day-1/solutions-morning.md:86
+#: src/exercises/concurrency/solutions-morning.md:123
+msgid "\"a\""
+msgstr ""
+
+#: src/traits/drop.md:19 src/exercises/day-1/solutions-morning.md:86
+msgid "\"b\""
+msgstr ""
+
+#: src/traits/drop.md:21 src/exercises/day-1/solutions-morning.md:86
+msgid "\"c\""
+msgstr ""
+
+#: src/traits/drop.md:22 src/exercises/day-1/solutions-morning.md:86
+msgid "\"d\""
+msgstr ""
+
+#: src/traits/drop.md:23
+msgid "\"Exiting block B\""
+msgstr ""
+
+#: src/traits/drop.md:25
+msgid "\"Exiting block A\""
+msgstr ""
+
+#: src/traits/drop.md:28
+msgid "\"Exiting main\""
+msgstr ""
+
+#: src/traits/drop.md:34
+msgid "Note that `std::mem::drop` is not the same as `std::ops::Drop::drop`."
+msgstr ""
+
+#: src/traits/drop.md:35
+msgid "Values are automatically dropped when they go out of scope."
+msgstr ""
+
+#: src/traits/drop.md:36
+msgid ""
+"When a value is dropped, if it implements `std::ops::Drop` then its `Drop::"
+"drop` implementation will be called."
+msgstr ""
+
+#: src/traits/drop.md:38
+msgid ""
+"All its fields will then be dropped too, whether or not it implements `Drop`."
+msgstr ""
+
+#: src/traits/drop.md:39
+msgid ""
+"`std::mem::drop` is just an empty function that takes any value. The "
+"significance is that it takes ownership of the value, so at the end of its "
+"scope it gets dropped. This makes it a convenient way to explicitly drop "
+"values earlier than they would otherwise go out of scope."
msgstr ""
-#: src/traits/drop.md:34 src/traits/operators.md:26
+#: src/traits/drop.md:42
+msgid ""
+"This can be useful for objects that do some work on `drop`: releasing locks, "
+"closing files, etc."
+msgstr ""
+
+#: src/traits/drop.md:45 src/traits/operators.md:26
msgid "Discussion points:"
msgstr "Cuestiones de debate:"
-#: src/traits/drop.md:36
+#: src/traits/drop.md:47
msgid "Why doesn't `Drop::drop` take `self`?"
msgstr "¿Por qué `Drop::drop` no acepta `self`?"
-#: src/traits/drop.md:37
+#: src/traits/drop.md:48
msgid ""
"Short-answer: If it did, `std::mem::drop` would be called at the end of the "
"block, resulting in another call to `Drop::drop`, and a stack overflow!"
@@ -10731,7 +9529,7 @@ msgstr ""
"bloque, lo que daría como resultado otra llamada a `Drop::drop` y un "
"desbordamiento de la _stack_."
-#: src/traits/drop.md:40
+#: src/traits/drop.md:51
msgid "Try replacing `drop(a)` with `a.drop()`."
msgstr "Prueba a sustituir `drop(a)` por `a.drop()`."
@@ -10747,40 +9545,24 @@ msgstr ""
"El trait [`Default`](https://doc.rust-lang.org/std/default/trait.Default."
"html) produce un valor predeterminado para un tipo."
-#: src/traits/default.md:5
-msgid ""
-"```rust,editable\n"
-"#[derive(Debug, Default)]\n"
-"struct Derived {\n"
-" x: u32,\n"
-" y: String,\n"
-" z: Implemented,\n"
-"}\n"
-"\n"
-"#[derive(Debug)]\n"
-"struct Implemented(String);\n"
-"\n"
-"impl Default for Implemented {\n"
-" fn default() -> Self {\n"
-" Self(\"John Smith\".into())\n"
-" }\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let default_struct = Derived::default();\n"
-" println!(\"{default_struct:#?}\");\n"
-"\n"
-" let almost_default_struct = Derived {\n"
-" y: \"Y is set!\".into(),\n"
-" ..Derived::default()\n"
-" };\n"
-" println!(\"{almost_default_struct:#?}\");\n"
-"\n"
-" let nothing: Option = None;\n"
-" println!(\"{:#?}\", nothing.unwrap_or_default());\n"
-"}\n"
-"\n"
-"```"
+#: src/traits/default.md:18
+msgid "\"John Smith\""
+msgstr ""
+
+#: src/traits/default.md:24
+msgid "\"{default_struct:#?}\""
+msgstr ""
+
+#: src/traits/default.md:27
+msgid "\"Y is set!\""
+msgstr ""
+
+#: src/traits/default.md:30
+msgid "\"{almost_default_struct:#?}\""
+msgstr ""
+
+#: src/traits/default.md:33
+msgid "\"{:#?}\""
msgstr ""
#: src/traits/default.md:40
@@ -10849,26 +9631,8 @@ msgstr ""
"La sobrecarga de operadores se implementa mediante _traits_ en [`std::ops`]"
"(https://doc.rust-lang.org/std/ops/index.html):"
-#: src/traits/operators.md:5
-msgid ""
-"```rust,editable\n"
-"#[derive(Debug, Copy, Clone)]\n"
-"struct Point { x: i32, y: i32 }\n"
-"\n"
-"impl std::ops::Add for Point {\n"
-" type Output = Self;\n"
-"\n"
-" fn add(self, other: Self) -> Self {\n"
-" Self {x: self.x + other.x, y: self.y + other.y}\n"
-" }\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let p1 = Point { x: 10, y: 20 };\n"
-" let p2 = Point { x: 100, y: 200 };\n"
-" println!(\"{:?} + {:?} = {:?}\", p1, p2, p1 + p2);\n"
-"}\n"
-"```"
+#: src/traits/operators.md:20
+msgid "\"{:?} + {:?} = {:?}\""
msgstr ""
#: src/traits/operators.md:28
@@ -10930,31 +9694,22 @@ msgstr ""
"FnMut.html) y [`FnOnce`](https://doc.rust-lang.org/std/ops/trait.FnOnce."
"html):"
-#: src/traits/closures.md:8
-msgid ""
-"```rust,editable\n"
-"fn apply_with_log(func: impl FnOnce(i32) -> i32, input: i32) -> i32 {\n"
-" println!(\"Calling function on {input}\");\n"
-" func(input)\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let add_3 = |x| x + 3;\n"
-" println!(\"add_3: {}\", apply_with_log(add_3, 10));\n"
-" println!(\"add_3: {}\", apply_with_log(add_3, 20));\n"
-"\n"
-" let mut v = Vec::new();\n"
-" let mut accumulate = |x: i32| {\n"
-" v.push(x);\n"
-" v.iter().sum::()\n"
-" };\n"
-" println!(\"accumulate: {}\", apply_with_log(&mut accumulate, 4));\n"
-" println!(\"accumulate: {}\", apply_with_log(&mut accumulate, 5));\n"
-"\n"
-" let multiply_sum = |x| x * v.into_iter().sum::();\n"
-" println!(\"multiply_sum: {}\", apply_with_log(multiply_sum, 3));\n"
-"}\n"
-"```"
+#: src/traits/closures.md:10
+#, fuzzy
+#| msgid "Calling Unsafe Functions"
+msgid "\"Calling function on {input}\""
+msgstr "Llamar Funciones Unsafe (Inseguras)"
+
+#: src/traits/closures.md:16 src/traits/closures.md:17
+msgid "\"add_3: {}\""
+msgstr ""
+
+#: src/traits/closures.md:24 src/traits/closures.md:25
+msgid "\"accumulate: {}\""
+msgstr ""
+
+#: src/traits/closures.md:28
+msgid "\"multiply_sum: {}\""
msgstr ""
#: src/traits/closures.md:34
@@ -11010,18 +9765,12 @@ msgstr ""
"De forma predeterminada, los cierres capturan, si pueden, por referencia. La "
"palabra clave `move` hace que capturen por valor."
-#: src/traits/closures.md:52
-msgid ""
-"```rust,editable\n"
-"fn make_greeter(prefix: String) -> impl Fn(&str) {\n"
-" return move |name| println!(\"{} {}\", prefix, name)\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let hi = make_greeter(\"Hi\".to_string());\n"
-" hi(\"there\");\n"
-"}\n"
-"```"
+#: src/traits/closures.md:58
+msgid "\"Hi\""
+msgstr ""
+
+#: src/traits/closures.md:59
+msgid "\"there\""
msgstr ""
#: src/exercises/day-3/morning.md:1
@@ -11040,10 +9789,22 @@ msgstr ""
"También veremos la asignación de enumeraciones con un ejercicio que "
"involucra puntos y polígonos."
+#: src/exercises/day-3/simple-gui.md:1
+#: src/exercises/day-3/solutions-morning.md:3
+#, fuzzy
+#| msgid "A Simple GUI Library"
+msgid "Drawing A Simple GUI"
+msgstr "Una Biblioteca GUI sencilla"
+
#: src/exercises/day-3/simple-gui.md:3
+#, fuzzy
+#| msgid ""
+#| "Let us design a classical GUI library using our new knowledge of traits "
+#| "and trait objects."
msgid ""
"Let us design a classical GUI library using our new knowledge of traits and "
-"trait objects."
+"trait objects. We'll only implement the drawing of it (as text) for "
+"simplicity."
msgstr ""
"Vamos a diseñar una biblioteca GUI clásica con nuestro recién adquirido "
"conocimiento sobre _traits_ y objetos trait."
@@ -11058,21 +9819,20 @@ msgstr "`Window`: tiene un `title` y contiene otros widgets."
#: src/exercises/day-3/simple-gui.md:9
msgid ""
-"`Button`: has a `label` and a callback function which is invoked when the "
-"button is pressed."
+"`Button`: has a `label`. In reality, it would also take a callback function "
+"to allow the program to do something when the button is clicked but we won't "
+"include that since we're only drawing the GUI."
msgstr ""
-"`Button`: tiene una `label` y una función de retrollamada que se invoca "
-"cuando se pulsa el botón."
-#: src/exercises/day-3/simple-gui.md:11
+#: src/exercises/day-3/simple-gui.md:12
msgid "`Label`: has a `label`."
msgstr "`Label`: tiene una `label`."
-#: src/exercises/day-3/simple-gui.md:13
+#: src/exercises/day-3/simple-gui.md:14
msgid "The widgets will implement a `Widget` trait, see below."
msgstr "Los widgets implementarán un trait `Widget`, como se indica más abajo."
-#: src/exercises/day-3/simple-gui.md:15
+#: src/exercises/day-3/simple-gui.md:16
msgid ""
"Copy the code below to , fill in the missing "
"`draw_into` methods so that you implement the `Widget` trait:"
@@ -11081,140 +9841,46 @@ msgstr ""
"org/> y rellena los métodos `draw_into` que faltan para implementar el trait "
"`Widget`:"
-#: src/exercises/day-3/simple-gui.md:18
-msgid ""
-"```rust,should_panic\n"
-"// TODO: remove this when you're done with your implementation.\n"
-"#![allow(unused_imports, unused_variables, dead_code)]\n"
-"\n"
-"pub trait Widget {\n"
-" /// Natural width of `self`.\n"
-" fn width(&self) -> usize;\n"
-"\n"
-" /// Draw the widget into a buffer.\n"
-" fn draw_into(&self, buffer: &mut dyn std::fmt::Write);\n"
-"\n"
-" /// Draw the widget on standard output.\n"
-" fn draw(&self) {\n"
-" let mut buffer = String::new();\n"
-" self.draw_into(&mut buffer);\n"
-" println!(\"{buffer}\");\n"
-" }\n"
-"}\n"
-"\n"
-"pub struct Label {\n"
-" label: String,\n"
-"}\n"
-"\n"
-"impl Label {\n"
-" fn new(label: &str) -> Label {\n"
-" Label {\n"
-" label: label.to_owned(),\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"pub struct Button {\n"
-" label: Label,\n"
-" callback: Box,\n"
-"}\n"
-"\n"
-"impl Button {\n"
-" fn new(label: &str, callback: Box) -> Button {\n"
-" Button {\n"
-" label: Label::new(label),\n"
-" callback,\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"pub struct Window {\n"
-" title: String,\n"
-" widgets: Vec>,\n"
-"}\n"
-"\n"
-"impl Window {\n"
-" fn new(title: &str) -> Window {\n"
-" Window {\n"
-" title: title.to_owned(),\n"
-" widgets: Vec::new(),\n"
-" }\n"
-" }\n"
-"\n"
-" fn add_widget(&mut self, widget: Box) {\n"
-" self.widgets.push(widget);\n"
-" }\n"
-"\n"
-" fn inner_width(&self) -> usize {\n"
-" std::cmp::max(\n"
-" self.title.chars().count(),\n"
-" self.widgets.iter().map(|w| w.width()).max().unwrap_or(0),\n"
-" )\n"
-" }\n"
-"}\n"
-"\n"
-"\n"
-"impl Widget for Label {\n"
-" fn width(&self) -> usize {\n"
-" unimplemented!()\n"
-" }\n"
-"\n"
-" fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n"
-" unimplemented!()\n"
-" }\n"
-"}\n"
-"\n"
-"impl Widget for Button {\n"
-" fn width(&self) -> usize {\n"
-" unimplemented!()\n"
-" }\n"
-"\n"
-" fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n"
-" unimplemented!()\n"
-" }\n"
-"}\n"
-"\n"
-"impl Widget for Window {\n"
-" fn width(&self) -> usize {\n"
-" unimplemented!()\n"
-" }\n"
-"\n"
-" fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n"
-" unimplemented!()\n"
-" }\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let mut window = Window::new(\"Rust GUI Demo 1.23\");\n"
-" window.add_widget(Box::new(Label::new(\"This is a small text GUI demo."
-"\")));\n"
-" window.add_widget(Box::new(Button::new(\n"
-" \"Click me!\",\n"
-" Box::new(|| println!(\"You clicked the button!\")),\n"
-" )));\n"
-" window.draw();\n"
-"}\n"
-"```"
+#: src/exercises/day-3/simple-gui.md:24
+#: src/exercises/day-3/solutions-morning.md:9
+msgid "/// Natural width of `self`.\n"
msgstr ""
-#: src/exercises/day-3/simple-gui.md:130
-msgid "The output of the above program can be something simple like this:"
-msgstr "La salida del programa anterior puede ser algo sencillo como esto:"
+#: src/exercises/day-3/simple-gui.md:27
+#: src/exercises/day-3/solutions-morning.md:12
+msgid "/// Draw the widget into a buffer.\n"
+msgstr ""
-#: src/exercises/day-3/simple-gui.md:132
-msgid ""
-"```text\n"
-"========\n"
-"Rust GUI Demo 1.23\n"
-"========\n"
-"\n"
-"This is a small text GUI demo.\n"
-"\n"
-"| Click me! |\n"
-"```"
+#: src/exercises/day-3/simple-gui.md:30
+#: src/exercises/day-3/solutions-morning.md:15
+msgid "/// Draw the widget on standard output.\n"
+msgstr ""
+
+#: src/exercises/day-3/simple-gui.md:34
+#: src/exercises/day-3/solutions-morning.md:19
+msgid "\"{buffer}\""
+msgstr ""
+
+#: src/exercises/day-3/simple-gui.md:119
+#: src/exercises/day-3/solutions-morning.md:133
+msgid "\"Rust GUI Demo 1.23\""
+msgstr ""
+
+#: src/exercises/day-3/simple-gui.md:120
+#: src/exercises/day-3/solutions-morning.md:134
+msgid "\"This is a small text GUI demo.\""
+msgstr ""
+
+#: src/exercises/day-3/simple-gui.md:122
+#: src/exercises/day-3/solutions-morning.md:136
+msgid "\"Click me!\""
msgstr ""
-#: src/exercises/day-3/simple-gui.md:142
+#: src/exercises/day-3/simple-gui.md:128
+msgid "The output of the above program can be something simple like this:"
+msgstr "La salida del programa anterior puede ser algo sencillo como esto:"
+
+#: src/exercises/day-3/simple-gui.md:140
msgid ""
"If you want to draw aligned text, you can use the [fill/alignment](https://"
"doc.rust-lang.org/std/fmt/index.html#fillalignment) formatting operators. In "
@@ -11226,39 +9892,25 @@ msgstr ""
"html#fillalignment). En concreto, observa cómo puedes rellenar con distintos "
"caracteres (en este caso, `'/'`) y cómo puedes controlar la alineación:"
-#: src/exercises/day-3/simple-gui.md:147
-msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let width = 10;\n"
-" println!(\"left aligned: |{:/ width$}|\", \"foo\");\n"
-"}\n"
-"```"
+#: src/exercises/day-3/simple-gui.md:148
+msgid "\"left aligned: |{:/ width$}|\""
msgstr ""
-#: src/exercises/day-3/simple-gui.md:156
+#: src/exercises/day-3/simple-gui.md:154
msgid ""
"Using such alignment tricks, you can for example produce output like this:"
msgstr ""
"Con estos trucos de alineación puedes, por ejemplo, obtener resultados como "
"el siguiente:"
-#: src/exercises/day-3/simple-gui.md:158
-msgid ""
-"```text\n"
-"+--------------------------------+\n"
-"| Rust GUI Demo 1.23 |\n"
-"+================================+\n"
-"| This is a small text GUI demo. |\n"
-"| +-----------+ |\n"
-"| | Click me! | |\n"
-"| +-----------+ |\n"
-"+--------------------------------+\n"
-"```"
-msgstr ""
-
#: src/exercises/day-3/points-polygons.md:1
msgid "Polygon Struct"
msgstr "Estructura de polígono"
@@ -11273,117 +9925,20 @@ msgstr ""
"siguiente fragmento de código en la página y "
"rellena los métodos que faltan para pasar las pruebas:"
-#: src/exercises/day-3/points-polygons.md:7
-msgid ""
-"```rust\n"
-"// TODO: remove this when you're done with your implementation.\n"
-"#![allow(unused_variables, dead_code)]\n"
-"\n"
-"pub struct Point {\n"
-" // add fields\n"
-"}\n"
-"\n"
-"impl Point {\n"
-" // add methods\n"
-"}\n"
-"\n"
-"pub struct Polygon {\n"
-" // add fields\n"
-"}\n"
-"\n"
-"impl Polygon {\n"
-" // add methods\n"
-"}\n"
-"\n"
-"pub struct Circle {\n"
-" // add fields\n"
-"}\n"
-"\n"
-"impl Circle {\n"
-" // add methods\n"
-"}\n"
-"\n"
-"pub enum Shape {\n"
-" Polygon(Polygon),\n"
-" Circle(Circle),\n"
-"}\n"
-"\n"
-"#[cfg(test)]\n"
-"mod tests {\n"
-" use super::*;\n"
-"\n"
-" fn round_two_digits(x: f64) -> f64 {\n"
-" (x * 100.0).round() / 100.0\n"
-" }\n"
-"\n"
-" #[test]\n"
-" fn test_point_magnitude() {\n"
-" let p1 = Point::new(12, 13);\n"
-" assert_eq!(round_two_digits(p1.magnitude()), 17.69);\n"
-" }\n"
-"\n"
-" #[test]\n"
-" fn test_point_dist() {\n"
-" let p1 = Point::new(10, 10);\n"
-" let p2 = Point::new(14, 13);\n"
-" assert_eq!(round_two_digits(p1.dist(p2)), 5.00);\n"
-" }\n"
-"\n"
-" #[test]\n"
-" fn test_point_add() {\n"
-" let p1 = Point::new(16, 16);\n"
-" let p2 = p1 + Point::new(-4, 3);\n"
-" assert_eq!(p2, Point::new(12, 19));\n"
-" }\n"
-"\n"
-" #[test]\n"
-" fn test_polygon_left_most_point() {\n"
-" let p1 = Point::new(12, 13);\n"
-" let p2 = Point::new(16, 16);\n"
-"\n"
-" let mut poly = Polygon::new();\n"
-" poly.add_point(p1);\n"
-" poly.add_point(p2);\n"
-" assert_eq!(poly.left_most_point(), Some(p1));\n"
-" }\n"
-"\n"
-" #[test]\n"
-" fn test_polygon_iter() {\n"
-" let p1 = Point::new(12, 13);\n"
-" let p2 = Point::new(16, 16);\n"
-"\n"
-" let mut poly = Polygon::new();\n"
-" poly.add_point(p1);\n"
-" poly.add_point(p2);\n"
-"\n"
-" let points = poly.iter().cloned().collect::>();\n"
-" assert_eq!(points, vec![Point::new(12, 13), Point::new(16, 16)]);\n"
-" }\n"
-"\n"
-" #[test]\n"
-" fn test_shape_perimeters() {\n"
-" let mut poly = Polygon::new();\n"
-" poly.add_point(Point::new(12, 13));\n"
-" poly.add_point(Point::new(17, 11));\n"
-" poly.add_point(Point::new(16, 16));\n"
-" let shapes = vec![\n"
-" Shape::from(poly),\n"
-" Shape::from(Circle::new(Point::new(10, 20), 5)),\n"
-" ];\n"
-" let perimeters = shapes\n"
-" .iter()\n"
-" .map(Shape::perimeter)\n"
-" .map(round_two_digits)\n"
-" .collect::>();\n"
-" assert_eq!(perimeters, vec![15.48, 31.42]);\n"
-" }\n"
-"}\n"
-"\n"
-"#[allow(dead_code)]\n"
-"fn main() {}\n"
-"```"
+#: src/exercises/day-3/points-polygons.md:12
+#: src/exercises/day-3/points-polygons.md:20
+#: src/exercises/day-3/points-polygons.md:28
+msgid "// add fields\n"
msgstr ""
+#: src/exercises/day-3/points-polygons.md:16
+#: src/exercises/day-3/points-polygons.md:24
+#: src/exercises/day-3/points-polygons.md:32
+#, fuzzy
+#| msgid "Structs and methods."
+msgid "// add methods\n"
+msgstr "Estructuras (_Structs_) y métodos."
+
#: src/exercises/day-3/points-polygons.md:117
msgid ""
"Since the method signatures are missing from the problem statements, the key "
@@ -11435,14 +9990,8 @@ msgstr "No hay excepciones."
msgid "Rust will trigger a panic if a fatal error happens at runtime:"
msgstr "Rust activará un _panic_ si se produce un error grave en _runtime_:"
-#: src/error-handling/panics.md:5
-msgid ""
-"```rust,editable,should_panic\n"
-"fn main() {\n"
-" let v = vec![10, 20, 30];\n"
-" println!(\"v[100]: {}\", v[100]);\n"
-"}\n"
-"```"
+#: src/error-handling/panics.md:8
+msgid "\"v[100]: {}\""
msgstr ""
#: src/error-handling/panics.md:12
@@ -11472,23 +10021,16 @@ msgstr ""
"De forma predeterminada, el _panic_ hará que la _stack_ se desenrolle. El "
"proceso de desenrrollado se puede detectar:"
-#: src/error-handling/panic-unwind.md:5
-msgid ""
-"```rust,editable\n"
-"use std::panic;\n"
-"\n"
-"fn main() {\n"
-" let result = panic::catch_unwind(|| {\n"
-" println!(\"hello!\");\n"
-" });\n"
-" assert!(result.is_ok());\n"
-" \n"
-" let result = panic::catch_unwind(|| {\n"
-" panic!(\"oh no!\");\n"
-" });\n"
-" assert!(result.is_err());\n"
-"}\n"
-"```"
+#: src/error-handling/panic-unwind.md:10
+msgid "\"No problem here!\""
+msgstr ""
+
+#: src/error-handling/panic-unwind.md:12 src/error-handling/panic-unwind.md:17
+msgid "\"{result:?}\""
+msgstr ""
+
+#: src/error-handling/panic-unwind.md:15
+msgid "\"oh no!\""
msgstr ""
#: src/error-handling/panic-unwind.md:21
@@ -11515,26 +10057,16 @@ msgstr ""
"Ya hemos visto la _enum_ `Result`. Se utiliza normalmente cuando se esperan "
"errores como parte del funcionamiento normal:"
-#: src/error-handling/result.md:6
-msgid ""
-"```rust,editable\n"
-"use std::fs;\n"
-"use std::io::Read;\n"
-"\n"
-"fn main() {\n"
-" let file = fs::File::open(\"diary.txt\");\n"
-" match file {\n"
-" Ok(mut file) => {\n"
-" let mut contents = String::new();\n"
-" file.read_to_string(&mut contents);\n"
-" println!(\"Dear diary: {contents}\");\n"
-" },\n"
-" Err(err) => {\n"
-" println!(\"The diary could not be opened: {err}\");\n"
-" }\n"
-" }\n"
-"}\n"
-"```"
+#: src/error-handling/result.md:11
+msgid "\"diary.txt\""
+msgstr ""
+
+#: src/error-handling/result.md:16
+msgid "\"Dear diary: {contents}\""
+msgstr ""
+
+#: src/error-handling/result.md:19
+msgid "\"The diary could not be opened: {err}\""
msgstr ""
#: src/error-handling/result.md:27
@@ -11572,57 +10104,29 @@ msgstr ""
"El operador try `?` se utiliza para devolver errores al llamador. Te permite "
"convertir"
-#: src/error-handling/try-operator.md:6
-msgid ""
-"```rust,ignore\n"
-"match some_expression {\n"
-" Ok(value) => value,\n"
-" Err(err) => return Err(err),\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/error-handling/try-operator.md:13
msgid "into the much simpler"
msgstr "en algo mucho más sencillo:"
-#: src/error-handling/try-operator.md:15
-msgid ""
-"```rust,ignore\n"
-"some_expression?\n"
-"```"
-msgstr ""
-
#: src/error-handling/try-operator.md:19
msgid "We can use this to simplify our error handling code:"
msgstr "Podemos utilizarlo para simplificar el código de gestión de errores:"
-#: src/error-handling/try-operator.md:21
-msgid ""
-"```rust,editable\n"
-"use std::{fs, io};\n"
-"use std::io::Read;\n"
-"\n"
-"fn read_username(path: &str) -> Result {\n"
-" let username_file_result = fs::File::open(path);\n"
-" let mut username_file = match username_file_result {\n"
-" Ok(file) => file,\n"
-" Err(err) => return Err(err),\n"
-" };\n"
-"\n"
-" let mut username = String::new();\n"
-" match username_file.read_to_string(&mut username) {\n"
-" Ok(_) => Ok(username),\n"
-" Err(err) => Err(err),\n"
-" }\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" //fs::write(\"config.dat\", \"alice\").unwrap();\n"
-" let username = read_username(\"config.dat\");\n"
-" println!(\"username or error: {username:?}\");\n"
-"}\n"
-"```"
+#: src/error-handling/try-operator.md:40
+msgid "//fs::write(\"config.dat\", \"alice\").unwrap();\n"
+msgstr ""
+
+#: src/error-handling/try-operator.md:41
+#: src/error-handling/converting-error-types-example.md:43
+#: src/error-handling/deriving-error-enums.md:30
+#: src/error-handling/dynamic-errors.md:27
+#: src/error-handling/error-contexts.md:26
+msgid "\"config.dat\""
+msgstr ""
+
+#: src/error-handling/try-operator.md:42
+#: src/error-handling/converting-error-types-example.md:44
+msgid "\"username or error: {username:?}\""
msgstr ""
#: src/error-handling/try-operator.md:50
@@ -11675,27 +10179,10 @@ msgstr ""
"La expansión efectiva de `?` es un poco más complicada de lo que se ha "
"indicado anteriormente:"
-#: src/error-handling/converting-error-types.md:5
-msgid ""
-"```rust,ignore\n"
-"expression?\n"
-"```"
-msgstr ""
-
#: src/error-handling/converting-error-types.md:9
msgid "works the same as"
msgstr "funciona igual que"
-#: src/error-handling/converting-error-types.md:11
-msgid ""
-"```rust,ignore\n"
-"match expression {\n"
-" Ok(value) => value,\n"
-" Err(err) => return Err(From::from(err)),\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/error-handling/converting-error-types.md:18
msgid ""
"The `From::from` call here means we attempt to convert the error type to the "
@@ -11704,53 +10191,19 @@ msgstr ""
"Aquí la llamada a `From::from` significa que intentamos convertir el tipo de "
"error al tipo que devuelve la función:"
-#: src/error-handling/converting-error-types-example.md:3
-msgid ""
-"```rust,editable\n"
-"use std::error::Error;\n"
-"use std::fmt::{self, Display, Formatter};\n"
-"use std::fs::{self, File};\n"
-"use std::io::{self, Read};\n"
-"\n"
-"#[derive(Debug)]\n"
-"enum ReadUsernameError {\n"
-" IoError(io::Error),\n"
-" EmptyUsername(String),\n"
-"}\n"
-"\n"
-"impl Error for ReadUsernameError {}\n"
-"\n"
-"impl Display for ReadUsernameError {\n"
-" fn fmt(&self, f: &mut Formatter) -> fmt::Result {\n"
-" match self {\n"
-" Self::IoError(e) => write!(f, \"IO error: {e}\"),\n"
-" Self::EmptyUsername(filename) => write!(f, \"Found no username "
-"in {filename}\"),\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"impl From for ReadUsernameError {\n"
-" fn from(err: io::Error) -> ReadUsernameError {\n"
-" ReadUsernameError::IoError(err)\n"
-" }\n"
-"}\n"
-"\n"
-"fn read_username(path: &str) -> Result {\n"
-" let mut username = String::with_capacity(100);\n"
-" File::open(path)?.read_to_string(&mut username)?;\n"
-" if username.is_empty() {\n"
-" return Err(ReadUsernameError::EmptyUsername(String::from(path)));\n"
-" }\n"
-" Ok(username)\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" //fs::write(\"config.dat\", \"\").unwrap();\n"
-" let username = read_username(\"config.dat\");\n"
-" println!(\"username or error: {username:?}\");\n"
-"}\n"
-"```"
+#: src/error-handling/converting-error-types-example.md:20
+msgid "\"IO error: {e}\""
+msgstr ""
+
+#: src/error-handling/converting-error-types-example.md:21
+msgid "\"Found no username in {filename}\""
+msgstr ""
+
+#: src/error-handling/converting-error-types-example.md:42
+#: src/error-handling/deriving-error-enums.md:29
+#: src/error-handling/dynamic-errors.md:26
+#: src/error-handling/error-contexts.md:25
+msgid "//fs::write(\"config.dat\", \"\").unwrap();\n"
msgstr ""
#: src/error-handling/converting-error-types-example.md:55
@@ -11786,38 +10239,24 @@ msgstr ""
"errores es el crate [thiserror](https://docs.rs/thiserror/), como hicimos en "
"la página anterior:"
-#: src/error-handling/deriving-error-enums.md:6
-msgid ""
-"```rust,editable,compile_fail\n"
-"use std::{fs, io};\n"
-"use std::io::Read;\n"
-"use thiserror::Error;\n"
-"\n"
-"#[derive(Debug, Error)]\n"
-"enum ReadUsernameError {\n"
-" #[error(\"Could not read: {0}\")]\n"
-" IoError(#[from] io::Error),\n"
-" #[error(\"Found no username in {0}\")]\n"
-" EmptyUsername(String),\n"
-"}\n"
-"\n"
-"fn read_username(path: &str) -> Result {\n"
-" let mut username = String::new();\n"
-" fs::File::open(path)?.read_to_string(&mut username)?;\n"
-" if username.is_empty() {\n"
-" return Err(ReadUsernameError::EmptyUsername(String::from(path)));\n"
-" }\n"
-" Ok(username)\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" //fs::write(\"config.dat\", \"\").unwrap();\n"
-" match read_username(\"config.dat\") {\n"
-" Ok(username) => println!(\"Username: {username}\"),\n"
-" Err(err) => println!(\"Error: {err}\"),\n"
-" }\n"
-"}\n"
-"```"
+#: src/error-handling/deriving-error-enums.md:13
+msgid "\"Could not read: {0}\""
+msgstr ""
+
+#: src/error-handling/deriving-error-enums.md:15
+#: src/error-handling/dynamic-errors.md:13
+msgid "\"Found no username in {0}\""
+msgstr ""
+
+#: src/error-handling/deriving-error-enums.md:31
+#: src/error-handling/dynamic-errors.md:28
+#: src/error-handling/error-contexts.md:27
+msgid "\"Username: {username}\""
+msgstr ""
+
+#: src/error-handling/deriving-error-enums.md:32
+#: src/error-handling/dynamic-errors.md:29
+msgid "\"Error: {err}\""
msgstr ""
#: src/error-handling/deriving-error-enums.md:39
@@ -11846,37 +10285,6 @@ msgstr ""
"escribir nuestra propia _enum_ que cubra todas las posibilidades. `std::"
"error::Error` facilita este proceso."
-#: src/error-handling/dynamic-errors.md:6
-msgid ""
-"```rust,editable,compile_fail\n"
-"use std::fs;\n"
-"use std::io::Read;\n"
-"use thiserror::Error;\n"
-"use std::error::Error;\n"
-"\n"
-"#[derive(Clone, Debug, Eq, Error, PartialEq)]\n"
-"#[error(\"Found no username in {0}\")]\n"
-"struct EmptyUsernameError(String);\n"
-"\n"
-"fn read_username(path: &str) -> Result> {\n"
-" let mut username = String::new();\n"
-" fs::File::open(path)?.read_to_string(&mut username)?;\n"
-" if username.is_empty() {\n"
-" return Err(EmptyUsernameError(String::from(path)).into());\n"
-" }\n"
-" Ok(username)\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" //fs::write(\"config.dat\", \"\").unwrap();\n"
-" match read_username(\"config.dat\") {\n"
-" Ok(username) => println!(\"Username: {username}\"),\n"
-" Err(err) => println!(\"Error: {err}\"),\n"
-" }\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/error-handling/dynamic-errors.md:36
msgid ""
"This saves on code, but gives up the ability to cleanly handle different "
@@ -11901,33 +10309,20 @@ msgstr ""
"puede ayudar a añadir información contextual a los errores y permite tener "
"menos tipos de errores personalizados:"
-#: src/error-handling/error-contexts.md:7
-msgid ""
-"```rust,editable,compile_fail\n"
-"use std::{fs, io};\n"
-"use std::io::Read;\n"
-"use anyhow::{Context, Result, bail};\n"
-"\n"
-"fn read_username(path: &str) -> Result {\n"
-" let mut username = String::with_capacity(100);\n"
-" fs::File::open(path)\n"
-" .with_context(|| format!(\"Failed to open {path}\"))?\n"
-" .read_to_string(&mut username)\n"
-" .context(\"Failed to read\")?;\n"
-" if username.is_empty() {\n"
-" bail!(\"Found no username in {path}\");\n"
-" }\n"
-" Ok(username)\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" //fs::write(\"config.dat\", \"\").unwrap();\n"
-" match read_username(\"config.dat\") {\n"
-" Ok(username) => println!(\"Username: {username}\"),\n"
-" Err(err) => println!(\"Error: {err:?}\"),\n"
-" }\n"
-"}\n"
-"```"
+#: src/error-handling/error-contexts.md:15
+msgid "\"Failed to open {path}\""
+msgstr ""
+
+#: src/error-handling/error-contexts.md:17
+msgid "\"Failed to read\""
+msgstr ""
+
+#: src/error-handling/error-contexts.md:19
+msgid "\"Found no username in {path}\""
+msgstr ""
+
+#: src/error-handling/error-contexts.md:28
+msgid "\"Error: {err:?}\""
msgstr ""
#: src/error-handling/error-contexts.md:35
@@ -11979,32 +10374,11 @@ msgstr ""
msgid "Mark unit tests with `#[test]`:"
msgstr "Marca pruebas unitarias con `#[test]`:"
-#: src/testing/unit-tests.md:5
-msgid ""
-"```rust,editable,ignore\n"
-"fn first_word(text: &str) -> &str {\n"
-" match text.find(' ') {\n"
-" Some(idx) => &text[..idx],\n"
-" None => &text,\n"
-" }\n"
-"}\n"
-"\n"
-"#[test]\n"
-"fn test_empty() {\n"
-" assert_eq!(first_word(\"\"), \"\");\n"
-"}\n"
-"\n"
-"#[test]\n"
-"fn test_single_word() {\n"
-" assert_eq!(first_word(\"Hello\"), \"Hello\");\n"
-"}\n"
-"\n"
-"#[test]\n"
-"fn test_multiple_words() {\n"
-" assert_eq!(first_word(\"Hello World\"), \"Hello\");\n"
-"}\n"
-"```"
-msgstr ""
+#: src/testing/unit-tests.md:25
+#, fuzzy
+#| msgid "Hello World!"
+msgid "\"Hello World\""
+msgstr "¡Hola, mundo!"
#: src/testing/unit-tests.md:29
msgid "Use `cargo test` to find and run the unit tests."
@@ -12018,27 +10392,12 @@ msgstr ""
"Las pruebas unitarias se suelen incluir en un módulo anidado (ejecuta las "
"pruebas en el [_Playground_](https://play.rust-lang.org/)):"
-#: src/testing/test-modules.md:6
-msgid ""
-"```rust,editable\n"
-"fn helper(a: &str, b: &str) -> String {\n"
-" format!(\"{a} {b}\")\n"
-"}\n"
-"\n"
-"pub fn main() {\n"
-" println!(\"{}\", helper(\"Hello\", \"World\"));\n"
-"}\n"
-"\n"
-"#[cfg(test)]\n"
-"mod tests {\n"
-" use super::*;\n"
-"\n"
-" #[test]\n"
-" fn test_helper() {\n"
-" assert_eq!(helper(\"foo\", \"bar\"), \"foo bar\");\n"
-" }\n"
-"}\n"
-"```"
+#: src/testing/test-modules.md:8
+msgid "\"{a} {b}\""
+msgstr ""
+
+#: src/testing/test-modules.md:21
+msgid "\"foo bar\""
msgstr ""
#: src/testing/test-modules.md:26
@@ -12054,20 +10413,15 @@ msgstr ""
msgid "Rust has built-in support for documentation tests:"
msgstr "Rust cuenta con asistencia integrada para pruebas de documentación:"
-#: src/testing/doc-tests.md:5
+#: src/testing/doc-tests.md:6
msgid ""
-"```rust\n"
"/// Shortens a string to the given length.\n"
"///\n"
"/// ```\n"
-"/// use playground::shorten_string;\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"
-"pub fn shorten_string(s: &str, length: usize) -> &str {\n"
-" &s[..std::cmp::min(length, s.len())]\n"
-"}\n"
-"```"
msgstr ""
#: src/testing/doc-tests.md:18
@@ -12082,6 +10436,12 @@ msgstr "El código se compilará y ejecutará como parte de `cargo test`."
#: src/testing/doc-tests.md:20
msgid ""
+"Adding `# ` in the code will hide it from the docs, but will still compile/"
+"run it."
+msgstr ""
+
+#: src/testing/doc-tests.md:21
+msgid ""
"Test the above code on the [Rust Playground](https://play.rust-lang.org/?"
"version=stable&mode=debug&edition=2021&gist=3ce2ad13ea1302f6572cb15cd96becf0)."
msgstr ""
@@ -12098,18 +10458,6 @@ msgstr ""
msgid "Create a `.rs` file under `tests/`:"
msgstr "Crea un archivo `.rs` en `tests/`:"
-#: src/testing/integration-tests.md:7
-msgid ""
-"```rust,ignore\n"
-"use my_library::init;\n"
-"\n"
-"#[test]\n"
-"fn test_init() {\n"
-" assert!(init().is_ok());\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/testing/integration-tests.md:16
msgid "These tests only have access to the public API of your crate."
msgstr "Estas pruebas solo tienen acceso a la API pública de tu crate."
@@ -12238,28 +10586,22 @@ msgstr ""
"La creación de punteros es un proceso seguro, pero para anular las "
"referencias, es necesario utilizar `unsafe`:"
-#: src/unsafe/raw-pointers.md:5
+#: src/unsafe/raw-pointers.md:12
msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let mut num = 5;\n"
-"\n"
-" let r1 = &mut num as *mut i32;\n"
-" let r2 = r1 as *const i32;\n"
-"\n"
-" // Safe because r1 and r2 were obtained from references and so are\n"
+"// Safe because r1 and r2 were obtained from references and so are\n"
" // guaranteed to be non-null and properly aligned, the objects "
"underlying\n"
" // the references from which they were obtained are live throughout the\n"
" // whole unsafe block, and they are not accessed either through the\n"
" // references or concurrently through any other pointers.\n"
-" unsafe {\n"
-" println!(\"r1 is: {}\", *r1);\n"
-" *r1 = 10;\n"
-" println!(\"r2 is: {}\", *r2);\n"
-" }\n"
-"}\n"
-"```"
+msgstr ""
+
+#: src/unsafe/raw-pointers.md:18
+msgid "\"r1 is: {}\""
+msgstr ""
+
+#: src/unsafe/raw-pointers.md:20
+msgid "\"r2 is: {}\""
msgstr ""
#: src/unsafe/raw-pointers.md:27
@@ -12321,15 +10663,14 @@ msgstr ""
msgid "It is safe to read an immutable static variable:"
msgstr "Es seguro leer una variable estática inmutable:"
-#: src/unsafe/mutable-static-variables.md:5
-msgid ""
-"```rust,editable\n"
-"static HELLO_WORLD: &str = \"Hello, world!\";\n"
-"\n"
-"fn main() {\n"
-" println!(\"HELLO_WORLD: {HELLO_WORLD}\");\n"
-"}\n"
-"```"
+#: src/unsafe/mutable-static-variables.md:6
+#, fuzzy
+#| msgid "Hello World!"
+msgid "\"Hello, world!\""
+msgstr "¡Hola, mundo!"
+
+#: src/unsafe/mutable-static-variables.md:9
+msgid "\"HELLO_WORLD: {HELLO_WORLD}\""
msgstr ""
#: src/unsafe/mutable-static-variables.md:13
@@ -12340,25 +10681,25 @@ msgstr ""
"Sin embargo, dado que pueden producirse carreras de datos, no es seguro leer "
"y escribir variables estáticas mutables:"
-#: src/unsafe/mutable-static-variables.md:16
-msgid ""
-"```rust,editable\n"
-"static mut COUNTER: u32 = 0;\n"
-"\n"
-"fn add_to_counter(inc: u32) {\n"
-" unsafe { COUNTER += inc; } // Potential data race!\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" add_to_counter(42);\n"
-"\n"
-" unsafe { println!(\"COUNTER: {COUNTER}\"); } // Potential data race!\n"
-"}\n"
-"```"
+#: src/unsafe/mutable-static-variables.md:20
+#: src/unsafe/mutable-static-variables.md:26
+msgid "// Potential data race!\n"
+msgstr ""
+
+#: src/unsafe/mutable-static-variables.md:26
+msgid "\"COUNTER: {COUNTER}\""
msgstr ""
#: src/unsafe/mutable-static-variables.md:32
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."
+msgstr ""
+
+#: src/unsafe/mutable-static-variables.md:36
+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."
@@ -12373,23 +10714,20 @@ msgstr ""
"Las uniones son como _enums_ (enumeraciones), pero eres tú quien debe hacer "
"el seguimiento del campo activo:"
-#: src/unsafe/unions.md:5
-msgid ""
-"```rust,editable\n"
-"#[repr(C)]\n"
-"union MyUnion {\n"
-" i: u8,\n"
-" b: bool,\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let u = MyUnion { i: 42 };\n"
-" println!(\"int: {}\", unsafe { u.i });\n"
-" println!(\"bool: {}\", unsafe { u.b }); // Undefined behavior!\n"
-"}\n"
-"```"
+#: src/unsafe/unions.md:14
+msgid "\"int: {}\""
+msgstr ""
+
+#: src/unsafe/unions.md:15
+msgid "\"bool: {}\""
msgstr ""
+#: src/unsafe/unions.md:15
+#, fuzzy
+#| msgid "No undefined behavior at runtime:"
+msgid "// Undefined behavior!\n"
+msgstr "No hay comportamientos indefinidos en _runtime_:"
+
#: src/unsafe/unions.md:21
msgid ""
"Unions are very rarely needed in Rust as you can usually use an enum. They "
@@ -12419,34 +10757,32 @@ msgstr ""
"previas adicionales que debes mantener para evitar un comportamiento "
"indefinido:"
-#: src/unsafe/calling-unsafe-functions.md:6
+#: src/unsafe/calling-unsafe-functions.md:8
+msgid "\"🗻∈🌏\""
+msgstr ""
+
+#: src/unsafe/calling-unsafe-functions.md:10
msgid ""
-"```rust,editable\n"
-"fn main() {\n"
-" let emojis = \"🗻∈🌏\";\n"
-"\n"
-" // Safe because the indices are in the correct order, within the bounds "
-"of\n"
+"// Safe because the indices are in the correct order, within the bounds of\n"
" // the string slice, and lie on UTF-8 sequence boundaries.\n"
-" unsafe {\n"
-" println!(\"emoji: {}\", emojis.get_unchecked(0..4));\n"
-" println!(\"emoji: {}\", emojis.get_unchecked(4..7));\n"
-" println!(\"emoji: {}\", emojis.get_unchecked(7..11));\n"
-" }\n"
-"\n"
-" println!(\"char count: {}\", count_chars(unsafe { emojis."
-"get_unchecked(0..7) }));\n"
-"\n"
-" // Not upholding the UTF-8 encoding requirement breaks memory safety!\n"
+msgstr ""
+
+#: src/unsafe/calling-unsafe-functions.md:13
+#: src/unsafe/calling-unsafe-functions.md:14
+#: src/unsafe/calling-unsafe-functions.md:15
+msgid "\"emoji: {}\""
+msgstr ""
+
+#: src/unsafe/calling-unsafe-functions.md:18
+msgid "\"char count: {}\""
+msgstr ""
+
+#: src/unsafe/calling-unsafe-functions.md:20
+msgid ""
+"// Not upholding the UTF-8 encoding requirement breaks memory safety!\n"
" // println!(\"emoji: {}\", unsafe { emojis.get_unchecked(0..3) });\n"
" // println!(\"char count: {}\", count_chars(unsafe { emojis."
"get_unchecked(0..3) }));\n"
-"}\n"
-"\n"
-"fn count_chars(s: &str) -> usize {\n"
-" s.chars().map(|_| 1).sum()\n"
-"}\n"
-"```"
msgstr ""
#: src/unsafe/writing-unsafe-functions.md:3
@@ -12457,32 +10793,21 @@ msgstr ""
"Puedes marcar tus propias funciones como `unsafe` si requieren condiciones "
"concretas para evitar un comportamiento indefinido."
-#: src/unsafe/writing-unsafe-functions.md:6
+#: src/unsafe/writing-unsafe-functions.md:7
msgid ""
-"```rust,editable\n"
"/// Swaps the values pointed to by the given pointers.\n"
"///\n"
"/// # Safety\n"
"///\n"
"/// The pointers must be valid and properly aligned.\n"
-"unsafe fn swap(a: *mut u8, b: *mut u8) {\n"
-" let temp = *a;\n"
-" *a = *b;\n"
-" *b = temp;\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let mut a = 42;\n"
-" let mut b = 66;\n"
-"\n"
-" // Safe because ...\n"
-" unsafe {\n"
-" swap(&mut a, &mut b);\n"
-" }\n"
-"\n"
-" println!(\"a = {}, b = {}\", a, b);\n"
-"}\n"
-"```"
+msgstr ""
+
+#: src/unsafe/writing-unsafe-functions.md:22
+msgid "// Safe because ...\n"
+msgstr ""
+
+#: src/unsafe/writing-unsafe-functions.md:27
+msgid "\"a = {}, b = {}\""
msgstr ""
#: src/unsafe/writing-unsafe-functions.md:33
@@ -12515,20 +10840,30 @@ msgstr ""
"Es posible que las funciones de otros lenguajes infrinjan las garantías de "
"Rust. Por lo tanto, no es seguro llamarlas:"
-#: src/unsafe/extern-functions.md:6
-msgid ""
-"```rust,editable\n"
-"extern \"C\" {\n"
-" fn abs(input: i32) -> i32;\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" unsafe {\n"
-" // Undefined behavior if abs misbehaves.\n"
-" println!(\"Absolute value of -3 according to C: {}\", abs(-3));\n"
-" }\n"
-"}\n"
-"```"
+#: src/unsafe/extern-functions.md:7 src/exercises/day-3/safe-ffi-wrapper.md:89
+#: src/android/interoperability/with-c.md:9
+#: src/android/interoperability/with-c/rust.md:15
+#: src/android/interoperability/with-c/rust.md:30
+#: src/bare-metal/aps/inline-assembly.md:18
+#: src/bare-metal/aps/better-uart/using.md:24
+#: src/bare-metal/aps/logging/using.md:23 src/exercises/bare-metal/rtc.md:46
+#: src/exercises/bare-metal/rtc.md:100 src/exercises/bare-metal/rtc.md:106
+#: src/exercises/bare-metal/rtc.md:113 src/exercises/bare-metal/rtc.md:119
+#: src/exercises/bare-metal/rtc.md:125 src/exercises/bare-metal/rtc.md:131
+#: src/exercises/bare-metal/rtc.md:137 src/exercises/bare-metal/rtc.md:143
+#: src/exercises/day-3/solutions-afternoon.md:45
+#: src/exercises/bare-metal/solutions-afternoon.md:43
+msgid "\"C\""
+msgstr ""
+
+#: src/unsafe/extern-functions.md:13
+#, fuzzy
+#| msgid "No undefined behavior at runtime:"
+msgid "// Undefined behavior if abs misbehaves.\n"
+msgstr "No hay comportamientos indefinidos en _runtime_:"
+
+#: src/unsafe/extern-functions.md:14
+msgid "\"Absolute value of -3 according to C: {}\""
msgstr ""
#: src/unsafe/extern-functions.md:21
@@ -12567,27 +10902,15 @@ msgstr ""
"Por ejemplo, el crate `zerocopy` tiene un trait inseguro, [que se parece a "
"esto](https://docs.rs/zerocopy/latest/zerocopy/trait.AsBytes.html):"
-#: src/unsafe/unsafe-traits.md:9
+#: src/unsafe/unsafe-traits.md:12
msgid ""
-"```rust,editable\n"
-"use std::mem::size_of_val;\n"
-"use std::slice;\n"
-"\n"
"/// ...\n"
"/// # Safety\n"
"/// The type must have a defined representation and no padding.\n"
-"pub unsafe trait AsBytes {\n"
-" fn as_bytes(&self) -> &[u8] {\n"
-" unsafe {\n"
-" slice::from_raw_parts(self as *const Self as *const u8, "
-"size_of_val(self))\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"// Safe because u32 has a defined representation and no padding.\n"
-"unsafe impl AsBytes for u32 {}\n"
-"```"
+msgstr ""
+
+#: src/unsafe/unsafe-traits.md:23
+msgid "// Safe because u32 has a defined representation and no padding.\n"
msgstr ""
#: src/unsafe/unsafe-traits.md:30
@@ -12645,10 +10968,15 @@ msgstr ""
"afternoon.md) proporcionada."
#: src/exercises/day-3/safe-ffi-wrapper.md:3
+#, fuzzy
+#| msgid ""
+#| "Rust has great support for calling functions through a _foreign function "
+#| "interface_ (FFI). We will use this to build a safe wrapper for the `libc` "
+#| "functions you would use from C to read the filenames of a directory."
msgid ""
"Rust has great support for calling functions through a _foreign function "
"interface_ (FFI). We will use this to build a safe wrapper for the `libc` "
-"functions you would use from C to read the filenames of a directory."
+"functions you would use from C to read the names of files in a directory."
msgstr ""
"Rust ofrece una gran asisencia para llamar a funciones a través de una "
"_interfaz de función externa_ (FFI). Usaremos esto para crear un envoltorio "
@@ -12762,9 +11090,13 @@ msgstr ""
"final `\\0`,"
#: src/exercises/day-3/safe-ffi-wrapper.md:27
+#, fuzzy
+#| msgid ""
+#| "`&CStr` to `&[u8]`: a slice of bytes is the universal interface for "
+#| "\"some unknow data\","
msgid ""
"`&CStr` to `&[u8]`: a slice of bytes is the universal interface for \"some "
-"unknow data\","
+"unknown data\","
msgstr ""
"De `&CStr` a `&[u8]`: un slice de bytes es la interfaz universal para "
"\"algunos datos desconocidos\"."
@@ -12801,111 +11133,88 @@ msgstr ""
"Copia el fragmento de código que aparece más abajo en la página y rellena los métodos y funciones que faltan:"
-#: src/exercises/day-3/safe-ffi-wrapper.md:48
+#: src/exercises/day-3/safe-ffi-wrapper.md:54
+#: src/exercises/day-3/safe-ffi-wrapper.md:67
+#: src/exercises/day-3/safe-ffi-wrapper.md:78
+#: src/exercises/day-3/safe-ffi-wrapper.md:92
+#: src/exercises/day-3/safe-ffi-wrapper.md:100
+#: src/exercises/day-3/solutions-afternoon.md:10
+#: src/exercises/day-3/solutions-afternoon.md:23
+#: src/exercises/day-3/solutions-afternoon.md:34
+#: src/exercises/day-3/solutions-afternoon.md:48
+#: src/exercises/day-3/solutions-afternoon.md:56
+msgid "\"macos\""
+msgstr ""
+
+#: src/exercises/day-3/safe-ffi-wrapper.md:57
+#: src/exercises/day-3/solutions-afternoon.md:13
+msgid "// Opaque type. See https://doc.rust-lang.org/nomicon/ffi.html.\n"
+msgstr ""
+
+#: src/exercises/day-3/safe-ffi-wrapper.md:64
+#: src/exercises/day-3/solutions-afternoon.md:20
msgid ""
-"```rust,should_panic\n"
-"// TODO: remove this when you're done with your implementation.\n"
-"#![allow(unused_imports, unused_variables, dead_code)]\n"
-"\n"
-"mod ffi {\n"
-" use std::os::raw::{c_char, c_int};\n"
-" #[cfg(not(target_os = \"macos\"))]\n"
-" use std::os::raw::{c_long, c_ulong, c_ushort, c_uchar};\n"
-"\n"
-" // Opaque type. See https://doc.rust-lang.org/nomicon/ffi.html.\n"
-" #[repr(C)]\n"
-" pub struct DIR {\n"
-" _data: [u8; 0],\n"
-" _marker: core::marker::PhantomData<(*mut u8, core::marker::"
-"PhantomPinned)>,\n"
-" }\n"
-"\n"
-" // Layout according to the Linux man page for readdir(3), where ino_t "
-"and\n"
+"// Layout according to the Linux man page for readdir(3), where ino_t and\n"
" // off_t are resolved according to the definitions in\n"
" // /usr/include/x86_64-linux-gnu/{sys/types.h, bits/typesizes.h}.\n"
-" #[cfg(not(target_os = \"macos\"))]\n"
-" #[repr(C)]\n"
-" pub struct dirent {\n"
-" pub d_ino: c_ulong,\n"
-" pub d_off: c_long,\n"
-" pub d_reclen: c_ushort,\n"
-" pub d_type: c_uchar,\n"
-" pub d_name: [c_char; 256],\n"
-" }\n"
-"\n"
-" // Layout according to the macOS man page for dir(5).\n"
-" #[cfg(all(target_os = \"macos\"))]\n"
-" #[repr(C)]\n"
-" pub struct dirent {\n"
-" pub d_fileno: u64,\n"
-" pub d_seekoff: u64,\n"
-" pub d_reclen: u16,\n"
-" pub d_namlen: u16,\n"
-" pub d_type: u8,\n"
-" pub d_name: [c_char; 1024],\n"
-" }\n"
-"\n"
-" extern \"C\" {\n"
-" pub fn opendir(s: *const c_char) -> *mut DIR;\n"
-"\n"
-" #[cfg(not(all(target_os = \"macos\", target_arch = \"x86_64\")))]\n"
-" pub fn readdir(s: *mut DIR) -> *const dirent;\n"
-"\n"
-" // See https://github.com/rust-lang/libc/issues/414 and the section "
-"on\n"
+msgstr ""
+
+#: src/exercises/day-3/safe-ffi-wrapper.md:77
+#: src/exercises/day-3/solutions-afternoon.md:33
+msgid "// Layout according to the macOS man page for dir(5).\n"
+msgstr ""
+
+#: src/exercises/day-3/safe-ffi-wrapper.md:92
+#: src/exercises/day-3/safe-ffi-wrapper.md:100
+#: src/exercises/day-3/solutions-afternoon.md:48
+#: src/exercises/day-3/solutions-afternoon.md:56
+msgid "\"x86_64\""
+msgstr ""
+
+#: src/exercises/day-3/safe-ffi-wrapper.md:95
+#: src/exercises/day-3/solutions-afternoon.md:51
+msgid ""
+"// See https://github.com/rust-lang/libc/issues/414 and the section on\n"
" // _DARWIN_FEATURE_64_BIT_INODE in the macOS man page for stat(2).\n"
" //\n"
" // \"Platforms that existed before these updates were available\" "
"refers\n"
" // to macOS (as opposed to iOS / wearOS / etc.) on Intel and "
"PowerPC.\n"
-" #[cfg(all(target_os = \"macos\", target_arch = \"x86_64\"))]\n"
-" #[link_name = \"readdir$INODE64\"]\n"
-" pub fn readdir(s: *mut DIR) -> *const dirent;\n"
-"\n"
-" pub fn closedir(s: *mut DIR) -> c_int;\n"
-" }\n"
-"}\n"
-"\n"
-"use std::ffi::{CStr, CString, OsStr, OsString};\n"
-"use std::os::unix::ffi::OsStrExt;\n"
-"\n"
-"#[derive(Debug)]\n"
-"struct DirectoryIterator {\n"
-" path: CString,\n"
-" dir: *mut ffi::DIR,\n"
-"}\n"
-"\n"
-"impl DirectoryIterator {\n"
-" fn new(path: &str) -> Result {\n"
-" // Call opendir and return a Ok value if that worked,\n"
+msgstr ""
+
+#: src/exercises/day-3/safe-ffi-wrapper.md:101
+#: src/exercises/day-3/solutions-afternoon.md:57
+msgid "\"readdir$INODE64\""
+msgstr ""
+
+#: src/exercises/day-3/safe-ffi-wrapper.md:119
+#: src/exercises/day-3/solutions-afternoon.md:75
+msgid ""
+"// Call opendir and return a Ok value if that worked,\n"
" // otherwise return Err with a message.\n"
-" unimplemented!()\n"
-" }\n"
-"}\n"
-"\n"
-"impl Iterator for DirectoryIterator {\n"
-" type Item = OsString;\n"
-" fn next(&mut self) -> Option {\n"
-" // Keep calling readdir until we get a NULL pointer back.\n"
-" unimplemented!()\n"
-" }\n"
-"}\n"
-"\n"
-"impl Drop for DirectoryIterator {\n"
-" fn drop(&mut self) {\n"
-" // Call closedir as needed.\n"
-" unimplemented!()\n"
-" }\n"
-"}\n"
-"\n"
-"fn main() -> Result<(), String> {\n"
-" let iter = DirectoryIterator::new(\".\")?;\n"
-" println!(\"files: {:#?}\", iter.collect::>());\n"
-" Ok(())\n"
-"}\n"
-"```"
+msgstr ""
+
+#: src/exercises/day-3/safe-ffi-wrapper.md:128
+msgid "// Keep calling readdir until we get a NULL pointer back.\n"
+msgstr ""
+
+#: src/exercises/day-3/safe-ffi-wrapper.md:135
+#: src/exercises/day-3/solutions-afternoon.md:108
+msgid "// Call closedir as needed.\n"
+msgstr ""
+
+#: src/exercises/day-3/safe-ffi-wrapper.md:141
+#: src/android/interoperability/with-c/rust.md:44
+#: src/exercises/day-3/solutions-afternoon.md:119
+#: src/exercises/day-3/solutions-afternoon.md:143
+#: src/exercises/day-3/solutions-afternoon.md:158
+msgid "\".\""
+msgstr ""
+
+#: src/exercises/day-3/safe-ffi-wrapper.md:142
+#: src/exercises/day-3/solutions-afternoon.md:120
+msgid "\"files: {:#?}\""
msgstr ""
#: src/android.md:1
@@ -12942,15 +11251,6 @@ msgstr ""
"Utilizaremos un dispositivo Android virtual para probar el código. Asegúrate "
"de que tienes acceso a uno o créalo con:"
-#: src/android/setup.md:6
-msgid ""
-"```shell\n"
-"source build/envsetup.sh\n"
-"lunch aosp_cf_x86_64_phone-userdebug\n"
-"acloud create\n"
-"```"
-msgstr ""
-
#: src/android/setup.md:12
msgid ""
"Please see the [Android Developer Codelab](https://source.android.com/docs/"
@@ -13076,31 +11376,31 @@ msgstr ""
msgid "_hello_rust/Android.bp_:"
msgstr "_hello_rust/Android.bp_:"
-#: src/android/build-rules/binary.md:8
-msgid ""
-"```javascript\n"
-"rust_binary {\n"
-" name: \"hello_rust\",\n"
-" crate_name: \"hello_rust\",\n"
-" srcs: [\"src/main.rs\"],\n"
-"}\n"
-"```"
+#: src/android/build-rules/binary.md:10 src/android/build-rules/binary.md:11
+msgid "\"hello_rust\""
msgstr ""
+#: src/android/build-rules/binary.md:12 src/android/build-rules/library.md:19
+#: src/android/logging.md:12
+#, fuzzy
+#| msgid "`src/main.rs`:"
+msgid "\"src/main.rs\""
+msgstr "`src/main.rs`:"
+
#: src/android/build-rules/binary.md:16 src/android/build-rules/library.md:34
msgid "_hello_rust/src/main.rs_:"
msgstr "_hello_rust/src/main.rs_:"
-#: src/android/build-rules/binary.md:18
-msgid ""
-"```rust\n"
-"//! Rust demo.\n"
-"\n"
-"/// Prints a greeting to standard output.\n"
-"fn main() {\n"
-" println!(\"Hello from Rust!\");\n"
-"}\n"
-"```"
+#: src/android/build-rules/binary.md:19 src/android/build-rules/library.md:37
+msgid "//! Rust demo.\n"
+msgstr ""
+
+#: src/android/build-rules/binary.md:20 src/android/build-rules/library.md:41
+msgid "/// Prints a greeting to standard output.\n"
+msgstr ""
+
+#: src/android/build-rules/binary.md:23
+msgid "\"Hello from Rust!\""
msgstr ""
#: src/android/build-rules/binary.md:27
@@ -13116,13 +11416,6 @@ msgid ""
"```"
msgstr ""
-#: src/android/build-rules/binary.md:35
-msgid ""
-"```text\n"
-"Hello from Rust!\n"
-"```"
-msgstr ""
-
#: src/android/build-rules/library.md:1
msgid "Rust Libraries"
msgstr "Bibliotecas de Rust"
@@ -13149,94 +11442,53 @@ msgstr ""
"(https://cs.android.com/android/platform/superproject/+/master:external/rust/"
"crates/)."
-#: src/android/build-rules/library.md:15
-msgid ""
-"```javascript\n"
-"rust_binary {\n"
-" name: \"hello_rust_with_dep\",\n"
-" crate_name: \"hello_rust_with_dep\",\n"
-" srcs: [\"src/main.rs\"],\n"
-" rustlibs: [\n"
-" \"libgreetings\",\n"
-" \"libtextwrap\",\n"
-" ],\n"
-" prefer_rlib: true,\n"
-"}\n"
-"\n"
-"rust_library {\n"
-" name: \"libgreetings\",\n"
-" crate_name: \"greetings\",\n"
-" srcs: [\"src/lib.rs\"],\n"
-"}\n"
-"```"
+#: src/android/build-rules/library.md:17 src/android/build-rules/library.md:18
+msgid "\"hello_rust_with_dep\""
msgstr ""
-"```javascript\n"
-"rust_binary {\n"
-" name: \"hello_rust_with_dep\",\n"
-" crate_name: \"hello_rust_with_dep\",\n"
-" srcs: [\"src/main.rs\"],\n"
-" rustlibs: [\n"
-" \"libgreetings\",\n"
-" \"libtextwrap\",\n"
-" ],\n"
-" prefer_rlib: true,\n"
-"}\n"
-"\n"
-"rust_library {\n"
-" name: \"libgreetings\",\n"
-" crate_name: \"greetings\",\n"
-" srcs: [\"src/lib.rs\"],\n"
-"}\n"
-"```"
-#: src/android/build-rules/library.md:36
-msgid ""
-"```rust,ignore\n"
-"//! Rust demo.\n"
-"\n"
-"use greetings::greeting;\n"
-"use textwrap::fill;\n"
-"\n"
-"/// Prints a greeting to standard output.\n"
-"fn main() {\n"
-" println!(\"{}\", fill(&greeting(\"Bob\"), 24));\n"
-"}\n"
-"```"
+#: src/android/build-rules/library.md:21 src/android/build-rules/library.md:28
+msgid "\"libgreetings\""
msgstr ""
-"```rust,ignore\n"
-"//! Rust demo.\n"
-"\n"
-"use greetings::greeting;\n"
-"use textwrap::fill;\n"
-"\n"
-"/// Imprime un saludo en una salida estándar.\n"
-"fn main() {\n"
-" println!(\"{}\", fill(&greeting(\"Bob\"), 24));\n"
-"}\n"
-"```"
+
+#: src/android/build-rules/library.md:22
+msgid "\"libtextwrap\""
+msgstr ""
+
+#: src/android/build-rules/library.md:29
+msgid "\"greetings\""
+msgstr ""
+
+#: src/android/build-rules/library.md:30 src/android/aidl/implementation.md:31
+#: src/android/interoperability/java.md:38
+#, fuzzy
+#| msgid "`src/main.rs`:"
+msgid "\"src/lib.rs\""
+msgstr "`src/main.rs`:"
#: src/android/build-rules/library.md:48
msgid "_hello_rust/src/lib.rs_:"
msgstr "_hello_rust/src/lib.rs_:"
-#: src/android/build-rules/library.md:50
-msgid ""
-"```rust,ignore\n"
-"//! Greeting library.\n"
-"\n"
-"/// Greet `name`.\n"
-"pub fn greeting(name: &str) -> String {\n"
-" format!(\"Hello {name}, it is very nice to meet you!\")\n"
-"}\n"
-"```"
+#: src/android/build-rules/library.md:51
+msgid "//! Greeting library.\n"
msgstr ""
-"```rust,ignore\n"
-"//! Greeting library.\n"
-"\n"
-"/// Saludar a `name`.\n"
-"pub fn greeting(name: &str) -> String {\n"
-" format!(\"Hello {name}, it is very nice to meet you!\")\n"
-"}\n"
+
+#: src/android/build-rules/library.md:52
+msgid "/// Greet `name`.\n"
+msgstr ""
+
+#: src/android/build-rules/library.md:55
+#, fuzzy
+#| msgid ""
+#| "```text\n"
+#| "Hello Bob, it is very\n"
+#| "nice to meet you!\n"
+#| "```"
+msgid "\"Hello {name}, it is very nice to meet you!\""
+msgstr ""
+"```text\n"
+"Hello Bob, it is very\n"
+"nice to meet you!\n"
"```"
#: src/android/build-rules/library.md:59
@@ -13259,19 +11511,7 @@ msgstr ""
"adb shell /data/local/tmp/hello_rust_with_dep\n"
"```"
-#: src/android/build-rules/library.md:67
-msgid ""
-"```text\n"
-"Hello Bob, it is very\n"
-"nice to meet you!\n"
-"```"
-msgstr ""
-"```text\n"
-"Hello Bob, it is very\n"
-"nice to meet you!\n"
-"```"
-
-#: src/android/aidl.md:3
+#: src/android/aidl.md:3
msgid ""
"The [Android Interface Definition Language (AIDL)](https://developer.android."
"com/guide/components/aidl) is supported in Rust:"
@@ -13302,59 +11542,33 @@ msgid ""
msgstr ""
"_birthday_service/aidl/com/example/birthdayservice/IBirthdayService.aidl_:"
-#: src/android/aidl/interface.md:7
-msgid ""
-"```java\n"
-"package com.example.birthdayservice;\n"
-"\n"
-"/** Birthday service interface. */\n"
-"interface IBirthdayService {\n"
-" /** Generate a Happy Birthday message. */\n"
-" String wishHappyBirthday(String name, int years);\n"
-"}\n"
-"```"
+#: src/android/aidl/interface.md:9 src/android/aidl/changing.md:8
+msgid "/** Birthday service interface. */"
+msgstr ""
+
+#: src/android/aidl/interface.md:12 src/android/aidl/changing.md:11
+msgid "/** Generate a Happy Birthday message. */"
msgstr ""
-"```java\n"
-"package com.example.birthdayservice;\n"
-"\n"
-"/** Birthday service interface. */\n"
-"interface IBirthdayService {\n"
-" /** Generate a Happy Birthday message. */\n"
-" String wishHappyBirthday(String name, int years);\n"
-"}\n"
-"```"
#: src/android/aidl/interface.md:17
msgid "_birthday_service/aidl/Android.bp_:"
msgstr "_birthday_service/aidl/Android.bp_:"
-#: src/android/aidl/interface.md:19
-msgid ""
-"```javascript\n"
-"aidl_interface {\n"
-" name: \"com.example.birthdayservice\",\n"
-" srcs: [\"com/example/birthdayservice/*.aidl\"],\n"
-" unstable: true,\n"
-" backend: {\n"
-" rust: { // Rust is not enabled by default\n"
-" enabled: true,\n"
-" },\n"
-" },\n"
-"}\n"
-"```"
+#: src/android/aidl/interface.md:21
+msgid "\"com.example.birthdayservice\""
+msgstr ""
+
+#: src/android/aidl/interface.md:22
+#, fuzzy
+#| msgid ""
+#| "_birthday_service/aidl/com/example/birthdayservice/IBirthdayService.aidl_:"
+msgid "\"com/example/birthdayservice/*.aidl\""
+msgstr ""
+"_birthday_service/aidl/com/example/birthdayservice/IBirthdayService.aidl_:"
+
+#: src/android/aidl/interface.md:25
+msgid "// Rust is not enabled by default\n"
msgstr ""
-"```javascript\n"
-"aidl_interface {\n"
-" name: \"com.example.birthdayservice\",\n"
-" srcs: [\"com/example/birthdayservice/*.aidl\"],\n"
-" unstable: true,\n"
-" backend: {\n"
-" rust: { // Rust is not enabled by default\n"
-" enabled: true,\n"
-" },\n"
-" },\n"
-"}\n"
-"```"
#: src/android/aidl/interface.md:32
msgid ""
@@ -13376,29 +11590,18 @@ msgstr "Ahora podemos implementar el servicio de AIDL:"
msgid "_birthday_service/src/lib.rs_:"
msgstr "_birthday_service/src/lib.rs_:"
-#: src/android/aidl/implementation.md:7
-msgid ""
-"```rust,ignore\n"
-"//! Implementation of the `IBirthdayService` AIDL interface.\n"
-"use com_example_birthdayservice::aidl::com::example::birthdayservice::"
-"IBirthdayService::IBirthdayService;\n"
-"use com_example_birthdayservice::binder;\n"
-"\n"
-"/// The `IBirthdayService` implementation.\n"
-"pub struct BirthdayService;\n"
-"\n"
-"impl binder::Interface for BirthdayService {}\n"
-"\n"
-"impl IBirthdayService for BirthdayService {\n"
-" fn wishHappyBirthday(&self, name: &str, years: i32) -> binder::"
-"Result {\n"
-" Ok(format!(\n"
-" \"Happy Birthday {name}, congratulations with the {years} years!"
-"\"\n"
-" ))\n"
-" }\n"
-"}\n"
-"```"
+#: src/android/aidl/implementation.md:8
+msgid "//! Implementation of the `IBirthdayService` AIDL interface.\n"
+msgstr ""
+
+#: src/android/aidl/implementation.md:11
+#, fuzzy
+#| msgid "Service Implementation"
+msgid "/// The `IBirthdayService` implementation.\n"
+msgstr "Implementación del servicio"
+
+#: src/android/aidl/implementation.md:20
+msgid "\"Happy Birthday {name}, congratulations with the {years} years!\""
msgstr ""
#: src/android/aidl/implementation.md:26 src/android/aidl/server.md:28
@@ -13406,19 +11609,27 @@ msgstr ""
msgid "_birthday_service/Android.bp_:"
msgstr "_birthday_service/Android.bp_:"
-#: src/android/aidl/implementation.md:28
-msgid ""
-"```javascript\n"
-"rust_library {\n"
-" name: \"libbirthdayservice\",\n"
-" srcs: [\"src/lib.rs\"],\n"
-" crate_name: \"birthdayservice\",\n"
-" rustlibs: [\n"
-" \"com.example.birthdayservice-rust\",\n"
-" \"libbinder_rs\",\n"
-" ],\n"
-"}\n"
-"```"
+#: src/android/aidl/implementation.md:30 src/android/aidl/server.md:38
+#, fuzzy
+#| msgid "_birthday_service/src/lib.rs_:"
+msgid "\"libbirthdayservice\""
+msgstr "_birthday_service/src/lib.rs_:"
+
+#: src/android/aidl/implementation.md:32 src/android/aidl/server.md:13
+#: src/android/aidl/client.md:12
+#, fuzzy
+#| msgid "_birthday_service/src/lib.rs_:"
+msgid "\"birthdayservice\""
+msgstr "_birthday_service/src/lib.rs_:"
+
+#: src/android/aidl/implementation.md:34 src/android/aidl/server.md:36
+#: src/android/aidl/client.md:45
+msgid "\"com.example.birthdayservice-rust\""
+msgstr ""
+
+#: src/android/aidl/implementation.md:35 src/android/aidl/server.md:37
+#: src/android/aidl/client.md:46
+msgid "\"libbinder_rs\""
msgstr ""
#: src/android/aidl/server.md:1
@@ -13433,49 +11644,30 @@ msgstr "Por último, podemos crear un servidor que exponga el servicio:"
msgid "_birthday_service/src/server.rs_:"
msgstr "_birthday_service/src/server.rs_:"
-#: src/android/aidl/server.md:7
-msgid ""
-"```rust,ignore\n"
-"//! Birthday service.\n"
-"use birthdayservice::BirthdayService;\n"
-"use com_example_birthdayservice::aidl::com::example::birthdayservice::"
-"IBirthdayService::BnBirthdayService;\n"
-"use com_example_birthdayservice::binder;\n"
-"\n"
-"const SERVICE_IDENTIFIER: &str = \"birthdayservice\";\n"
-"\n"
-"/// Entry point for birthday service.\n"
-"fn main() {\n"
-" let birthday_service = BirthdayService;\n"
-" let birthday_service_binder = BnBirthdayService::new_binder(\n"
-" birthday_service,\n"
-" binder::BinderFeatures::default(),\n"
-" );\n"
-" binder::add_service(SERVICE_IDENTIFIER, birthday_service_binder."
-"as_binder())\n"
-" .expect(\"Failed to register service\");\n"
-" binder::ProcessState::join_thread_pool()\n"
-"}\n"
-"```"
+#: src/android/aidl/server.md:8 src/android/aidl/client.md:8
+msgid "//! Birthday service.\n"
msgstr ""
-#: src/android/aidl/server.md:30
-msgid ""
-"```javascript\n"
-"rust_binary {\n"
-" name: \"birthday_server\",\n"
-" crate_name: \"birthday_server\",\n"
-" srcs: [\"src/server.rs\"],\n"
-" rustlibs: [\n"
-" \"com.example.birthdayservice-rust\",\n"
-" \"libbinder_rs\",\n"
-" \"libbirthdayservice\",\n"
-" ],\n"
-" prefer_rlib: true,\n"
-"}\n"
-"```"
+#: src/android/aidl/server.md:14
+msgid "/// Entry point for birthday service.\n"
+msgstr ""
+
+#: src/android/aidl/server.md:23
+msgid "\"Failed to register service\""
msgstr ""
+#: src/android/aidl/server.md:32 src/android/aidl/server.md:33
+#, fuzzy
+#| msgid "_birthday_service/src/lib.rs_:"
+msgid "\"birthday_server\""
+msgstr "_birthday_service/src/lib.rs_:"
+
+#: src/android/aidl/server.md:34
+#, fuzzy
+#| msgid "`src/bin/server.rs`:"
+msgid "\"src/server.rs\""
+msgstr "`src/bin/server.rs`:"
+
#: src/android/aidl/deploy.md:3
msgid "We can now build, push, and start the service:"
msgstr "Ahora podemos crear, insertar e iniciar el servicio:"
@@ -13494,46 +11686,10 @@ msgstr ""
msgid "In another terminal, check that the service runs:"
msgstr "Comprueba que el servicio funciona en otra terminal:"
-#: src/android/aidl/deploy.md:13
-msgid ""
-"```shell\n"
-"adb shell service check birthdayservice\n"
-"```"
-msgstr ""
-
-#: src/android/aidl/deploy.md:17
-msgid ""
-"```text\n"
-"Service birthdayservice: found\n"
-"```"
-msgstr ""
-
#: src/android/aidl/deploy.md:21
msgid "You can also call the service with `service call`:"
msgstr "También puedes llamar al servicio con `service call`:"
-#: src/android/aidl/deploy.md:23
-msgid ""
-"```shell\n"
-"adb shell service call birthdayservice 1 s16 Bob i32 24\n"
-"```"
-msgstr ""
-
-#: src/android/aidl/deploy.md:27
-msgid ""
-"```text\n"
-"Result: Parcel(\n"
-" 0x00000000: 00000000 00000036 00610048 00700070 '....6...H.a.p.p.'\n"
-" 0x00000010: 00200079 00690042 00740072 00640068 'y. .B.i.r.t.h.d.'\n"
-" 0x00000020: 00790061 00420020 0062006f 0020002c 'a.y. .B.o.b.,. .'\n"
-" 0x00000030: 006f0063 0067006e 00610072 00750074 'c.o.n.g.r.a.t.u.'\n"
-" 0x00000040: 0061006c 00690074 006e006f 00200073 'l.a.t.i.o.n.s. .'\n"
-" 0x00000050: 00690077 00680074 00740020 00650068 'w.i.t.h. .t.h.e.'\n"
-" 0x00000060: 00320020 00200034 00650079 00720061 ' .2.4. .y.e.a.r.'\n"
-" 0x00000070: 00210073 00000000 's.!..... ')\n"
-"```"
-msgstr ""
-
#: src/android/aidl/client.md:1
msgid "AIDL Client"
msgstr "Cliente de AIDL"
@@ -13547,58 +11703,34 @@ msgstr ""
msgid "_birthday_service/src/client.rs_:"
msgstr "_birthday_service/src/client.rs_:"
-#: src/android/aidl/client.md:7
-msgid ""
-"```rust,ignore\n"
-"//! Birthday service.\n"
-"use com_example_birthdayservice::aidl::com::example::birthdayservice::"
-"IBirthdayService::IBirthdayService;\n"
-"use com_example_birthdayservice::binder;\n"
-"\n"
-"const SERVICE_IDENTIFIER: &str = \"birthdayservice\";\n"
-"\n"
-"/// Connect to the BirthdayService.\n"
-"pub fn connect() -> Result, binder::"
-"StatusCode> {\n"
-" binder::get_interface(SERVICE_IDENTIFIER)\n"
-"}\n"
-"\n"
-"/// Call the birthday service.\n"
-"fn main() -> Result<(), binder::Status> {\n"
-" let name = std::env::args()\n"
-" .nth(1)\n"
-" .unwrap_or_else(|| String::from(\"Bob\"));\n"
-" let years = std::env::args()\n"
-" .nth(2)\n"
-" .and_then(|arg| arg.parse::().ok())\n"
-" .unwrap_or(42);\n"
-"\n"
-" binder::ProcessState::start_thread_pool();\n"
-" let service = connect().expect(\"Failed to connect to "
-"BirthdayService\");\n"
-" let msg = service.wishHappyBirthday(&name, years)?;\n"
-" println!(\"{msg}\");\n"
-" Ok(())\n"
-"}\n"
-"```"
+#: src/android/aidl/client.md:13
+msgid "/// Connect to the BirthdayService.\n"
msgstr ""
-#: src/android/aidl/client.md:39
-msgid ""
-"```javascript\n"
-"rust_binary {\n"
-" name: \"birthday_client\",\n"
-" crate_name: \"birthday_client\",\n"
-" srcs: [\"src/client.rs\"],\n"
-" rustlibs: [\n"
-" \"com.example.birthdayservice-rust\",\n"
-" \"libbinder_rs\",\n"
-" ],\n"
-" prefer_rlib: true,\n"
-"}\n"
-"```"
+#: src/android/aidl/client.md:18
+msgid "/// Call the birthday service.\n"
+msgstr ""
+
+#: src/android/aidl/client.md:30
+msgid "\"Failed to connect to BirthdayService\""
msgstr ""
+#: src/android/aidl/client.md:32
+msgid "\"{msg}\""
+msgstr ""
+
+#: src/android/aidl/client.md:41 src/android/aidl/client.md:42
+#, fuzzy
+#| msgid "_birthday_service/src/client.rs_:"
+msgid "\"birthday_client\""
+msgstr "_birthday_service/src/client.rs_:"
+
+#: src/android/aidl/client.md:43
+#, fuzzy
+#| msgid "`src/bin/client.rs`:"
+msgid "\"src/client.rs\""
+msgstr "`src/bin/client.rs`:"
+
#: src/android/aidl/client.md:52
msgid "Notice that the client does not depend on `libbirthdayservice`."
msgstr "Ten en cuenta que el cliente no depende de `libbirthdayservice`."
@@ -13617,13 +11749,6 @@ msgid ""
"```"
msgstr ""
-#: src/android/aidl/client.md:62
-msgid ""
-"```text\n"
-"Happy Birthday Charlie, congratulations with the 60 years!\n"
-"```"
-msgstr ""
-
#: src/android/aidl/changing.md:3
msgid ""
"Let us extend the API with more functionality: we want to let clients "
@@ -13632,19 +11757,6 @@ msgstr ""
"Ampliemos la API con más funciones. Queremos que los clientes puedan indicar "
"una lista de líneas para la tarjeta de cumpleaños:"
-#: src/android/aidl/changing.md:6
-msgid ""
-"```java\n"
-"package com.example.birthdayservice;\n"
-"\n"
-"/** Birthday service interface. */\n"
-"interface IBirthdayService {\n"
-" /** Generate a Happy Birthday message. */\n"
-" String wishHappyBirthday(String name, int years, in String[] text);\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/android/logging.md:3
msgid ""
"You should use the `log` crate to automatically log to `logcat` (on-device) "
@@ -13657,46 +11769,46 @@ msgstr ""
msgid "_hello_rust_logs/Android.bp_:"
msgstr "_hello_rust_logs/Android.bp_:"
-#: src/android/logging.md:8
-msgid ""
-"```javascript\n"
-"rust_binary {\n"
-" name: \"hello_rust_logs\",\n"
-" crate_name: \"hello_rust_logs\",\n"
-" srcs: [\"src/main.rs\"],\n"
-" rustlibs: [\n"
-" \"liblog_rust\",\n"
-" \"liblogger\",\n"
-" ],\n"
-" prefer_rlib: true,\n"
-" host_supported: true,\n"
-"}\n"
-"```"
+#: src/android/logging.md:10 src/android/logging.md:11
+#, fuzzy
+#| msgid "_hello_rust_logs/Android.bp_:"
+msgid "\"hello_rust_logs\""
+msgstr "_hello_rust_logs/Android.bp_:"
+
+#: src/android/logging.md:14
+msgid "\"liblog_rust\""
+msgstr ""
+
+#: src/android/logging.md:15
+msgid "\"liblogger\""
msgstr ""
#: src/android/logging.md:22
msgid "_hello_rust_logs/src/main.rs_:"
msgstr "_hello_rust_logs/src/main.rs_:"
-#: src/android/logging.md:24
-msgid ""
-"```rust,ignore\n"
-"//! Rust logging demo.\n"
-"\n"
-"use log::{debug, error, info};\n"
-"\n"
-"/// Logs a greeting.\n"
-"fn main() {\n"
-" logger::init(\n"
-" logger::Config::default()\n"
-" .with_tag_on_device(\"rust\")\n"
-" .with_min_level(log::Level::Trace),\n"
-" );\n"
-" debug!(\"Starting program.\");\n"
-" info!(\"Things are going fine.\");\n"
-" error!(\"Something went wrong!\");\n"
-"}\n"
-"```"
+#: src/android/logging.md:25
+msgid "//! Rust logging demo.\n"
+msgstr ""
+
+#: src/android/logging.md:28
+msgid "/// Logs a greeting.\n"
+msgstr ""
+
+#: src/android/logging.md:33
+msgid "\"rust\""
+msgstr ""
+
+#: src/android/logging.md:36
+msgid "\"Starting program.\""
+msgstr ""
+
+#: src/android/logging.md:37
+msgid "\"Things are going fine.\""
+msgstr ""
+
+#: src/android/logging.md:38
+msgid "\"Something went wrong!\""
msgstr ""
#: src/android/logging.md:42 src/android/interoperability/with-c/bindgen.md:98
@@ -13718,24 +11830,6 @@ msgstr ""
msgid "The logs show up in `adb logcat`:"
msgstr "Los registros se muestran en `adb logcat`:"
-#: src/android/logging.md:52
-msgid ""
-"```shell\n"
-"adb logcat -s rust\n"
-"```"
-msgstr ""
-
-#: src/android/logging.md:56
-msgid ""
-"```text\n"
-"09-08 08:38:32.454 2420 2420 D rust: hello_rust_logs: Starting program.\n"
-"09-08 08:38:32.454 2420 2420 I rust: hello_rust_logs: Things are going "
-"fine.\n"
-"09-08 08:38:32.454 2420 2420 E rust: hello_rust_logs: Something went "
-"wrong!\n"
-"```"
-msgstr ""
-
#: src/android/interoperability.md:3
msgid ""
"Rust has excellent support for interoperability with other languages. This "
@@ -13776,19 +11870,8 @@ msgstr ""
msgid "You can do it by hand if you want:"
msgstr "Si quieres, puedes hacerlo de forma manual:"
-#: src/android/interoperability/with-c.md:8
-msgid ""
-"```rust\n"
-"extern \"C\" {\n"
-" fn abs(x: i32) -> i32;\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let x = -42;\n"
-" let abs_x = unsafe { abs(x) };\n"
-" println!(\"{x}, {abs_x}\");\n"
-"}\n"
-"```"
+#: src/android/interoperability/with-c.md:16
+msgid "\"{x}, {abs_x}\""
msgstr ""
#: src/android/interoperability/with-c.md:20
@@ -13832,35 +11915,26 @@ msgstr "En primer lugar, crea una biblioteca de C pequeña:"
msgid "_interoperability/bindgen/libbirthday.h_:"
msgstr "_interoperability/bindgen/libbirthday.h_:"
-#: src/android/interoperability/with-c/bindgen.md:10
-msgid ""
-"```c\n"
-"typedef struct card {\n"
-" const char* name;\n"
-" int years;\n"
-"} card;\n"
-"\n"
-"void print_card(const card* card);\n"
-"```"
-msgstr ""
-
#: src/android/interoperability/with-c/bindgen.md:19
msgid "_interoperability/bindgen/libbirthday.c_:"
msgstr "_interoperability/bindgen/libbirthday.c_:"
-#: src/android/interoperability/with-c/bindgen.md:21
-msgid ""
-"```c\n"
-"#include \n"
-"#include \"libbirthday.h\"\n"
-"\n"
-"void print_card(const card* card) {\n"
-" printf(\"+--------------\\n\");\n"
-" printf(\"| Happy Birthday %s!\\n\", card->name);\n"
-" printf(\"| Congratulations with the %i years!\\n\", card->years);\n"
-" printf(\"+--------------\\n\");\n"
-"}\n"
-"```"
+#: src/android/interoperability/with-c/bindgen.md:23
+#: src/android/interoperability/with-c/bindgen.md:50
+msgid "\"libbirthday.h\""
+msgstr ""
+
+#: src/android/interoperability/with-c/bindgen.md:26
+#: src/android/interoperability/with-c/bindgen.md:29
+msgid "\"+--------------\\n\""
+msgstr ""
+
+#: src/android/interoperability/with-c/bindgen.md:27
+msgid "\"| Happy Birthday %s!\\n\""
+msgstr ""
+
+#: src/android/interoperability/with-c/bindgen.md:28
+msgid "\"| Congratulations with the %i years!\\n\""
msgstr ""
#: src/android/interoperability/with-c/bindgen.md:33
@@ -13874,14 +11948,13 @@ msgstr "Añade lo siguiente a tu archivo `Android.bp`:"
msgid "_interoperability/bindgen/Android.bp_:"
msgstr ""
-#: src/android/interoperability/with-c/bindgen.md:37
-msgid ""
-"```javascript\n"
-"cc_library {\n"
-" name: \"libbirthday\",\n"
-" srcs: [\"libbirthday.c\"],\n"
-"}\n"
-"```"
+#: src/android/interoperability/with-c/bindgen.md:39
+#: src/android/interoperability/with-c/bindgen.md:63
+msgid "\"libbirthday\""
+msgstr ""
+
+#: src/android/interoperability/with-c/bindgen.md:40
+msgid "\"libbirthday.c\""
msgstr ""
#: src/android/interoperability/with-c/bindgen.md:44
@@ -13896,67 +11969,49 @@ msgstr ""
msgid "_interoperability/bindgen/libbirthday_wrapper.h_:"
msgstr "_interoperability/bindgen/libbirthday_wrapper.h_:"
-#: src/android/interoperability/with-c/bindgen.md:49
-msgid ""
-"```c\n"
-"#include \"libbirthday.h\"\n"
-"```"
-msgstr ""
-
#: src/android/interoperability/with-c/bindgen.md:53
msgid "You can now auto-generate the bindings:"
msgstr "Ahora puedes generar automáticamente los enlaces:"
-#: src/android/interoperability/with-c/bindgen.md:57
-msgid ""
-"```javascript\n"
-"rust_bindgen {\n"
-" name: \"libbirthday_bindgen\",\n"
-" crate_name: \"birthday_bindgen\",\n"
-" wrapper_src: \"libbirthday_wrapper.h\",\n"
-" source_stem: \"bindings\",\n"
-" static_libs: [\"libbirthday\"],\n"
-"}\n"
-"```"
+#: src/android/interoperability/with-c/bindgen.md:59
+#: src/android/interoperability/with-c/bindgen.md:75
+msgid "\"libbirthday_bindgen\""
+msgstr ""
+
+#: src/android/interoperability/with-c/bindgen.md:60
+#, fuzzy
+#| msgid "`rust_bindgen`"
+msgid "\"birthday_bindgen\""
+msgstr "`rust_bindgen`"
+
+#: src/android/interoperability/with-c/bindgen.md:61
+msgid "\"libbirthday_wrapper.h\""
+msgstr ""
+
+#: src/android/interoperability/with-c/bindgen.md:62
+msgid "\"bindings\""
msgstr ""
#: src/android/interoperability/with-c/bindgen.md:67
msgid "Finally, we can use the bindings in our Rust program:"
msgstr "Por último, podemos utilizar los enlaces de nuestro programa de Rust:"
-#: src/android/interoperability/with-c/bindgen.md:71
-msgid ""
-"```javascript\n"
-"rust_binary {\n"
-" name: \"print_birthday_card\",\n"
-" srcs: [\"main.rs\"],\n"
-" rustlibs: [\"libbirthday_bindgen\"],\n"
-"}\n"
-"```"
+#: src/android/interoperability/with-c/bindgen.md:73
+msgid "\"print_birthday_card\""
msgstr ""
+#: src/android/interoperability/with-c/bindgen.md:74
+#, fuzzy
+#| msgid "`main.rs`:"
+msgid "\"main.rs\""
+msgstr "`main.rs`:"
+
#: src/android/interoperability/with-c/bindgen.md:79
msgid "_interoperability/bindgen/main.rs_:"
msgstr "_interoperability/bindgen/main.rs_:"
-#: src/android/interoperability/with-c/bindgen.md:81
-msgid ""
-"```rust,compile_fail\n"
-"//! Bindgen demo.\n"
-"\n"
-"use birthday_bindgen::{card, print_card};\n"
-"\n"
-"fn main() {\n"
-" let name = std::ffi::CString::new(\"Peter\").unwrap();\n"
-" let card = card {\n"
-" name: name.as_ptr(),\n"
-" years: 42,\n"
-" };\n"
-" unsafe {\n"
-" print_card(&card as *const card);\n"
-" }\n"
-"}\n"
-"```"
+#: src/android/interoperability/with-c/bindgen.md:82
+msgid "//! Bindgen demo.\n"
msgstr ""
#: src/android/interoperability/with-c/bindgen.md:100
@@ -13975,26 +12030,26 @@ msgstr ""
"Por último, podemos ejecutar pruebas generadas automáticamente para "
"comprobar que los enlaces funcionan:"
-#: src/android/interoperability/with-c/bindgen.md:110
-msgid ""
-"```javascript\n"
-"rust_test {\n"
-" name: \"libbirthday_bindgen_test\",\n"
-" srcs: [\":libbirthday_bindgen\"],\n"
-" crate_name: \"libbirthday_bindgen_test\",\n"
-" test_suites: [\"general-tests\"],\n"
-" auto_gen_config: true,\n"
-" clippy_lints: \"none\", // Generated file, skip linting\n"
-" lints: \"none\",\n"
-"}\n"
-"```"
+#: src/android/interoperability/with-c/bindgen.md:112
+#: src/android/interoperability/with-c/bindgen.md:114
+msgid "\"libbirthday_bindgen_test\""
msgstr ""
-#: src/android/interoperability/with-c/bindgen.md:122
-msgid ""
-"```shell\n"
-"atest libbirthday_bindgen_test\n"
-"```"
+#: src/android/interoperability/with-c/bindgen.md:113
+msgid "\":libbirthday_bindgen\""
+msgstr ""
+
+#: src/android/interoperability/with-c/bindgen.md:115
+msgid "\"general-tests\""
+msgstr ""
+
+#: src/android/interoperability/with-c/bindgen.md:117
+#: src/android/interoperability/with-c/bindgen.md:118
+msgid "\"none\""
+msgstr ""
+
+#: src/android/interoperability/with-c/bindgen.md:117
+msgid "// Generated file, skip linting\n"
msgstr ""
#: src/android/interoperability/with-c/rust.md:1
@@ -14009,58 +12064,41 @@ msgstr "Es fácil exportar las funciones y los tipos de Rust a C:"
msgid "_interoperability/rust/libanalyze/analyze.rs_"
msgstr "_interoperability/rust/libanalyze/analyze.rs_"
-#: src/android/interoperability/with-c/rust.md:7
-msgid ""
-"```rust,editable\n"
-"//! Rust FFI demo.\n"
-"#![deny(improper_ctypes_definitions)]\n"
-"\n"
-"use std::os::raw::c_int;\n"
-"\n"
-"/// Analyze the numbers.\n"
-"#[no_mangle]\n"
-"pub extern \"C\" fn analyze_numbers(x: c_int, y: c_int) {\n"
-" if x < y {\n"
-" println!(\"x ({x}) is smallest!\");\n"
-" } else {\n"
-" println!(\"y ({y}) is probably larger than x ({x})\");\n"
-" }\n"
-"}\n"
-"```"
+#: src/android/interoperability/with-c/rust.md:8
+msgid "//! Rust FFI demo.\n"
+msgstr ""
+
+#: src/android/interoperability/with-c/rust.md:12
+msgid "/// Analyze the numbers.\n"
+msgstr ""
+
+#: src/android/interoperability/with-c/rust.md:17
+msgid "\"x ({x}) is smallest!\""
+msgstr ""
+
+#: src/android/interoperability/with-c/rust.md:19
+msgid "\"y ({y}) is probably larger than x ({x})\""
msgstr ""
#: src/android/interoperability/with-c/rust.md:24
msgid "_interoperability/rust/libanalyze/analyze.h_"
msgstr "_interoperability/rust/libanalyze/analyze.h_"
-#: src/android/interoperability/with-c/rust.md:26
-msgid ""
-"```c\n"
-"#ifndef ANALYSE_H\n"
-"#define ANALYSE_H\n"
-"\n"
-"extern \"C\" {\n"
-"void analyze_numbers(int x, int y);\n"
-"}\n"
-"\n"
-"#endif\n"
-"```"
-msgstr ""
-
#: src/android/interoperability/with-c/rust.md:37
msgid "_interoperability/rust/libanalyze/Android.bp_"
msgstr "_interoperability/rust/libanalyze/Android.bp_"
-#: src/android/interoperability/with-c/rust.md:39
-msgid ""
-"```javascript\n"
-"rust_ffi {\n"
-" name: \"libanalyze_ffi\",\n"
-" crate_name: \"analyze_ffi\",\n"
-" srcs: [\"analyze.rs\"],\n"
-" include_dirs: [\".\"],\n"
-"}\n"
-"```"
+#: src/android/interoperability/with-c/rust.md:41
+#: src/android/interoperability/with-c/rust.md:68
+msgid "\"libanalyze_ffi\""
+msgstr ""
+
+#: src/android/interoperability/with-c/rust.md:42
+msgid "\"analyze_ffi\""
+msgstr ""
+
+#: src/android/interoperability/with-c/rust.md:43
+msgid "\"analyze.rs\""
msgstr ""
#: src/android/interoperability/with-c/rust.md:48
@@ -14071,32 +12109,20 @@ msgstr "Ahora podemos llamarlo desde un binario de C:"
msgid "_interoperability/rust/analyze/main.c_"
msgstr "_interoperability/rust/analyze/main.c_"
-#: src/android/interoperability/with-c/rust.md:52
-msgid ""
-"```c\n"
-"#include \"analyze.h\"\n"
-"\n"
-"int main() {\n"
-" analyze_numbers(10, 20);\n"
-" analyze_numbers(123, 123);\n"
-" return 0;\n"
-"}\n"
-"```"
+#: src/android/interoperability/with-c/rust.md:53
+msgid "\"analyze.h\""
msgstr ""
#: src/android/interoperability/with-c/rust.md:62
msgid "_interoperability/rust/analyze/Android.bp_"
msgstr "_interoperability/rust/analyze/Android.bp_"
-#: src/android/interoperability/with-c/rust.md:64
-msgid ""
-"```javascript\n"
-"cc_binary {\n"
-" name: \"analyze_numbers\",\n"
-" srcs: [\"main.c\"],\n"
-" static_libs: [\"libanalyze_ffi\"],\n"
-"}\n"
-"```"
+#: src/android/interoperability/with-c/rust.md:66
+msgid "\"analyze_numbers\""
+msgstr ""
+
+#: src/android/interoperability/with-c/rust.md:67
+msgid "\"main.c\""
msgstr ""
#: src/android/interoperability/with-c/rust.md:75
@@ -14120,6 +12146,10 @@ msgstr ""
"utilizar `#[export_name = \"some_name\"]` para especificar el nombre que "
"quieras."
+#: src/android/interoperability/cpp.md:1
+msgid "With C++"
+msgstr "Con C++"
+
#: src/android/interoperability/cpp.md:3
msgid ""
"The [CXX crate](https://cxx.rs/) makes it possible to do safe "
@@ -14210,28 +12240,20 @@ msgstr "En primer lugar, creamos una función de Rust para exportar a Java:"
msgid "_interoperability/java/src/lib.rs_:"
msgstr "_interoperability/java/src/lib.rs_:"
-#: src/android/interoperability/java.md:11
-msgid ""
-"```rust,compile_fail\n"
-"//! Rust <-> Java FFI demo.\n"
-"\n"
-"use jni::objects::{JClass, JString};\n"
-"use jni::sys::jstring;\n"
-"use jni::JNIEnv;\n"
-"\n"
-"/// HelloWorld::hello method implementation.\n"
-"#[no_mangle]\n"
-"pub extern \"system\" fn Java_HelloWorld_hello(\n"
-" env: JNIEnv,\n"
-" _class: JClass,\n"
-" name: JString,\n"
-") -> jstring {\n"
-" let input: String = env.get_string(name).unwrap().into();\n"
-" let greeting = format!(\"Hello, {input}!\");\n"
-" let output = env.new_string(greeting).unwrap();\n"
-" output.into_inner()\n"
-"}\n"
-"```"
+#: src/android/interoperability/java.md:12
+msgid "//! Rust <-> Java FFI demo.\n"
+msgstr ""
+
+#: src/android/interoperability/java.md:17
+msgid "/// HelloWorld::hello method implementation.\n"
+msgstr ""
+
+#: src/android/interoperability/java.md:20
+msgid "\"system\""
+msgstr ""
+
+#: src/android/interoperability/java.md:26
+msgid "\"Hello, {input}!\""
msgstr ""
#: src/android/interoperability/java.md:32
@@ -14239,16 +12261,18 @@ msgstr ""
msgid "_interoperability/java/Android.bp_:"
msgstr "_interoperability/java/Android.bp_:"
-#: src/android/interoperability/java.md:34
-msgid ""
-"```javascript\n"
-"rust_ffi_shared {\n"
-" name: \"libhello_jni\",\n"
-" crate_name: \"hello_jni\",\n"
-" srcs: [\"src/lib.rs\"],\n"
-" rustlibs: [\"libjni\"],\n"
-"}\n"
-"```"
+#: src/android/interoperability/java.md:36
+#: src/android/interoperability/java.md:69
+msgid "\"libhello_jni\""
+msgstr ""
+
+#: src/android/interoperability/java.md:37
+#: src/android/interoperability/java.md:52
+msgid "\"hello_jni\""
+msgstr ""
+
+#: src/android/interoperability/java.md:39
+msgid "\"libjni\""
msgstr ""
#: src/android/interoperability/java.md:43
@@ -14259,49 +12283,26 @@ msgstr "Por último, podemos llamar a esta función desde Java:"
msgid "_interoperability/java/HelloWorld.java_:"
msgstr "_interoperability/java/HelloWorld.java_:"
-#: src/android/interoperability/java.md:47
-msgid ""
-"```java\n"
-"class HelloWorld {\n"
-" private static native String hello(String name);\n"
-"\n"
-" static {\n"
-" System.loadLibrary(\"hello_jni\");\n"
-" }\n"
-"\n"
-" public static void main(String[] args) {\n"
-" String output = HelloWorld.hello(\"Alice\");\n"
-" System.out.println(output);\n"
-" }\n"
-"}\n"
-"```"
+#: src/android/interoperability/java.md:66
+msgid "\"helloworld_jni\""
msgstr ""
-#: src/android/interoperability/java.md:64
-msgid ""
-"```javascript\n"
-"java_binary {\n"
-" name: \"helloworld_jni\",\n"
-" srcs: [\"HelloWorld.java\"],\n"
-" main_class: \"HelloWorld\",\n"
-" required: [\"libhello_jni\"],\n"
-"}\n"
-"```"
-msgstr ""
+#: src/android/interoperability/java.md:67
+#, fuzzy
+#| msgid "Hello World!"
+msgid "\"HelloWorld.java\""
+msgstr "¡Hola, mundo!"
+
+#: src/android/interoperability/java.md:68
+#, fuzzy
+#| msgid "Hello World!"
+msgid "\"HelloWorld\""
+msgstr "¡Hola, mundo!"
#: src/android/interoperability/java.md:73
msgid "Finally, you can build, sync, and run the binary:"
msgstr "Ahora puedes compilar, sincronizar y ejecutar el binario:"
-#: src/android/interoperability/java.md:75
-msgid ""
-"```shell\n"
-"m helloworld_jni\n"
-"adb sync # requires adb root && adb remount\n"
-"adb shell /system/bin/helloworld_jni\n"
-"```"
-msgstr ""
-
#: src/exercises/android/morning.md:3
msgid ""
"This is a group exercise: We will look at one of the projects you work with "
@@ -14388,74 +12389,16 @@ msgstr ""
"Para empezar, instala algunas de las herramientas que necesitarás más "
"adelante. En gLinux o Debian:"
-#: src/bare-metal.md:22
-msgid ""
-"```bash\n"
-"sudo apt install gcc-aarch64-linux-gnu gdb-multiarch libudev-dev picocom pkg-"
-"config qemu-system-arm\n"
-"rustup update\n"
-"rustup target add aarch64-unknown-none thumbv7em-none-eabihf\n"
-"rustup component add llvm-tools-preview\n"
-"cargo install cargo-binutils cargo-embed\n"
-"```"
-msgstr ""
-"```bash\n"
-"sudo apt install gcc-aarch64-linux-gnu gdb-multiarch libudev-dev picocom pkg-"
-"config qemu-system-arm\n"
-"rustup update\n"
-"rustup target add aarch64-unknown-none thumbv7em-none-eabihf\n"
-"rustup component add llvm-tools-preview\n"
-"cargo install cargo-binutils cargo-embed\n"
-"```"
-
#: src/bare-metal.md:30
msgid ""
"And give users in the `plugdev` group access to the micro:bit programmer:"
msgstr ""
"Permite a los usuarios del grupo `plugdev` acceder al programador micro:bit:"
-#: src/bare-metal.md:32
-msgid ""
-"```bash\n"
-"echo 'SUBSYSTEM==\"usb\", ATTR{idVendor}==\"0d28\", MODE=\"0664\", "
-"GROUP=\"plugdev\"' |\\\n"
-" sudo tee /etc/udev/rules.d/50-microbit.rules\n"
-"sudo udevadm control --reload-rules\n"
-"```"
-msgstr ""
-"```bash\n"
-"echo 'SUBSYSTEM==\"usb\", ATTR{idVendor}==\"0d28\", MODE=\"0664\", "
-"GROUP=\"plugdev\"' |\\\n"
-" sudo tee /etc/udev/rules.d/50-microbit.rules\n"
-"sudo udevadm control --reload-rules\n"
-"```"
-
-#: src/bare-metal.md:38
+#: src/bare-metal.md:38 src/bare-metal/microcontrollers/debugging.md:27
msgid "On MacOS:"
msgstr "En MacOS:"
-#: src/bare-metal.md:40
-msgid ""
-"```bash\n"
-"xcode-select --install\n"
-"brew install gdb picocom qemu\n"
-"brew install --cask gcc-aarch64-embedded\n"
-"rustup update\n"
-"rustup target add aarch64-unknown-none thumbv7em-none-eabihf\n"
-"rustup component add llvm-tools-preview\n"
-"cargo install cargo-binutils cargo-embed\n"
-"```"
-msgstr ""
-"```bash\n"
-"xcode-select --install\n"
-"brew install gdb picocom qemu\n"
-"brew install --cask gcc-aarch64-embedded\n"
-"rustup update\n"
-"rustup target add aarch64-unknown-none thumbv7em-none-eabihf\n"
-"rustup component add llvm-tools-preview\n"
-"cargo install cargo-binutils cargo-embed\n"
-"```"
-
#: src/bare-metal/no_std.md:1
msgid "`no_std`"
msgstr "`no_std`"
@@ -14568,32 +12511,6 @@ msgstr "`std` vuelve a exportar el contenido de `core` y `alloc`."
msgid "A minimal `no_std` program"
msgstr "Un programa `no_std` mínimo"
-#: src/bare-metal/minimal.md:3
-msgid ""
-"```rust,editable,compile_fail\n"
-"#![no_main]\n"
-"#![no_std]\n"
-"\n"
-"use core::panic::PanicInfo;\n"
-"\n"
-"#[panic_handler]\n"
-"fn panic(_panic: &PanicInfo) -> ! {\n"
-" loop {}\n"
-"}\n"
-"```"
-msgstr ""
-"```rust,editable,compile_fail\n"
-"#![no_main]\n"
-"#![no_std]\n"
-"\n"
-"use core::panic::PanicInfo;\n"
-"\n"
-"#[panic_handler]\n"
-"fn panic(_panic: &PanicInfo) -> ! {\n"
-" loop {}\n"
-"}\n"
-"```"
-
#: src/bare-metal/minimal.md:17
msgid "This will compile to an empty binary."
msgstr "Se compilará en un binario vacío."
@@ -14635,71 +12552,24 @@ msgstr ""
"Para utilizar `alloc`, debes implementar un [asignador global (de _heap_)]"
"(https://doc.rust-lang.org/stable/std/alloc/trait.GlobalAlloc.html)."
-#: src/bare-metal/alloc.md:6
+#: src/bare-metal/alloc.md:23
msgid ""
-"```rust,editable,compile_fail\n"
-"#![no_main]\n"
-"#![no_std]\n"
-"\n"
-"extern crate alloc;\n"
-"extern crate panic_halt as _;\n"
-"\n"
-"use alloc::string::ToString;\n"
-"use alloc::vec::Vec;\n"
-"use buddy_system_allocator::LockedHeap;\n"
-"\n"
-"#[global_allocator]\n"
-"static HEAP_ALLOCATOR: LockedHeap<32> = LockedHeap::<32>::new();\n"
-"\n"
-"static mut HEAP: [u8; 65536] = [0; 65536];\n"
-"\n"
-"pub fn entry() {\n"
-" // Safe because `HEAP` is only used here and `entry` is only called "
-"once.\n"
-" unsafe {\n"
-" // Give the allocator some memory to allocate.\n"
-" HEAP_ALLOCATOR\n"
-" .lock()\n"
-" .init(HEAP.as_mut_ptr() as usize, HEAP.len());\n"
-" }\n"
-"\n"
-" // Now we can do things that require heap allocation.\n"
-" let mut v = Vec::new();\n"
-" v.push(\"A string\".to_string());\n"
-"}\n"
-"```"
+"// Safe because `HEAP` is only used here and `entry` is only called once.\n"
+msgstr ""
+
+#: src/bare-metal/alloc.md:25
+msgid "// Give the allocator some memory to allocate.\n"
+msgstr ""
+
+#: src/bare-metal/alloc.md:31
+msgid "// Now we can do things that require heap allocation.\n"
msgstr ""
-"```rust,editable,compile_fail\n"
-"#![no_main]\n"
-"#![no_std]\n"
-"\n"
-"extern crate alloc;\n"
-"extern crate panic_halt as _;\n"
-"\n"
-"use alloc::string::ToString;\n"
-"use alloc::vec::Vec;\n"
-"use buddy_system_allocator::LockedHeap;\n"
-"\n"
-"#[global_allocator]\n"
-"static HEAP_ALLOCATOR: LockedHeap<32> = LockedHeap::<32>::new();\n"
-"\n"
-"static mut HEAP: [u8; 65536] = [0; 65536];\n"
-"\n"
-"pub fn entry() {\n"
-" // Safe because `HEAP` is only used here and `entry` is only called "
-"once.\n"
-" unsafe {\n"
-" // Give the allocator some memory to allocate.\n"
-" HEAP_ALLOCATOR\n"
-" .lock()\n"
-" .init(HEAP.as_mut_ptr() as usize, HEAP.len());\n"
-" }\n"
-"\n"
-" // Ahora podemos hacer cosas que requieran asignación de _heap_.\n"
-" let mut v = Vec::new();\n"
-" v.push(\"A string\".to_string());\n"
-"}\n"
-"```"
+
+#: src/bare-metal/alloc.md:33
+#, fuzzy
+#| msgid "String"
+msgid "\"A string\""
+msgstr "String"
#: src/bare-metal/alloc.md:39
msgid ""
@@ -14752,25 +12622,6 @@ msgstr ""
"El crate `cortex_m_rt` proporciona (entre otras cosas) un controlador de "
"reinicio para microcontroladores Cortex M."
-#: src/bare-metal/microcontrollers.md:5
-msgid ""
-"```rust,editable,compile_fail\n"
-"#![no_main]\n"
-"#![no_std]\n"
-"\n"
-"extern crate panic_halt as _;\n"
-"\n"
-"mod interrupts;\n"
-"\n"
-"use cortex_m_rt::entry;\n"
-"\n"
-"#[entry]\n"
-"fn main() -> ! {\n"
-" loop {}\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/bare-metal/microcontrollers.md:21
msgid ""
"Next we'll look at how to access peripherals, with increasing levels of "
@@ -14800,69 +12651,35 @@ msgstr ""
"S asignada a la memoria. Vamos a probar a encender un LED en nuestro micro:"
"bit:"
-#: src/bare-metal/microcontrollers/mmio.md:6
+#: src/bare-metal/microcontrollers/mmio.md:16
+msgid "/// GPIO port 0 peripheral address\n"
+msgstr ""
+
+#: src/bare-metal/microcontrollers/mmio.md:19
+msgid "// GPIO peripheral offsets\n"
+msgstr ""
+
+#: src/bare-metal/microcontrollers/mmio.md:24
+msgid "// PIN_CNF fields\n"
+msgstr ""
+
+#: src/bare-metal/microcontrollers/mmio.md:34
+#: src/bare-metal/microcontrollers/pacs.md:21
+#: src/bare-metal/microcontrollers/hals.md:25
+msgid "// Configure GPIO 0 pins 21 and 28 as push-pull outputs.\n"
+msgstr ""
+
+#: src/bare-metal/microcontrollers/mmio.md:37
+#: src/bare-metal/microcontrollers/mmio.md:51
msgid ""
-"```rust,editable,compile_fail\n"
-"#![no_main]\n"
-"#![no_std]\n"
-"\n"
-"extern crate panic_halt as _;\n"
-"\n"
-"mod interrupts;\n"
-"\n"
-"use core::mem::size_of;\n"
-"use cortex_m_rt::entry;\n"
-"\n"
-"/// GPIO port 0 peripheral address\n"
-"const GPIO_P0: usize = 0x5000_0000;\n"
-"\n"
-"// GPIO peripheral offsets\n"
-"const PIN_CNF: usize = 0x700;\n"
-"const OUTSET: usize = 0x508;\n"
-"const OUTCLR: usize = 0x50c;\n"
-"\n"
-"// PIN_CNF fields\n"
-"const DIR_OUTPUT: u32 = 0x1;\n"
-"const INPUT_DISCONNECT: u32 = 0x1 << 1;\n"
-"const PULL_DISABLED: u32 = 0x0 << 2;\n"
-"const DRIVE_S0S1: u32 = 0x0 << 8;\n"
-"const SENSE_DISABLED: u32 = 0x0 << 16;\n"
-"\n"
-"#[entry]\n"
-"fn main() -> ! {\n"
-" // Configure GPIO 0 pins 21 and 28 as push-pull outputs.\n"
-" let pin_cnf_21 = (GPIO_P0 + PIN_CNF + 21 * size_of::()) as *mut "
-"u32;\n"
-" let pin_cnf_28 = (GPIO_P0 + PIN_CNF + 28 * size_of::()) as *mut "
-"u32;\n"
-" // Safe because the pointers are to valid peripheral control registers, "
-"and\n"
-" // no aliases exist.\n"
-" unsafe {\n"
-" pin_cnf_21.write_volatile(\n"
-" DIR_OUTPUT | INPUT_DISCONNECT | PULL_DISABLED | DRIVE_S0S1 | "
-"SENSE_DISABLED,\n"
-" );\n"
-" pin_cnf_28.write_volatile(\n"
-" DIR_OUTPUT | INPUT_DISCONNECT | PULL_DISABLED | DRIVE_S0S1 | "
-"SENSE_DISABLED,\n"
-" );\n"
-" }\n"
-"\n"
-" // Set pin 28 low and pin 21 high to turn the LED on.\n"
-" let gpio0_outset = (GPIO_P0 + OUTSET) as *mut u32;\n"
-" let gpio0_outclr = (GPIO_P0 + OUTCLR) as *mut u32;\n"
-" // Safe because the pointers are to valid peripheral control registers, "
-"and\n"
+"// Safe because the pointers are to valid peripheral control registers, and\n"
" // no aliases exist.\n"
-" unsafe {\n"
-" gpio0_outclr.write_volatile(1 << 28);\n"
-" gpio0_outset.write_volatile(1 << 21);\n"
-" }\n"
-"\n"
-" loop {}\n"
-"}\n"
-"```"
+msgstr ""
+
+#: src/bare-metal/microcontrollers/mmio.md:48
+#: src/bare-metal/microcontrollers/pacs.md:39
+#: src/bare-metal/microcontrollers/hals.md:29
+msgid "// Set pin 28 low and pin 21 high to turn the LED on.\n"
msgstr ""
#: src/bare-metal/microcontrollers/mmio.md:64
@@ -14880,13 +12697,6 @@ msgstr ""
msgid "Run the example with:"
msgstr "Ejecuta el ejemplo con:"
-#: src/bare-metal/microcontrollers/mmio.md:68
-msgid ""
-"```sh\n"
-"cargo embed --bin mmio\n"
-"```"
-msgstr ""
-
#: src/bare-metal/microcontrollers/pacs.md:1
msgid "Peripheral Access Crates"
msgstr "Crates de Acceso Periférico"
@@ -14902,49 +12712,6 @@ msgstr ""
"de archivos [CMSIS-SVD](https://www.keil.com/pack/doc/CMSIS/SVD/html/index."
"html)."
-#: src/bare-metal/microcontrollers/pacs.md:7
-msgid ""
-"```rust,editable,compile_fail\n"
-"#![no_main]\n"
-"#![no_std]\n"
-"\n"
-"extern crate panic_halt as _;\n"
-"\n"
-"use cortex_m_rt::entry;\n"
-"use nrf52833_pac::Peripherals;\n"
-"\n"
-"#[entry]\n"
-"fn main() -> ! {\n"
-" let p = Peripherals::take().unwrap();\n"
-" let gpio0 = p.P0;\n"
-"\n"
-" // Configure GPIO 0 pins 21 and 28 as push-pull outputs.\n"
-" gpio0.pin_cnf[21].write(|w| {\n"
-" w.dir().output();\n"
-" w.input().disconnect();\n"
-" w.pull().disabled();\n"
-" w.drive().s0s1();\n"
-" w.sense().disabled();\n"
-" w\n"
-" });\n"
-" gpio0.pin_cnf[28].write(|w| {\n"
-" w.dir().output();\n"
-" w.input().disconnect();\n"
-" w.pull().disabled();\n"
-" w.drive().s0s1();\n"
-" w.sense().disabled();\n"
-" w\n"
-" });\n"
-"\n"
-" // Set pin 28 low and pin 21 high to turn the LED on.\n"
-" gpio0.outclr.write(|w| w.pin28().clear());\n"
-" gpio0.outset.write(|w| w.pin21().set());\n"
-"\n"
-" loop {}\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/bare-metal/microcontrollers/pacs.md:49
msgid ""
"SVD (System View Description) files are XML files typically provided by "
@@ -14984,13 +12751,6 @@ msgstr ""
"Si instalas `cargo install cargo-binutils` puedes ejecutar `cargo objdump --"
"bin pac -- -d --no-show-raw-insn` para ver el binario resultante."
-#: src/bare-metal/microcontrollers/pacs.md:61
-msgid ""
-"```sh\n"
-"cargo embed --bin pac\n"
-"```"
-msgstr ""
-
#: src/bare-metal/microcontrollers/hals.md:1
msgid "HAL crates"
msgstr "Crates HAL"
@@ -15007,37 +12767,8 @@ msgstr ""
"alrededor de varios periféricos. Por lo general, implementan traits de "
"[`embedded-hal`](https://crates.io/crates/embedded-hal)."
-#: src/bare-metal/microcontrollers/hals.md:7
-msgid ""
-"```rust,editable,compile_fail\n"
-"#![no_main]\n"
-"#![no_std]\n"
-"\n"
-"extern crate panic_halt as _;\n"
-"\n"
-"use cortex_m_rt::entry;\n"
-"use nrf52833_hal::gpio::{p0, Level};\n"
-"use nrf52833_hal::pac::Peripherals;\n"
-"use nrf52833_hal::prelude::*;\n"
-"\n"
-"#[entry]\n"
-"fn main() -> ! {\n"
-" let p = Peripherals::take().unwrap();\n"
-"\n"
-" // Create HAL wrapper for GPIO port 0.\n"
-" let gpio0 = p0::Parts::new(p.P0);\n"
-"\n"
-" // Configure GPIO 0 pins 21 and 28 as push-pull outputs.\n"
-" let mut col1 = gpio0.p0_28.into_push_pull_output(Level::High);\n"
-" let mut row1 = gpio0.p0_21.into_push_pull_output(Level::Low);\n"
-"\n"
-" // Set pin 28 low and pin 21 high to turn the LED on.\n"
-" col1.set_low().unwrap();\n"
-" row1.set_high().unwrap();\n"
-"\n"
-" loop {}\n"
-"}\n"
-"```"
+#: src/bare-metal/microcontrollers/hals.md:22
+msgid "// Create HAL wrapper for GPIO port 0.\n"
msgstr ""
#: src/bare-metal/microcontrollers/hals.md:39
@@ -15054,13 +12785,6 @@ msgstr ""
"Hay crates HAL para muchos dispositivos Cortex-M y RISC-V, incluidos varios "
"microcontroladores STM32, GD32, nRF, NXP, MSP430, AVR y PIC."
-#: src/bare-metal/microcontrollers/hals.md:45
-msgid ""
-"```sh\n"
-"cargo embed --bin hal\n"
-"```"
-msgstr ""
-
#: src/bare-metal/microcontrollers/board-support.md:1
msgid "Board support crates"
msgstr "Crates de compatibilidad de placa"
@@ -15073,30 +12797,6 @@ msgstr ""
"Los crates de compatibilidad de placa proporcionan un nivel adicional de "
"envoltorio a una placa específica para mayor comodidad."
-#: src/bare-metal/microcontrollers/board-support.md:5
-msgid ""
-"```rust,editable,compile_fail\n"
-"#![no_main]\n"
-"#![no_std]\n"
-"\n"
-"extern crate panic_halt as _;\n"
-"\n"
-"use cortex_m_rt::entry;\n"
-"use microbit::hal::prelude::*;\n"
-"use microbit::Board;\n"
-"\n"
-"#[entry]\n"
-"fn main() -> ! {\n"
-" let mut board = Board::take().unwrap();\n"
-"\n"
-" board.display_pins.col1.set_low().unwrap();\n"
-" board.display_pins.row1.set_high().unwrap();\n"
-"\n"
-" loop {}\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/bare-metal/microcontrollers/board-support.md:28
msgid ""
"In this case the board support crate is just providing more useful names, "
@@ -15117,48 +12817,16 @@ msgstr ""
msgid "`microbit-v2` includes a simple driver for the LED matrix."
msgstr "`microbit-v2` incluye un controlador sencillo para la matriz de LED."
-#: src/bare-metal/microcontrollers/board-support.md:36
-msgid ""
-"```sh\n"
-"cargo embed --bin board_support\n"
-"```"
-msgstr ""
-
#: src/bare-metal/microcontrollers/type-state.md:1
msgid "The type state pattern"
msgstr "El patrón de tipo de estado"
-#: src/bare-metal/microcontrollers/type-state.md:3
-msgid ""
-"```rust,editable,compile_fail\n"
-"#[entry]\n"
-"fn main() -> ! {\n"
-" let p = Peripherals::take().unwrap();\n"
-" let gpio0 = p0::Parts::new(p.P0);\n"
-"\n"
-" let pin: P0_01 = gpio0.p0_01;\n"
-"\n"
-" // let gpio0_01_again = gpio0.p0_01; // Error, moved.\n"
-" let pin_input: P0_01 > = pin.into_floating_input();\n"
-" if pin_input.is_high().unwrap() {\n"
-" // ...\n"
-" }\n"
-" let mut pin_output: P0_01> = pin_input\n"
-" .into_open_drain_output(OpenDrainConfig::Disconnect0Standard1, "
-"Level::Low);\n"
-" pin_output.set_high().unwrap();\n"
-" // pin_input.is_high(); // Error, moved.\n"
-"\n"
-" let _pin2: P0_02> = gpio0\n"
-" .p0_02\n"
-" .into_open_drain_output(OpenDrainConfig::Disconnect0Standard1, "
-"Level::Low);\n"
-" let _pin3: P0_03> = gpio0.p0_03."
-"into_push_pull_output(Level::Low);\n"
-"\n"
-" loop {}\n"
-"}\n"
-"```"
+#: src/bare-metal/microcontrollers/type-state.md:11
+msgid "// let gpio0_01_again = gpio0.p0_01; // Error, moved.\n"
+msgstr ""
+
+#: src/bare-metal/microcontrollers/type-state.md:19
+msgid "// pin_input.is_high(); // Error, moved.\n"
msgstr ""
#: src/bare-metal/microcontrollers/type-state.md:32
@@ -15281,43 +12949,29 @@ msgstr ""
"integradas muy útil, como OpenOCD, pero mejor integrado."
#: src/bare-metal/microcontrollers/probe-rs.md:6
-msgid "SWD"
-msgstr "SWD"
-
-#: src/bare-metal/microcontrollers/probe-rs.md:6
-msgid " and JTAG via CMSIS-DAP, ST-Link and J-Link probes"
+#, fuzzy
+#| msgid " and JTAG via CMSIS-DAP, ST-Link and J-Link probes"
+msgid ""
+"SWD (Serial Wire Debug) and JTAG via CMSIS-DAP, ST-Link and J-Link probes"
msgstr " y JTAG a través de comprobaciones CMSIS-DAP, ST-Link y J-Link"
#: src/bare-metal/microcontrollers/probe-rs.md:7
-msgid "GDB stub and Microsoft "
-msgstr "GDB stub y el servidor "
-
-#: src/bare-metal/microcontrollers/probe-rs.md:7
-msgid "DAP"
-msgstr "DAP"
-
-#: src/bare-metal/microcontrollers/probe-rs.md:7
-msgid " server"
-msgstr " de Microsoft"
+msgid "GDB stub and Microsoft DAP (Debug Adapter Protocol) server"
+msgstr ""
#: src/bare-metal/microcontrollers/probe-rs.md:8
msgid "Cargo integration"
msgstr "Integración de Cargo"
#: src/bare-metal/microcontrollers/probe-rs.md:10
-msgid "`cargo-embed` is a cargo subcommand to build and flash binaries, log "
-msgstr ""
-"`cargo-embed` es un subcomando de Cargo para compilar e instalar binarios, "
-"registrar salidas "
-
-#: src/bare-metal/microcontrollers/probe-rs.md:11
-msgid "RTT"
-msgstr "TTR"
-
-#: src/bare-metal/microcontrollers/probe-rs.md:11
+#, fuzzy
+#| msgid ""
+#| " output and connect GDB. It's configured by an `Embed.toml` file in your "
+#| "project directory."
msgid ""
-" output and connect GDB. It's configured by an `Embed.toml` file in your "
-"project directory."
+"`cargo-embed` is a cargo subcommand to build and flash binaries, log RTT "
+"(Real Time Transfers) output and connect GDB. It's configured by an `Embed."
+"toml` file in your project directory."
msgstr ""
" y conectar GDB. Se configura mediante un archivo `Embed.toml` en el "
"directorio del proyecto."
@@ -15382,59 +13036,27 @@ msgstr ""
"circulares."
#: src/bare-metal/microcontrollers/debugging.md:3
-msgid "Embed.toml:"
+#, fuzzy
+#| msgid "Embed.toml:"
+msgid "_Embed.toml_:"
msgstr "Embed.toml:"
-#: src/bare-metal/microcontrollers/debugging.md:5
-msgid ""
-"```toml\n"
-"[default.general]\n"
-"chip = \"nrf52833_xxAA\"\n"
-"\n"
-"[debug.gdb]\n"
-"enabled = true\n"
-"```"
-msgstr ""
-
#: src/bare-metal/microcontrollers/debugging.md:13
msgid "In one terminal under `src/bare-metal/microcontrollers/examples/`:"
msgstr "En un terminal en `src/bare-metal/microcontrollers/examples/`:"
-#: src/bare-metal/microcontrollers/debugging.md:15
-msgid ""
-"```sh\n"
-"cargo embed --bin board_support debug\n"
-"```"
-msgstr ""
-
#: src/bare-metal/microcontrollers/debugging.md:19
msgid "In another terminal in the same directory:"
msgstr "En otro terminal del mismo directorio:"
#: src/bare-metal/microcontrollers/debugging.md:21
-msgid ""
-"```sh\n"
-"gdb-multiarch target/thumbv7em-none-eabihf/debug/board_support --eval-"
-"command=\"target remote :1337\"\n"
-"```"
+msgid "On gLinux or Debian:"
msgstr ""
-#: src/bare-metal/microcontrollers/debugging.md:27
+#: src/bare-metal/microcontrollers/debugging.md:34
msgid "In GDB, try running:"
msgstr "En GDB, prueba a ejecutar:"
-#: src/bare-metal/microcontrollers/debugging.md:29
-msgid ""
-"```gdb\n"
-"b src/bin/board_support.rs:29\n"
-"b src/bin/board_support.rs:30\n"
-"b src/bin/board_support.rs:32\n"
-"c\n"
-"c\n"
-"c\n"
-"```"
-msgstr ""
-
#: src/bare-metal/microcontrollers/other-projects.md:1
#: src/bare-metal/aps/other-projects.md:1
msgid "Other projects"
@@ -15620,114 +13242,55 @@ msgstr ""
"y busca los siguientes archivos en el directorio `compass`."
#: src/exercises/bare-metal/compass.md:26 src/exercises/bare-metal/rtc.md:19
-msgid "`src/main.rs`:"
+#, fuzzy
+#| msgid "`src/main.rs`:"
+msgid "_src/main.rs_:"
msgstr "`src/main.rs`:"
-#: src/exercises/bare-metal/compass.md:30
+#: src/exercises/bare-metal/compass.md:44
+#: src/exercises/bare-metal/solutions-morning.md:32
+msgid "// Configure serial port.\n"
+msgstr ""
+
+#: src/exercises/bare-metal/compass.md:52
msgid ""
-"```rust,compile_fail\n"
-"#![no_main]\n"
-"#![no_std]\n"
-"\n"
-"extern crate panic_halt as _;\n"
-"\n"
-"use core::fmt::Write;\n"
-"use cortex_m_rt::entry;\n"
-"use microbit::{hal::uarte::{Baudrate, Parity, Uarte}, Board};\n"
-"\n"
-"#[entry]\n"
-"fn main() -> ! {\n"
-" let board = Board::take().unwrap();\n"
-"\n"
-" // Configure serial port.\n"
-" let mut serial = Uarte::new(\n"
-" board.UARTE0,\n"
-" board.uart.into(),\n"
-" Parity::EXCLUDED,\n"
-" Baudrate::BAUD115200,\n"
-" );\n"
-"\n"
-" // Set up the I2C controller and Inertial Measurement Unit.\n"
+"// Set up the I2C controller and Inertial Measurement Unit.\n"
" // TODO\n"
-"\n"
-" writeln!(serial, \"Ready.\").unwrap();\n"
-"\n"
-" loop {\n"
-" // Read compass data and log it to the serial port.\n"
-" // TODO\n"
-" }\n"
-"}\n"
-"```"
msgstr ""
-#: src/exercises/bare-metal/compass.md:64 src/exercises/bare-metal/rtc.md:385
-msgid "`Cargo.toml` (you shouldn't need to change this):"
-msgstr "`Cargo.toml` (no debería ser necesario cambiarlo):"
+#: src/exercises/bare-metal/compass.md:55
+#: src/exercises/bare-metal/solutions-morning.md:56
+msgid "\"Ready.\""
+msgstr ""
-#: src/exercises/bare-metal/compass.md:68
+#: src/exercises/bare-metal/compass.md:58
msgid ""
-"```toml\n"
-"[workspace]\n"
-"\n"
-"[package]\n"
-"name = \"compass\"\n"
-"version = \"0.1.0\"\n"
-"edition = \"2021\"\n"
-"publish = false\n"
-"\n"
-"[dependencies]\n"
-"cortex-m-rt = \"0.7.3\"\n"
-"embedded-hal = \"0.2.6\"\n"
-"lsm303agr = \"0.2.2\"\n"
-"microbit-v2 = \"0.13.0\"\n"
-"panic-halt = \"0.2.0\"\n"
-"```"
+"// Read compass data and log it to the serial port.\n"
+" // TODO\n"
msgstr ""
+#: src/exercises/bare-metal/compass.md:64 src/exercises/bare-metal/rtc.md:385
+#, fuzzy
+#| msgid "`Cargo.toml` (you shouldn't need to change this):"
+msgid "_Cargo.toml_ (you shouldn't need to change this):"
+msgstr "`Cargo.toml` (no debería ser necesario cambiarlo):"
+
#: src/exercises/bare-metal/compass.md:85
-msgid "`Embed.toml` (you shouldn't need to change this):"
+#, fuzzy
+#| msgid "`Embed.toml` (you shouldn't need to change this):"
+msgid "_Embed.toml_ (you shouldn't need to change this):"
msgstr "`Embed.toml` (no debería ser necesario cambiarlo):"
-#: src/exercises/bare-metal/compass.md:89
-msgid ""
-"```toml\n"
-"[default.general]\n"
-"chip = \"nrf52833_xxAA\"\n"
-"\n"
-"[debug.gdb]\n"
-"enabled = true\n"
-"\n"
-"[debug.reset]\n"
-"halt_afterwards = true\n"
-"```"
-msgstr ""
-
#: src/exercises/bare-metal/compass.md:100 src/exercises/bare-metal/rtc.md:985
-msgid "`.cargo/config.toml` (you shouldn't need to change this):"
+#, fuzzy
+#| msgid "`.cargo/config.toml` (you shouldn't need to change this):"
+msgid "_.cargo/config.toml_ (you shouldn't need to change this):"
msgstr "`.cargo/config.toml` (no debería ser necesario cambiarlo):"
-#: src/exercises/bare-metal/compass.md:104
-msgid ""
-"```toml\n"
-"[build]\n"
-"target = \"thumbv7em-none-eabihf\" # Cortex-M4F\n"
-"\n"
-"[target.'cfg(all(target_arch = \"arm\", target_os = \"none\"))']\n"
-"rustflags = [\"-C\", \"link-arg=-Tlink.x\"]\n"
-"```"
-msgstr ""
-
#: src/exercises/bare-metal/compass.md:112
msgid "See the serial output on Linux with:"
msgstr "Consulta la salida de serie en Linux con:"
-#: src/exercises/bare-metal/compass.md:114
-msgid ""
-"```sh\n"
-"picocom --baud 115200 --imap lfcrlf /dev/ttyACM0\n"
-"```"
-msgstr ""
-
#: src/exercises/bare-metal/compass.md:118
msgid ""
"Or on Mac OS something like (the device name may be slightly different):"
@@ -15735,13 +13298,6 @@ msgstr ""
"En Mac OS debería ser algo como lo siguiente (el nombre del dispositivo "
"puede ser algo diferente):"
-#: src/exercises/bare-metal/compass.md:120
-msgid ""
-"```sh\n"
-"picocom --baud 115200 --imap lfcrlf /dev/tty.usbmodem14502\n"
-"```"
-msgstr ""
-
#: src/exercises/bare-metal/compass.md:124
msgid "Use Ctrl+A Ctrl+Q to quit picocom."
msgstr "Pulsa Ctrl+A Ctrl+Q para salir de Picocom."
@@ -15969,58 +13525,61 @@ msgid "Inline assembly"
msgstr "Ensamblaje integrado"
#: src/bare-metal/aps/inline-assembly.md:3
+#, fuzzy
+#| msgid ""
+#| "Sometimes we need to use assembly to do things that aren't possible with "
+#| "Rust code. For example, to make an "
msgid ""
"Sometimes we need to use assembly to do things that aren't possible with "
-"Rust code. For example, to make an "
+"Rust code. For example, to make an HVC (hypervisor call) to tell the "
+"firmware to power off the system:"
msgstr ""
"A veces necesitamos usar el ensamblador para hacer cosas que no son posibles "
"con código Rust. Por ejemplo, hacer un "
-#: src/bare-metal/aps/inline-assembly.md:4
-msgid "HVC"
-msgstr "HVC"
-
-#: src/bare-metal/aps/inline-assembly.md:4
-msgid " to tell the firmware to power off the system:"
-msgstr " para decirle al firmware que apague el sistema:"
-
-#: src/bare-metal/aps/inline-assembly.md:6
+#: src/bare-metal/aps/inline-assembly.md:19
msgid ""
-"```rust,editable,compile_fail\n"
-"#![no_main]\n"
-"#![no_std]\n"
-"\n"
-"use core::arch::asm;\n"
-"use core::panic::PanicInfo;\n"
-"\n"
-"mod exceptions;\n"
-"\n"
-"const PSCI_SYSTEM_OFF: u32 = 0x84000008;\n"
-"\n"
-"#[no_mangle]\n"
-"extern \"C\" fn main(_x0: u64, _x1: u64, _x2: u64, _x3: u64) {\n"
-" // Safe because this only uses the declared registers and doesn't do\n"
+"// Safe because this only uses the declared registers and doesn't do\n"
" // anything with memory.\n"
-" unsafe {\n"
-" asm!(\"hvc #0\",\n"
-" inout(\"w0\") PSCI_SYSTEM_OFF => _,\n"
-" inout(\"w1\") 0 => _,\n"
-" inout(\"w2\") 0 => _,\n"
-" inout(\"w3\") 0 => _,\n"
-" inout(\"w4\") 0 => _,\n"
-" inout(\"w5\") 0 => _,\n"
-" inout(\"w6\") 0 => _,\n"
-" inout(\"w7\") 0 => _,\n"
-" options(nomem, nostack)\n"
-" );\n"
-" }\n"
-"\n"
-" loop {}\n"
-"}\n"
-"```"
msgstr ""
-#: src/bare-metal/aps/inline-assembly.md:39
+#: src/bare-metal/aps/inline-assembly.md:22
+msgid "\"hvc #0\""
+msgstr ""
+
+#: src/bare-metal/aps/inline-assembly.md:23
+msgid "\"w0\""
+msgstr ""
+
+#: src/bare-metal/aps/inline-assembly.md:24
+msgid "\"w1\""
+msgstr ""
+
+#: src/bare-metal/aps/inline-assembly.md:25
+msgid "\"w2\""
+msgstr ""
+
+#: src/bare-metal/aps/inline-assembly.md:26
+msgid "\"w3\""
+msgstr ""
+
+#: src/bare-metal/aps/inline-assembly.md:27
+msgid "\"w4\""
+msgstr ""
+
+#: src/bare-metal/aps/inline-assembly.md:28
+msgid "\"w5\""
+msgstr ""
+
+#: src/bare-metal/aps/inline-assembly.md:29
+msgid "\"w6\""
+msgstr ""
+
+#: src/bare-metal/aps/inline-assembly.md:30
+msgid "\"w7\""
+msgstr ""
+
+#: src/bare-metal/aps/inline-assembly.md:39
msgid ""
"(If you actually want to do this, use the [`smccc`](https://crates.io/crates/"
"smccc) crate which has wrappers for all these functions.)"
@@ -16154,22 +13713,13 @@ msgstr ""
"La máquina \"virt\" de QEMU tiene una UART [PL011]https://developer.arm.com/"
"documentation/ddi0183/g), así que vamos a escribir un controlador para ella."
-#: src/bare-metal/aps/uart.md:5
+#: src/bare-metal/aps/uart.md:9
+msgid "/// Minimal driver for a PL011 UART.\n"
+msgstr ""
+
+#: src/bare-metal/aps/uart.md:17 src/bare-metal/aps/better-uart/driver.md:13
msgid ""
-"```rust,editable\n"
-"const FLAG_REGISTER_OFFSET: usize = 0x18;\n"
-"const FR_BUSY: u8 = 1 << 3;\n"
-"const FR_TXFF: u8 = 1 << 5;\n"
-"\n"
-"/// Minimal driver for a PL011 UART.\n"
-"#[derive(Debug)]\n"
-"pub struct Uart {\n"
-" base_address: *mut u8,\n"
-"}\n"
-"\n"
-"impl Uart {\n"
-" /// Constructs a new instance of the UART driver for a PL011 device at "
-"the\n"
+"/// Constructs a new instance of the UART driver for a PL011 device at the\n"
" /// given base address.\n"
" ///\n"
" /// # Safety\n"
@@ -16179,34 +13729,32 @@ msgid ""
" /// PL011 device, which must be mapped into the address space of the "
"process\n"
" /// as device memory and not have any other aliases.\n"
-" pub unsafe fn new(base_address: *mut u8) -> Self {\n"
-" Self { base_address }\n"
-" }\n"
-"\n"
-" /// Writes a single byte to the UART.\n"
-" pub fn write_byte(&self, byte: u8) {\n"
-" // Wait until there is room in the TX buffer.\n"
-" while self.read_flag_register() & FR_TXFF != 0 {}\n"
-"\n"
-" // Safe because we know that the base address points to the control\n"
-" // registers of a PL011 device which is appropriately mapped.\n"
-" unsafe {\n"
-" // Write to the TX buffer.\n"
-" self.base_address.write_volatile(byte);\n"
-" }\n"
-"\n"
-" // Wait until the UART is no longer busy.\n"
-" while self.read_flag_register() & FR_BUSY != 0 {}\n"
-" }\n"
-"\n"
-" fn read_flag_register(&self) -> u8 {\n"
-" // Safe because we know that the base address points to the control\n"
+msgstr ""
+
+#: src/bare-metal/aps/uart.md:29 src/bare-metal/aps/better-uart/driver.md:27
+#: src/exercises/bare-metal/rtc.md:336
+msgid "/// Writes a single byte to the UART.\n"
+msgstr ""
+
+#: src/bare-metal/aps/uart.md:31 src/bare-metal/aps/better-uart/driver.md:29
+#: src/exercises/bare-metal/rtc.md:338
+msgid "// Wait until there is room in the TX buffer.\n"
+msgstr ""
+
+#: src/bare-metal/aps/uart.md:34 src/bare-metal/aps/uart.md:46
+msgid ""
+"// Safe because we know that the base address points to the control\n"
" // registers of a PL011 device which is appropriately mapped.\n"
-" unsafe { self.base_address.add(FLAG_REGISTER_OFFSET)."
-"read_volatile() }\n"
-" }\n"
-"}\n"
-"```"
+msgstr ""
+
+#: src/bare-metal/aps/uart.md:37 src/bare-metal/aps/better-uart/driver.md:35
+#: src/exercises/bare-metal/rtc.md:344
+msgid "// Write to the TX buffer.\n"
+msgstr ""
+
+#: src/bare-metal/aps/uart.md:41 src/bare-metal/aps/better-uart/driver.md:39
+#: src/exercises/bare-metal/rtc.md:348
+msgid "// Wait until the UART is no longer busy.\n"
msgstr ""
#: src/bare-metal/aps/uart.md:55
@@ -16258,24 +13806,11 @@ msgstr ""
"Hemos derivado el trait `Debug`. También sería útil implementar algunos "
"traits más."
-#: src/bare-metal/aps/uart/traits.md:5
+#: src/bare-metal/aps/uart/traits.md:16 src/exercises/bare-metal/rtc.md:379
+#: src/exercises/bare-metal/solutions-afternoon.md:231
msgid ""
-"```rust,editable,compile_fail\n"
-"use core::fmt::{self, Write};\n"
-"\n"
-"impl Write for Uart {\n"
-" fn write_str(&mut self, s: &str) -> fmt::Result {\n"
-" for c in s.as_bytes() {\n"
-" self.write_byte(*c);\n"
-" }\n"
-" Ok(())\n"
-" }\n"
-"}\n"
-"\n"
"// Safe because it just contains a pointer to device memory, which can be\n"
"// accessed from any context.\n"
-"unsafe impl Send for Uart {}\n"
-"```"
msgstr ""
#: src/bare-metal/aps/uart/traits.md:24
@@ -16481,37 +14016,54 @@ msgstr ""
"El crate [`bitflags`](https://crates.io/crates/bitflags) resulta útil para "
"trabajar con bitflags."
-#: src/bare-metal/aps/better-uart/bitflags.md:5
-msgid ""
-"```rust,editable,compile_fail\n"
-"use bitflags::bitflags;\n"
-"\n"
-"bitflags! {\n"
-" /// Flags from the UART flag register.\n"
-" #[repr(transparent)]\n"
-" #[derive(Copy, Clone, Debug, Eq, PartialEq)]\n"
-" struct Flags: u16 {\n"
-" /// Clear to send.\n"
-" const CTS = 1 << 0;\n"
-" /// Data set ready.\n"
-" const DSR = 1 << 1;\n"
-" /// Data carrier detect.\n"
-" const DCD = 1 << 2;\n"
-" /// UART busy transmitting data.\n"
-" const BUSY = 1 << 3;\n"
-" /// Receive FIFO is empty.\n"
-" const RXFE = 1 << 4;\n"
-" /// Transmit FIFO is full.\n"
-" const TXFF = 1 << 5;\n"
-" /// Receive FIFO is full.\n"
-" const RXFF = 1 << 6;\n"
-" /// Transmit FIFO is empty.\n"
-" const TXFE = 1 << 7;\n"
-" /// Ring indicator.\n"
-" const RI = 1 << 8;\n"
-" }\n"
-"}\n"
-"```"
+#: src/bare-metal/aps/better-uart/bitflags.md:9
+#: src/exercises/bare-metal/rtc.md:238
+msgid "/// Flags from the UART flag register.\n"
+msgstr ""
+
+#: src/bare-metal/aps/better-uart/bitflags.md:13
+#: src/exercises/bare-metal/rtc.md:242
+msgid "/// Clear to send.\n"
+msgstr ""
+
+#: src/bare-metal/aps/better-uart/bitflags.md:15
+#: src/exercises/bare-metal/rtc.md:244
+msgid "/// Data set ready.\n"
+msgstr ""
+
+#: src/bare-metal/aps/better-uart/bitflags.md:17
+#: src/exercises/bare-metal/rtc.md:246
+msgid "/// Data carrier detect.\n"
+msgstr ""
+
+#: src/bare-metal/aps/better-uart/bitflags.md:19
+#: src/exercises/bare-metal/rtc.md:248
+msgid "/// UART busy transmitting data.\n"
+msgstr ""
+
+#: src/bare-metal/aps/better-uart/bitflags.md:21
+#: src/exercises/bare-metal/rtc.md:250
+msgid "/// Receive FIFO is empty.\n"
+msgstr ""
+
+#: src/bare-metal/aps/better-uart/bitflags.md:23
+#: src/exercises/bare-metal/rtc.md:252
+msgid "/// Transmit FIFO is full.\n"
+msgstr ""
+
+#: src/bare-metal/aps/better-uart/bitflags.md:25
+#: src/exercises/bare-metal/rtc.md:254
+msgid "/// Receive FIFO is full.\n"
+msgstr ""
+
+#: src/bare-metal/aps/better-uart/bitflags.md:27
+#: src/exercises/bare-metal/rtc.md:256
+msgid "/// Transmit FIFO is empty.\n"
+msgstr ""
+
+#: src/bare-metal/aps/better-uart/bitflags.md:29
+#: src/exercises/bare-metal/rtc.md:258
+msgid "/// Ring indicator.\n"
msgstr ""
#: src/bare-metal/aps/better-uart/bitflags.md:37
@@ -16533,43 +14085,6 @@ msgstr ""
"Podemos utilizar una estructura para representar la disposición de la "
"memoria de los registros de UART."
-#: src/bare-metal/aps/better-uart/registers.md:5
-msgid ""
-"```rust,editable,compile_fail\n"
-"#[repr(C, align(4))]\n"
-"struct Registers {\n"
-" dr: u16,\n"
-" _reserved0: [u8; 2],\n"
-" rsr: ReceiveStatus,\n"
-" _reserved1: [u8; 19],\n"
-" fr: Flags,\n"
-" _reserved2: [u8; 6],\n"
-" ilpr: u8,\n"
-" _reserved3: [u8; 3],\n"
-" ibrd: u16,\n"
-" _reserved4: [u8; 2],\n"
-" fbrd: u8,\n"
-" _reserved5: [u8; 3],\n"
-" lcr_h: u8,\n"
-" _reserved6: [u8; 3],\n"
-" cr: u16,\n"
-" _reserved7: [u8; 3],\n"
-" ifls: u8,\n"
-" _reserved8: [u8; 3],\n"
-" imsc: u16,\n"
-" _reserved9: [u8; 2],\n"
-" ris: u16,\n"
-" _reserved10: [u8; 2],\n"
-" mis: u16,\n"
-" _reserved11: [u8; 2],\n"
-" icr: u16,\n"
-" _reserved12: [u8; 2],\n"
-" dmacr: u8,\n"
-" _reserved13: [u8; 3],\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/bare-metal/aps/better-uart/registers.md:41
msgid ""
"[`#[repr(C)]`](https://doc.rust-lang.org/reference/type-layout.html#the-c-"
@@ -16591,69 +14106,28 @@ msgstr ""
"Ahora vamos a utilizar la nueva estructura de `Registers` en nuestro "
"controlador."
-#: src/bare-metal/aps/better-uart/driver.md:5
+#: src/bare-metal/aps/better-uart/driver.md:6
+msgid "/// Driver for a PL011 UART.\n"
+msgstr ""
+
+#: src/bare-metal/aps/better-uart/driver.md:32
+#: src/bare-metal/aps/better-uart/driver.md:55
+#: src/exercises/bare-metal/rtc.md:341 src/exercises/bare-metal/rtc.md:364
msgid ""
-"```rust,editable,compile_fail\n"
-"/// Driver for a PL011 UART.\n"
-"#[derive(Debug)]\n"
-"pub struct Uart {\n"
-" registers: *mut Registers,\n"
-"}\n"
-"\n"
-"impl Uart {\n"
-" /// Constructs a new instance of the UART driver for a PL011 device at "
-"the\n"
-" /// given base address.\n"
-" ///\n"
-" /// # Safety\n"
-" ///\n"
-" /// The given base address must point to the 8 MMIO control registers of "
-"a\n"
-" /// PL011 device, which must be mapped into the address space of the "
-"process\n"
-" /// as device memory and not have any other aliases.\n"
-" pub unsafe fn new(base_address: *mut u32) -> Self {\n"
-" Self {\n"
-" registers: base_address as *mut Registers,\n"
-" }\n"
-" }\n"
-"\n"
-" /// Writes a single byte to the UART.\n"
-" pub fn write_byte(&self, byte: u8) {\n"
-" // Wait until there is room in the TX buffer.\n"
-" while self.read_flag_register().contains(Flags::TXFF) {}\n"
-"\n"
-" // Safe because we know that self.registers points to the control\n"
+"// Safe because we know that self.registers points to the control\n"
" // registers of a PL011 device which is appropriately mapped.\n"
-" unsafe {\n"
-" // Write to the TX buffer.\n"
-" addr_of_mut!((*self.registers).dr).write_volatile(byte.into());\n"
-" }\n"
-"\n"
-" // Wait until the UART is no longer busy.\n"
-" while self.read_flag_register().contains(Flags::BUSY) {}\n"
-" }\n"
-"\n"
-" /// Reads and returns a pending byte, or `None` if nothing has been "
+msgstr ""
+
+#: src/bare-metal/aps/better-uart/driver.md:43
+#: src/exercises/bare-metal/rtc.md:352
+msgid ""
+"/// Reads and returns a pending byte, or `None` if nothing has been "
"received.\n"
-" pub fn read_byte(&self) -> Option {\n"
-" if self.read_flag_register().contains(Flags::RXFE) {\n"
-" None\n"
-" } else {\n"
-" let data = unsafe { addr_of!((*self.registers).dr)."
-"read_volatile() };\n"
-" // TODO: Check for error conditions in bits 8-11.\n"
-" Some(data as u8)\n"
-" }\n"
-" }\n"
-"\n"
-" fn read_flag_register(&self) -> Flags {\n"
-" // Safe because we know that self.registers points to the control\n"
-" // registers of a PL011 device which is appropriately mapped.\n"
-" unsafe { addr_of!((*self.registers).fr).read_volatile() }\n"
-" }\n"
-"}\n"
-"```"
+msgstr ""
+
+#: src/bare-metal/aps/better-uart/driver.md:49
+#: src/exercises/bare-metal/rtc.md:358
+msgid "// TODO: Check for error conditions in bits 8-11.\n"
msgstr ""
#: src/bare-metal/aps/better-uart/driver.md:64
@@ -16678,51 +14152,40 @@ msgstr ""
"Vamos a crear un pequeño programa con nuestro controlador para escribir en "
"la consola serie y compartir los bytes entrantes."
-#: src/bare-metal/aps/better-uart/using.md:6
+#: src/bare-metal/aps/better-uart/using.md:19
+#: src/bare-metal/aps/logging/using.md:18 src/exercises/bare-metal/rtc.md:41
+#: src/exercises/bare-metal/solutions-afternoon.md:33
+msgid "/// Base address of the primary PL011 UART.\n"
+msgstr ""
+
+#: src/bare-metal/aps/better-uart/using.md:25
+#: src/bare-metal/aps/logging/using.md:24 src/exercises/bare-metal/rtc.md:47
+#: src/exercises/bare-metal/solutions-afternoon.md:44
msgid ""
-"```rust,editable,compile_fail\n"
-"#![no_main]\n"
-"#![no_std]\n"
-"\n"
-"mod exceptions;\n"
-"mod pl011;\n"
-"\n"
-"use crate::pl011::Uart;\n"
-"use core::fmt::Write;\n"
-"use core::panic::PanicInfo;\n"
-"use log::error;\n"
-"use smccc::psci::system_off;\n"
-"use smccc::Hvc;\n"
-"\n"
-"/// Base address of the primary PL011 UART.\n"
-"const PL011_BASE_ADDRESS: *mut u32 = 0x900_0000 as _;\n"
-"\n"
-"#[no_mangle]\n"
-"extern \"C\" fn main(x0: u64, x1: u64, x2: u64, x3: u64) {\n"
-" // Safe because `PL011_BASE_ADDRESS` is the base address of a PL011 "
-"device,\n"
+"// Safe because `PL011_BASE_ADDRESS` is the base address of a PL011 device,\n"
" // and nothing else accesses that address range.\n"
-" let mut uart = unsafe { Uart::new(PL011_BASE_ADDRESS) };\n"
-"\n"
-" writeln!(uart, \"main({x0:#x}, {x1:#x}, {x2:#x}, {x3:#x})\").unwrap();\n"
-"\n"
-" loop {\n"
-" if let Some(byte) = uart.read_byte() {\n"
-" uart.write_byte(byte);\n"
-" match byte {\n"
-" b'\\r' => {\n"
-" uart.write_byte(b'\\n');\n"
-" }\n"
-" b'q' => break,\n"
-" _ => {}\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" writeln!(uart, \"Bye!\").unwrap();\n"
-" system_off::().unwrap();\n"
-"}\n"
-"```"
+msgstr ""
+
+#: src/bare-metal/aps/better-uart/using.md:29
+#: src/bare-metal/aps/logging/using.md:29
+msgid "\"main({x0:#x}, {x1:#x}, {x2:#x}, {x3:#x})\""
+msgstr ""
+
+#: src/bare-metal/aps/better-uart/using.md:35
+msgid "b'\\r'"
+msgstr ""
+
+#: src/bare-metal/aps/better-uart/using.md:36
+#: src/async/pitfalls/cancellation.md:27
+msgid "b'\\n'"
+msgstr ""
+
+#: src/bare-metal/aps/better-uart/using.md:38
+msgid "b'q'"
+msgstr ""
+
+#: src/bare-metal/aps/better-uart/using.md:44
+msgid "\"Bye!\""
msgstr ""
#: src/bare-metal/aps/better-uart/using.md:51
@@ -16750,50 +14213,12 @@ msgstr ""
"Estaría bien poder utilizar las macros de registro del crate [`log`](https://"
"crates.io/crates/log). Podemos hacerlo implementando el trait `Log`."
-#: src/bare-metal/aps/logging.md:6
-msgid ""
-"```rust,editable,compile_fail\n"
-"use crate::pl011::Uart;\n"
-"use core::fmt::Write;\n"
-"use log::{LevelFilter, Log, Metadata, Record, SetLoggerError};\n"
-"use spin::mutex::SpinMutex;\n"
-"\n"
-"static LOGGER: Logger = Logger {\n"
-" uart: SpinMutex::new(None),\n"
-"};\n"
-"\n"
-"struct Logger {\n"
-" uart: SpinMutex>,\n"
-"}\n"
-"\n"
-"impl Log for Logger {\n"
-" fn enabled(&self, _metadata: &Metadata) -> bool {\n"
-" true\n"
-" }\n"
-"\n"
-" fn log(&self, record: &Record) {\n"
-" writeln!(\n"
-" self.uart.lock().as_mut().unwrap(),\n"
-" \"[{}] {}\",\n"
-" record.level(),\n"
-" record.args()\n"
-" )\n"
-" .unwrap();\n"
-" }\n"
-"\n"
-" fn flush(&self) {}\n"
-"}\n"
-"\n"
-"/// Initialises UART logger.\n"
-"pub fn init(uart: Uart, max_level: LevelFilter) -> Result<(), "
-"SetLoggerError> {\n"
-" LOGGER.uart.lock().replace(uart);\n"
-"\n"
-" log::set_logger(&LOGGER)?;\n"
-" log::set_max_level(max_level);\n"
-" Ok(())\n"
-"}\n"
-"```"
+#: src/bare-metal/aps/logging.md:28 src/exercises/bare-metal/rtc.md:190
+msgid "\"[{}] {}\""
+msgstr ""
+
+#: src/bare-metal/aps/logging.md:37 src/exercises/bare-metal/rtc.md:199
+msgid "/// Initialises UART logger.\n"
msgstr ""
#: src/bare-metal/aps/logging.md:50
@@ -16808,47 +14233,9 @@ msgstr ""
msgid "We need to initialise the logger before we use it."
msgstr "Debemos inicializar el registrador antes de utilizarlo."
-#: src/bare-metal/aps/logging/using.md:5
-msgid ""
-"```rust,editable,compile_fail\n"
-"#![no_main]\n"
-"#![no_std]\n"
-"\n"
-"mod exceptions;\n"
-"mod logger;\n"
-"mod pl011;\n"
-"\n"
-"use crate::pl011::Uart;\n"
-"use core::panic::PanicInfo;\n"
-"use log::{error, info, LevelFilter};\n"
-"use smccc::psci::system_off;\n"
-"use smccc::Hvc;\n"
-"\n"
-"/// Base address of the primary PL011 UART.\n"
-"const PL011_BASE_ADDRESS: *mut u32 = 0x900_0000 as _;\n"
-"\n"
-"#[no_mangle]\n"
-"extern \"C\" fn main(x0: u64, x1: u64, x2: u64, x3: u64) {\n"
-" // Safe because `PL011_BASE_ADDRESS` is the base address of a PL011 "
-"device,\n"
-" // and nothing else accesses that address range.\n"
-" let uart = unsafe { Uart::new(PL011_BASE_ADDRESS) };\n"
-" logger::init(uart, LevelFilter::Trace).unwrap();\n"
-"\n"
-" info!(\"main({x0:#x}, {x1:#x}, {x2:#x}, {x3:#x})\");\n"
-"\n"
-" assert_eq!(x1, 42);\n"
-"\n"
-" system_off::().unwrap();\n"
-"}\n"
-"\n"
-"#[panic_handler]\n"
-"fn panic(info: &PanicInfo) -> ! {\n"
-" error!(\"{info}\");\n"
-" system_off::().unwrap();\n"
-" loop {}\n"
-"}\n"
-"```"
+#: src/bare-metal/aps/logging/using.md:38 src/exercises/bare-metal/rtc.md:69
+#: src/exercises/bare-metal/solutions-afternoon.md:121
+msgid "\"{info}\""
msgstr ""
#: src/bare-metal/aps/logging/using.md:46
@@ -16879,63 +14266,6 @@ msgstr ""
"AArch32). Implementamos esto en el ensamblaje para guardar los registros "
"volátiles en la _stack_ antes de llamar al código de Rust:"
-#: src/bare-metal/aps/exceptions.md:8
-msgid ""
-"```rust,editable,compile_fail\n"
-"use log::error;\n"
-"use smccc::psci::system_off;\n"
-"use smccc::Hvc;\n"
-"\n"
-"#[no_mangle]\n"
-"extern \"C\" fn sync_exception_current(_elr: u64, _spsr: u64) {\n"
-" error!(\"sync_exception_current\");\n"
-" system_off::().unwrap();\n"
-"}\n"
-"\n"
-"#[no_mangle]\n"
-"extern \"C\" fn irq_current(_elr: u64, _spsr: u64) {\n"
-" error!(\"irq_current\");\n"
-" system_off::().unwrap();\n"
-"}\n"
-"\n"
-"#[no_mangle]\n"
-"extern \"C\" fn fiq_current(_elr: u64, _spsr: u64) {\n"
-" error!(\"fiq_current\");\n"
-" system_off::().unwrap();\n"
-"}\n"
-"\n"
-"#[no_mangle]\n"
-"extern \"C\" fn serr_current(_elr: u64, _spsr: u64) {\n"
-" error!(\"serr_current\");\n"
-" system_off::().unwrap();\n"
-"}\n"
-"\n"
-"#[no_mangle]\n"
-"extern \"C\" fn sync_lower(_elr: u64, _spsr: u64) {\n"
-" error!(\"sync_lower\");\n"
-" system_off::().unwrap();\n"
-"}\n"
-"\n"
-"#[no_mangle]\n"
-"extern \"C\" fn irq_lower(_elr: u64, _spsr: u64) {\n"
-" error!(\"irq_lower\");\n"
-" system_off::().unwrap();\n"
-"}\n"
-"\n"
-"#[no_mangle]\n"
-"extern \"C\" fn fiq_lower(_elr: u64, _spsr: u64) {\n"
-" error!(\"fiq_lower\");\n"
-" system_off::().unwrap();\n"
-"}\n"
-"\n"
-"#[no_mangle]\n"
-"extern \"C\" fn serr_lower(_elr: u64, _spsr: u64) {\n"
-" error!(\"serr_lower\");\n"
-" system_off::().unwrap();\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/bare-metal/aps/exceptions.md:64
msgid "EL is exception level; all our examples this afternoon run in EL1."
msgstr ""
@@ -17087,43 +14417,6 @@ msgstr ""
"traits y macros para realizar conversiones seguras entre secuencias de bytes "
"y otros tipos."
-#: src/bare-metal/useful-crates/zerocopy.md:6
-msgid ""
-"```rust,editable,compile_fail\n"
-"use zerocopy::AsBytes;\n"
-"\n"
-"#[repr(u32)]\n"
-"#[derive(AsBytes, Debug, Default)]\n"
-"enum RequestType {\n"
-" #[default]\n"
-" In = 0,\n"
-" Out = 1,\n"
-" Flush = 4,\n"
-"}\n"
-"\n"
-"#[repr(C)]\n"
-"#[derive(AsBytes, Debug, Default)]\n"
-"struct VirtioBlockRequest {\n"
-" request_type: RequestType,\n"
-" reserved: u32,\n"
-" sector: u64,\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let request = VirtioBlockRequest {\n"
-" request_type: RequestType::Flush,\n"
-" sector: 42,\n"
-" ..Default::default()\n"
-" };\n"
-"\n"
-" assert_eq!(\n"
-" request.as_bytes(),\n"
-" &[4, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0]\n"
-" );\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/bare-metal/useful-crates/zerocopy.md:40
msgid ""
"This is not suitable for MMIO (as it doesn't use volatile reads and writes), "
@@ -17185,27 +14478,16 @@ msgstr ""
"crear tablas de páginas de acuerdo con la arquitectura del sistema de "
"memoria virtual AArch64."
-#: src/bare-metal/useful-crates/aarch64-paging.md:6
-msgid ""
-"```rust,editable,compile_fail\n"
-"use aarch64_paging::{\n"
-" idmap::IdMap,\n"
-" paging::{Attributes, MemoryRegion},\n"
-"};\n"
-"\n"
-"const ASID: usize = 1;\n"
-"const ROOT_LEVEL: usize = 1;\n"
-"\n"
-"// Create a new page table with identity mapping.\n"
-"let mut idmap = IdMap::new(ASID, ROOT_LEVEL);\n"
-"// Map a 2 MiB region of memory as read-only.\n"
-"idmap.map_range(\n"
-" &MemoryRegion::new(0x80200000, 0x80400000),\n"
-" Attributes::NORMAL | Attributes::NON_GLOBAL | Attributes::READ_ONLY,\n"
-").unwrap();\n"
-"// Set `TTBR0_EL1` to activate the page table.\n"
-"idmap.activate();\n"
-"```"
+#: src/bare-metal/useful-crates/aarch64-paging.md:14
+msgid "// Create a new page table with identity mapping.\n"
+msgstr ""
+
+#: src/bare-metal/useful-crates/aarch64-paging.md:16
+msgid "// Map a 2 MiB region of memory as read-only.\n"
+msgstr ""
+
+#: src/bare-metal/useful-crates/aarch64-paging.md:21
+msgid "// Set `TTBR0_EL1` to activate the page table.\n"
msgstr ""
#: src/bare-metal/useful-crates/aarch64-paging.md:28
@@ -17259,25 +14541,6 @@ msgstr ""
"direcciones. Por ejemplo, podríamos querer asignar espacio MMIO para los "
"registros de dirección base (BAR) de PCI:"
-#: src/bare-metal/useful-crates/buddy_system_allocator.md:8
-msgid ""
-"```rust,editable,compile_fail\n"
-"use buddy_system_allocator::FrameAllocator;\n"
-"use core::alloc::Layout;\n"
-"\n"
-"fn main() {\n"
-" let mut allocator = FrameAllocator::<32>::new();\n"
-" allocator.add_frame(0x200_0000, 0x400_0000);\n"
-"\n"
-" let layout = Layout::from_size_align(0x100, 0x100).unwrap();\n"
-" let bar = allocator\n"
-" .alloc_aligned(layout)\n"
-" .expect(\"Failed to allocate 0x100 byte MMIO region\");\n"
-" println!(\"Allocated 0x100 byte MMIO region at {:#x}\", bar);\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/bare-metal/useful-crates/buddy_system_allocator.md:26
msgid "PCI BARs always have alignment equal to their size."
msgstr "Los BAR de PCI siempre tienen una alineación igual a su tamaño."
@@ -17311,22 +14574,6 @@ msgstr ""
"elementos se usan, entrando en _panic_ si intentas utilizar más elementos de "
"los asignados."
-#: src/bare-metal/useful-crates/tinyvec.md:8
-msgid ""
-"```rust,editable,compile_fail\n"
-"use tinyvec::{array_vec, ArrayVec};\n"
-"\n"
-"fn main() {\n"
-" let mut numbers: ArrayVec<[u32; 5]> = array_vec!(42, 66);\n"
-" println!(\"{numbers:?}\");\n"
-" numbers.push(7);\n"
-" println!(\"{numbers:?}\");\n"
-" numbers.remove(1);\n"
-" println!(\"{numbers:?}\");\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/bare-metal/useful-crates/tinyvec.md:23
msgid ""
"`tinyvec` requires that the element type implement `Default` for "
@@ -17365,21 +14612,6 @@ msgstr ""
"El crate [`spin`](https://crates.io/crates/spin) proporciona equivalentes "
"basados en spinlocks de muchos de estos primitivos."
-#: src/bare-metal/useful-crates/spin.md:9
-msgid ""
-"```rust,editable,compile_fail\n"
-"use spin::mutex::SpinMutex;\n"
-"\n"
-"static counter: SpinMutex = SpinMutex::new(0);\n"
-"\n"
-"fn main() {\n"
-" println!(\"count: {}\", counter.lock());\n"
-" *counter.lock() += 2;\n"
-" println!(\"count: {}\", counter.lock());\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/bare-metal/useful-crates/spin.md:23
msgid "Be careful to avoid deadlock if you take locks in interrupt handlers."
msgstr ""
@@ -17425,48 +14657,6 @@ msgstr ""
"binario en sí. Por último, un `raw_binary` para convertir el ELF en un "
"binario sin formato que pueda ejecutarse."
-#: src/bare-metal/android.md:7
-msgid ""
-"```soong\n"
-"rust_ffi_static {\n"
-" name: \"libvmbase_example\",\n"
-" defaults: [\"vmbase_ffi_defaults\"],\n"
-" crate_name: \"vmbase_example\",\n"
-" srcs: [\"src/main.rs\"],\n"
-" rustlibs: [\n"
-" \"libvmbase\",\n"
-" ],\n"
-"}\n"
-"\n"
-"cc_binary {\n"
-" name: \"vmbase_example\",\n"
-" defaults: [\"vmbase_elf_defaults\"],\n"
-" srcs: [\n"
-" \"idmap.S\",\n"
-" ],\n"
-" static_libs: [\n"
-" \"libvmbase_example\",\n"
-" ],\n"
-" linker_scripts: [\n"
-" \"image.ld\",\n"
-" \":vmbase_sections\",\n"
-" ],\n"
-"}\n"
-"\n"
-"raw_binary {\n"
-" name: \"vmbase_example_bin\",\n"
-" stem: \"vmbase_example.bin\",\n"
-" src: \":vmbase_example\",\n"
-" enabled: false,\n"
-" target: {\n"
-" android_arm64: {\n"
-" enabled: true,\n"
-" },\n"
-" },\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/bare-metal/android/vmbase.md:3
msgid ""
"For VMs running under crosvm on aarch64, the [vmbase](https://android."
@@ -17481,22 +14671,6 @@ msgstr ""
"reglas de compilación, además de un punto de entrada, registro de la consola "
"UART y mucho más."
-#: src/bare-metal/android/vmbase.md:6
-msgid ""
-"```rust,compile_fail\n"
-"#![no_main]\n"
-"#![no_std]\n"
-"\n"
-"use vmbase::{main, println};\n"
-"\n"
-"main!(main);\n"
-"\n"
-"pub fn main(arg0: u64, arg1: u64, arg2: u64, arg3: u64) {\n"
-" println!(\"Hello world\");\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/bare-metal/android/vmbase.md:21
msgid ""
"The `main!` macro marks your main function, to be called from the `vmbase` "
@@ -17589,75 +14763,47 @@ msgstr ""
"Descarga la [plantilla de ejercicio](../../comprehensive-rust-exercises.zip) "
"y busca en el directorio `rtc` los siguientes archivos."
-#: src/exercises/bare-metal/rtc.md:23
+#: src/exercises/bare-metal/rtc.md:37
+#: src/exercises/bare-metal/solutions-afternoon.md:29
+msgid "/// Base addresses of the GICv3.\n"
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:52
+#: src/exercises/bare-metal/solutions-afternoon.md:49
+msgid "\"main({:#x}, {:#x}, {:#x}, {:#x})\""
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:54
+#: src/exercises/bare-metal/solutions-afternoon.md:51
msgid ""
-"```rust,compile_fail\n"
-"#![no_main]\n"
-"#![no_std]\n"
-"\n"
-"mod exceptions;\n"
-"mod logger;\n"
-"mod pl011;\n"
-"\n"
-"use crate::pl011::Uart;\n"
-"use arm_gic::gicv3::GicV3;\n"
-"use core::panic::PanicInfo;\n"
-"use log::{error, info, trace, LevelFilter};\n"
-"use smccc::psci::system_off;\n"
-"use smccc::Hvc;\n"
-"\n"
-"/// Base addresses of the GICv3.\n"
-"const GICD_BASE_ADDRESS: *mut u64 = 0x800_0000 as _;\n"
-"const GICR_BASE_ADDRESS: *mut u64 = 0x80A_0000 as _;\n"
-"\n"
-"/// Base address of the primary PL011 UART.\n"
-"const PL011_BASE_ADDRESS: *mut u32 = 0x900_0000 as _;\n"
-"\n"
-"#[no_mangle]\n"
-"extern \"C\" fn main(x0: u64, x1: u64, x2: u64, x3: u64) {\n"
-" // Safe because `PL011_BASE_ADDRESS` is the base address of a PL011 "
-"device,\n"
-" // and nothing else accesses that address range.\n"
-" let uart = unsafe { Uart::new(PL011_BASE_ADDRESS) };\n"
-" logger::init(uart, LevelFilter::Trace).unwrap();\n"
-"\n"
-" info!(\"main({:#x}, {:#x}, {:#x}, {:#x})\", x0, x1, x2, x3);\n"
-"\n"
-" // Safe because `GICD_BASE_ADDRESS` and `GICR_BASE_ADDRESS` are the "
-"base\n"
+"// Safe because `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"
-" let mut gic = unsafe { GicV3::new(GICD_BASE_ADDRESS, "
-"GICR_BASE_ADDRESS) };\n"
-" gic.setup();\n"
-"\n"
-" // TODO: Create instance of RTC driver and print current time.\n"
-"\n"
-" // TODO: Wait for 3 seconds.\n"
-"\n"
-" system_off::().unwrap();\n"
-"}\n"
-"\n"
-"#[panic_handler]\n"
-"fn panic(info: &PanicInfo) -> ! {\n"
-" error!(\"{info}\");\n"
-" system_off::().unwrap();\n"
-" loop {}\n"
-"}\n"
-"```"
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:60
+msgid "// TODO: Create instance of RTC driver and print current time.\n"
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:62
+msgid "// TODO: Wait for 3 seconds.\n"
msgstr ""
#: src/exercises/bare-metal/rtc.md:75
+#, fuzzy
+#| msgid ""
+#| "`src/exceptions.rs` (you should only need to change this for the 3rd part "
+#| "of the exercise):"
msgid ""
-"`src/exceptions.rs` (you should only need to change this for the 3rd part of "
+"_src/exceptions.rs_ (you should only need to change this for the 3rd part of "
"the exercise):"
msgstr ""
"`src/exceptions.rs` (solo se debería cambiar esto en la tercera parte del "
"ejercicio):"
-#: src/exercises/bare-metal/rtc.md:79
+#: src/exercises/bare-metal/rtc.md:80 src/exercises/bare-metal/rtc.md:154
+#: src/exercises/bare-metal/rtc.md:215 src/exercises/bare-metal/rtc.md:415
msgid ""
-"```rust,compile_fail\n"
"// Copyright 2023 Google LLC\n"
"//\n"
"// Licensed under the Apache License, Version 2.0 (the \"License\");\n"
@@ -17671,245 +14817,110 @@ msgid ""
"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
"// See the License for the specific language governing permissions and\n"
"// limitations under the License.\n"
-"\n"
-"use arm_gic::gicv3::GicV3;\n"
-"use log::{error, info, trace};\n"
-"use smccc::psci::system_off;\n"
-"use smccc::Hvc;\n"
-"\n"
-"#[no_mangle]\n"
-"extern \"C\" fn sync_exception_current(_elr: u64, _spsr: u64) {\n"
-" error!(\"sync_exception_current\");\n"
-" system_off::().unwrap();\n"
-"}\n"
-"\n"
-"#[no_mangle]\n"
-"extern \"C\" fn irq_current(_elr: u64, _spsr: u64) {\n"
-" trace!(\"irq_current\");\n"
-" let intid = GicV3::get_and_acknowledge_interrupt().expect(\"No pending "
-"interrupt\");\n"
-" info!(\"IRQ {intid:?}\");\n"
-"}\n"
-"\n"
-"#[no_mangle]\n"
-"extern \"C\" fn fiq_current(_elr: u64, _spsr: u64) {\n"
-" error!(\"fiq_current\");\n"
-" system_off::().unwrap();\n"
-"}\n"
-"\n"
-"#[no_mangle]\n"
-"extern \"C\" fn serr_current(_elr: u64, _spsr: u64) {\n"
-" error!(\"serr_current\");\n"
-" system_off::().unwrap();\n"
-"}\n"
-"\n"
-"#[no_mangle]\n"
-"extern \"C\" fn sync_lower(_elr: u64, _spsr: u64) {\n"
-" error!(\"sync_lower\");\n"
-" system_off::().unwrap();\n"
-"}\n"
-"\n"
-"#[no_mangle]\n"
-"extern \"C\" fn irq_lower(_elr: u64, _spsr: u64) {\n"
-" error!(\"irq_lower\");\n"
-" system_off::().unwrap();\n"
-"}\n"
-"\n"
-"#[no_mangle]\n"
-"extern \"C\" fn fiq_lower(_elr: u64, _spsr: u64) {\n"
-" error!(\"fiq_lower\");\n"
-" system_off::().unwrap();\n"
-"}\n"
-"\n"
-"#[no_mangle]\n"
-"extern \"C\" fn serr_lower(_elr: u64, _spsr: u64) {\n"
-" error!(\"serr_lower\");\n"
-" system_off::().unwrap();\n"
-"}\n"
-"```"
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:101
+msgid "\"sync_exception_current\""
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:107
+msgid "\"irq_current\""
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:108
+msgid "\"No pending interrupt\""
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:109
+msgid "\"IRQ {intid:?}\""
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:114
+msgid "\"fiq_current\""
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:120
+msgid "\"serr_current\""
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:126
+msgid "\"sync_lower\""
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:132
+msgid "\"irq_lower\""
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:138
+msgid "\"fiq_lower\""
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:144
+msgid "\"serr_lower\""
msgstr ""
#: src/exercises/bare-metal/rtc.md:149
-msgid "`src/logger.rs` (you shouldn't need to change this):"
+#, fuzzy
+#| msgid "`src/logger.rs` (you shouldn't need to change this):"
+msgid "_src/logger.rs_ (you shouldn't need to change this):"
msgstr "`src/logger.rs` (no debería ser necesario cambiarlo):"
-#: src/exercises/bare-metal/rtc.md:153
-msgid ""
-"```rust,compile_fail\n"
-"// Copyright 2023 Google LLC\n"
-"//\n"
-"// Licensed under the Apache License, Version 2.0 (the \"License\");\n"
-"// you may not use this file except in compliance with the License.\n"
-"// You may obtain a copy of the License at\n"
-"//\n"
-"// http://www.apache.org/licenses/LICENSE-2.0\n"
-"//\n"
-"// Unless required by applicable law or agreed to in writing, software\n"
-"// distributed under the License is distributed on an \"AS IS\" BASIS,\n"
-"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
-"// See the License for the specific language governing permissions and\n"
-"// limitations under the License.\n"
-"\n"
-"// ANCHOR: main\n"
-"use crate::pl011::Uart;\n"
-"use core::fmt::Write;\n"
-"use log::{LevelFilter, Log, Metadata, Record, SetLoggerError};\n"
-"use spin::mutex::SpinMutex;\n"
-"\n"
-"static LOGGER: Logger = Logger {\n"
-" uart: SpinMutex::new(None),\n"
-"};\n"
-"\n"
-"struct Logger {\n"
-" uart: SpinMutex>,\n"
-"}\n"
-"\n"
-"impl Log for Logger {\n"
-" fn enabled(&self, _metadata: &Metadata) -> bool {\n"
-" true\n"
-" }\n"
-"\n"
-" fn log(&self, record: &Record) {\n"
-" writeln!(\n"
-" self.uart.lock().as_mut().unwrap(),\n"
-" \"[{}] {}\",\n"
-" record.level(),\n"
-" record.args()\n"
-" )\n"
-" .unwrap();\n"
-" }\n"
-"\n"
-" fn flush(&self) {}\n"
-"}\n"
-"\n"
-"/// Initialises UART logger.\n"
-"pub fn init(uart: Uart, max_level: LevelFilter) -> Result<(), "
-"SetLoggerError> {\n"
-" LOGGER.uart.lock().replace(uart);\n"
-"\n"
-" log::set_logger(&LOGGER)?;\n"
-" log::set_max_level(max_level);\n"
-" Ok(())\n"
-"}\n"
-"```"
+#: src/exercises/bare-metal/rtc.md:167
+msgid "// ANCHOR: main\n"
msgstr ""
#: src/exercises/bare-metal/rtc.md:210
-msgid "`src/pl011.rs` (you shouldn't need to change this):"
+#, fuzzy
+#| msgid "`src/pl011.rs` (you shouldn't need to change this):"
+msgid "_src/pl011.rs_ (you shouldn't need to change this):"
msgstr "`src/pl011.rs` (no debería ser necesario cambiarlo):"
-#: src/exercises/bare-metal/rtc.md:214
+#: src/exercises/bare-metal/rtc.md:233
+msgid "// ANCHOR: Flags\n"
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:261
+msgid "// ANCHOR_END: Flags\n"
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:265
+msgid ""
+"/// Flags from the UART Receive Status Register / Error Clear Register.\n"
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:269
+msgid "/// Framing error.\n"
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:271
+msgid "/// Parity error.\n"
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:273
+msgid "/// Break error.\n"
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:275
+msgid "/// Overrun error.\n"
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:279
+msgid "// ANCHOR: Registers\n"
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:311
+msgid "// ANCHOR_END: Registers\n"
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:313
msgid ""
-"```rust,compile_fail\n"
-"// Copyright 2023 Google LLC\n"
-"//\n"
-"// Licensed under the Apache License, Version 2.0 (the \"License\");\n"
-"// you may not use this file except in compliance with the License.\n"
-"// You may obtain a copy of the License at\n"
-"//\n"
-"// http://www.apache.org/licenses/LICENSE-2.0\n"
-"//\n"
-"// Unless required by applicable law or agreed to in writing, software\n"
-"// distributed under the License is distributed on an \"AS IS\" BASIS,\n"
-"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
-"// See the License for the specific language governing permissions and\n"
-"// limitations under the License.\n"
-"\n"
-"#![allow(unused)]\n"
-"\n"
-"use core::fmt::{self, Write};\n"
-"use core::ptr::{addr_of, addr_of_mut};\n"
-"\n"
-"// ANCHOR: Flags\n"
-"use bitflags::bitflags;\n"
-"\n"
-"bitflags! {\n"
-" /// Flags from the UART flag register.\n"
-" #[repr(transparent)]\n"
-" #[derive(Copy, Clone, Debug, Eq, PartialEq)]\n"
-" struct Flags: u16 {\n"
-" /// Clear to send.\n"
-" const CTS = 1 << 0;\n"
-" /// Data set ready.\n"
-" const DSR = 1 << 1;\n"
-" /// Data carrier detect.\n"
-" const DCD = 1 << 2;\n"
-" /// UART busy transmitting data.\n"
-" const BUSY = 1 << 3;\n"
-" /// Receive FIFO is empty.\n"
-" const RXFE = 1 << 4;\n"
-" /// Transmit FIFO is full.\n"
-" const TXFF = 1 << 5;\n"
-" /// Receive FIFO is full.\n"
-" const RXFF = 1 << 6;\n"
-" /// Transmit FIFO is empty.\n"
-" const TXFE = 1 << 7;\n"
-" /// Ring indicator.\n"
-" const RI = 1 << 8;\n"
-" }\n"
-"}\n"
-"// ANCHOR_END: Flags\n"
-"\n"
-"bitflags! {\n"
-" /// Flags from the UART Receive Status Register / Error Clear Register.\n"
-" #[repr(transparent)]\n"
-" #[derive(Copy, Clone, Debug, Eq, PartialEq)]\n"
-" struct ReceiveStatus: u16 {\n"
-" /// Framing error.\n"
-" const FE = 1 << 0;\n"
-" /// Parity error.\n"
-" const PE = 1 << 1;\n"
-" /// Break error.\n"
-" const BE = 1 << 2;\n"
-" /// Overrun error.\n"
-" const OE = 1 << 3;\n"
-" }\n"
-"}\n"
-"\n"
-"// ANCHOR: Registers\n"
-"#[repr(C, align(4))]\n"
-"struct Registers {\n"
-" dr: u16,\n"
-" _reserved0: [u8; 2],\n"
-" rsr: ReceiveStatus,\n"
-" _reserved1: [u8; 19],\n"
-" fr: Flags,\n"
-" _reserved2: [u8; 6],\n"
-" ilpr: u8,\n"
-" _reserved3: [u8; 3],\n"
-" ibrd: u16,\n"
-" _reserved4: [u8; 2],\n"
-" fbrd: u8,\n"
-" _reserved5: [u8; 3],\n"
-" lcr_h: u8,\n"
-" _reserved6: [u8; 3],\n"
-" cr: u16,\n"
-" _reserved7: [u8; 3],\n"
-" ifls: u8,\n"
-" _reserved8: [u8; 3],\n"
-" imsc: u16,\n"
-" _reserved9: [u8; 2],\n"
-" ris: u16,\n"
-" _reserved10: [u8; 2],\n"
-" mis: u16,\n"
-" _reserved11: [u8; 2],\n"
-" icr: u16,\n"
-" _reserved12: [u8; 2],\n"
-" dmacr: u8,\n"
-" _reserved13: [u8; 3],\n"
-"}\n"
-"// ANCHOR_END: Registers\n"
-"\n"
"// ANCHOR: Uart\n"
"/// Driver for a PL011 UART.\n"
-"#[derive(Debug)]\n"
-"pub struct Uart {\n"
-" registers: *mut Registers,\n"
-"}\n"
-"\n"
-"impl Uart {\n"
-" /// Constructs a new instance of the UART driver for a PL011 device at "
-"the\n"
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:322
+msgid ""
+"/// Constructs a new instance of the UART driver for a PL011 device at the\n"
" /// given base address.\n"
" ///\n"
" /// # Safety\n"
@@ -17919,129 +14930,58 @@ msgid ""
" /// PL011 device, which must be mapped into the address space of the "
"process\n"
" /// as device memory and not have any other aliases.\n"
-" pub unsafe fn new(base_address: *mut u32) -> Self {\n"
-" Self {\n"
-" registers: base_address as *mut Registers,\n"
-" }\n"
-" }\n"
-"\n"
-" /// Writes a single byte to the UART.\n"
-" pub fn write_byte(&self, byte: u8) {\n"
-" // Wait until there is room in the TX buffer.\n"
-" while self.read_flag_register().contains(Flags::TXFF) {}\n"
-"\n"
-" // Safe because we know that self.registers points to the control\n"
-" // registers of a PL011 device which is appropriately mapped.\n"
-" unsafe {\n"
-" // Write to the TX buffer.\n"
-" addr_of_mut!((*self.registers).dr).write_volatile(byte.into());\n"
-" }\n"
-"\n"
-" // Wait until the UART is no longer busy.\n"
-" while self.read_flag_register().contains(Flags::BUSY) {}\n"
-" }\n"
-"\n"
-" /// Reads and returns a pending byte, or `None` if nothing has been "
-"received.\n"
-" pub fn read_byte(&self) -> Option {\n"
-" if self.read_flag_register().contains(Flags::RXFE) {\n"
-" None\n"
-" } else {\n"
-" let data = unsafe { addr_of!((*self.registers).dr)."
-"read_volatile() };\n"
-" // TODO: Check for error conditions in bits 8-11.\n"
-" Some(data as u8)\n"
-" }\n"
-" }\n"
-"\n"
-" fn read_flag_register(&self) -> Flags {\n"
-" // Safe because we know that self.registers points to the control\n"
-" // registers of a PL011 device which is appropriately mapped.\n"
-" unsafe { addr_of!((*self.registers).fr).read_volatile() }\n"
-" }\n"
-"}\n"
-"// ANCHOR_END: Uart\n"
-"\n"
-"impl Write for Uart {\n"
-" fn write_str(&mut self, s: &str) -> fmt::Result {\n"
-" for c in s.as_bytes() {\n"
-" self.write_byte(*c);\n"
-" }\n"
-" Ok(())\n"
-" }\n"
-"}\n"
-"\n"
-"// Safe because it just contains a pointer to device memory, which can be\n"
-"// accessed from any context.\n"
-"unsafe impl Send for Uart {}\n"
-"```"
msgstr ""
-#: src/exercises/bare-metal/rtc.md:389
-msgid ""
-"```toml\n"
-"[workspace]\n"
-"\n"
-"[package]\n"
-"name = \"rtc\"\n"
-"version = \"0.1.0\"\n"
-"edition = \"2021\"\n"
-"publish = false\n"
-"\n"
-"[dependencies]\n"
-"arm-gic = \"0.1.0\"\n"
-"bitflags = \"2.0.0\"\n"
-"chrono = { version = \"0.4.24\", default-features = false }\n"
-"log = \"0.4.17\"\n"
-"smccc = \"0.1.1\"\n"
-"spin = \"0.9.8\"\n"
-"\n"
-"[build-dependencies]\n"
-"cc = \"1.0.73\"\n"
-"```"
+#: src/exercises/bare-metal/rtc.md:368
+msgid "// ANCHOR_END: Uart\n"
msgstr ""
#: src/exercises/bare-metal/rtc.md:410
-msgid "`build.rs` (you shouldn't need to change this):"
+#, fuzzy
+#| msgid "`build.rs` (you shouldn't need to change this):"
+msgid "_build.rs_ (you shouldn't need to change this):"
msgstr "`build.rs` (no debería ser necesario cambiarlo):"
-#: src/exercises/bare-metal/rtc.md:414
-msgid ""
-"```rust,compile_fail\n"
-"// Copyright 2023 Google LLC\n"
-"//\n"
-"// Licensed under the Apache License, Version 2.0 (the \"License\");\n"
-"// you may not use this file except in compliance with the License.\n"
-"// You may obtain a copy of the License at\n"
-"//\n"
-"// http://www.apache.org/licenses/LICENSE-2.0\n"
-"//\n"
-"// Unless required by applicable law or agreed to in writing, software\n"
-"// distributed under the License is distributed on an \"AS IS\" BASIS,\n"
-"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
-"// See the License for the specific language governing permissions and\n"
-"// limitations under the License.\n"
-"\n"
-"use cc::Build;\n"
-"use std::env;\n"
-"\n"
-"fn main() {\n"
-" #[cfg(target_os = \"linux\")]\n"
-" env::set_var(\"CROSS_COMPILE\", \"aarch64-linux-gnu\");\n"
-" #[cfg(not(target_os = \"linux\"))]\n"
-" env::set_var(\"CROSS_COMPILE\", \"aarch64-none-elf\");\n"
-"\n"
-" Build::new()\n"
-" .file(\"entry.S\")\n"
-" .file(\"exceptions.S\")\n"
-" .file(\"idmap.S\")\n"
-" .compile(\"empty\")\n"
-"}\n"
-"```"
+#: src/exercises/bare-metal/rtc.md:433 src/exercises/bare-metal/rtc.md:435
+msgid "\"linux\""
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:434 src/exercises/bare-metal/rtc.md:436
+msgid "\"CROSS_COMPILE\""
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:434
+#, fuzzy
+#| msgid "aarch64-paging"
+msgid "\"aarch64-linux-gnu\""
+msgstr "aarch64-paging"
+
+#: src/exercises/bare-metal/rtc.md:436
+msgid "\"aarch64-none-elf\""
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:439
+msgid "\"entry.S\""
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:440
+#, fuzzy
+#| msgid "Exceptions"
+msgid "\"exceptions.S\""
+msgstr "Excepciones"
+
+#: src/exercises/bare-metal/rtc.md:441
+msgid "\"idmap.S\""
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:442
+msgid "\"empty\""
msgstr ""
#: src/exercises/bare-metal/rtc.md:446
-msgid "`entry.S` (you shouldn't need to change this):"
+#, fuzzy
+#| msgid "`entry.S` (you shouldn't need to change this):"
+msgid "_entry.S_ (you shouldn't need to change this):"
msgstr "`entry.S` (no debería ser necesario cambiarlo):"
#: src/exercises/bare-metal/rtc.md:450
@@ -18207,7 +15147,9 @@ msgid ""
msgstr ""
#: src/exercises/bare-metal/rtc.md:595
-msgid "`exceptions.S` (you shouldn't need to change this):"
+#, fuzzy
+#| msgid "`exceptions.S` (you shouldn't need to change this):"
+msgid "_exceptions.S_ (you shouldn't need to change this):"
msgstr "`exceptions.S` (no debería ser necesario cambiarlo):"
#: src/exercises/bare-metal/rtc.md:599
@@ -18405,7 +15347,9 @@ msgid ""
msgstr ""
#: src/exercises/bare-metal/rtc.md:780
-msgid "`idmap.S` (you shouldn't need to change this):"
+#, fuzzy
+#| msgid "`idmap.S` (you shouldn't need to change this):"
+msgid "_idmap.S_ (you shouldn't need to change this):"
msgstr "`idmap.S` (no debería ser necesario cambiarlo):"
#: src/exercises/bare-metal/rtc.md:784
@@ -18458,7 +15402,9 @@ msgid ""
msgstr ""
#: src/exercises/bare-metal/rtc.md:829
-msgid "`image.ld` (you shouldn't need to change this):"
+#, fuzzy
+#| msgid "`image.ld` (you shouldn't need to change this):"
+msgid "_image.ld_ (you shouldn't need to change this):"
msgstr "`image.ld` (no debería ser necesario cambiarlo):"
#: src/exercises/bare-metal/rtc.md:833
@@ -18573,61 +15519,31 @@ msgid ""
msgstr ""
#: src/exercises/bare-metal/rtc.md:940
-msgid "`Makefile` (you shouldn't need to change this):"
+#, fuzzy
+#| msgid "`Makefile` (you shouldn't need to change this):"
+msgid "_Makefile_ (you shouldn't need to change this):"
msgstr "`Makefile` (no debería ser necesario cambiarlo):"
-#: src/exercises/bare-metal/rtc.md:944
-msgid ""
-"```makefile\n"
-"# Copyright 2023 Google LLC\n"
-"#\n"
-"# Licensed under the Apache License, Version 2.0 (the \"License\");\n"
-"# you may not use this file except in compliance with the License.\n"
-"# You may obtain a copy of the License at\n"
-"#\n"
-"# http://www.apache.org/licenses/LICENSE-2.0\n"
-"#\n"
-"# Unless required by applicable law or agreed to in writing, software\n"
-"# distributed under the License is distributed on an \"AS IS\" BASIS,\n"
-"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
-"# See the License for the specific language governing permissions and\n"
-"# limitations under the License.\n"
-"\n"
-"UNAME := $(shell uname -s)\n"
-"ifeq ($(UNAME),Linux)\n"
-"\tTARGET = aarch64-linux-gnu\n"
-"else\n"
-"\tTARGET = aarch64-none-elf\n"
-"endif\n"
-"OBJCOPY = $(TARGET)-objcopy\n"
-"\n"
-".PHONY: build qemu_minimal qemu qemu_logger\n"
-"\n"
-"all: rtc.bin\n"
-"\n"
-"build:\n"
-"\tcargo build\n"
-"\n"
-"rtc.bin: build\n"
-"\t$(OBJCOPY) -O binary target/aarch64-unknown-none/debug/rtc $@\n"
-"\n"
-"qemu: rtc.bin\n"
-"\tqemu-system-aarch64 -machine virt,gic-version=3 -cpu max -serial mon:stdio "
-"-display none -kernel $< -s\n"
-"\n"
-"clean:\n"
-"\tcargo clean\n"
-"\trm -f *.bin\n"
-"```"
+#: src/exercises/bare-metal/rtc.md:945
+msgid "# Copyright 2023 Google LLC"
msgstr ""
-#: src/exercises/bare-metal/rtc.md:989
-msgid ""
-"```toml\n"
-"[build]\n"
-"target = \"aarch64-unknown-none\"\n"
-"rustflags = [\"-C\", \"link-arg=-Timage.ld\"]\n"
-"```"
+#: src/exercises/bare-metal/rtc.md:959
+msgid "$(shell uname -s)"
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:961
+#, fuzzy
+#| msgid "aarch64-paging"
+msgid "aarch64-linux-gnu"
+msgstr "aarch64-paging"
+
+#: src/exercises/bare-metal/rtc.md:978
+msgid "stdio -display none -kernel $< -s"
+msgstr ""
+
+#: src/exercises/bare-metal/rtc.md:981
+msgid "cargo clean"
msgstr ""
#: src/exercises/bare-metal/rtc.md:995
@@ -18661,26 +15577,12 @@ msgstr ""
msgid "Rust threads work similarly to threads in other languages:"
msgstr "Los hilos de Rust funcionan de forma similar a los de otros lenguajes:"
-#: src/concurrency/threads.md:5
-msgid ""
-"```rust,editable\n"
-"use std::thread;\n"
-"use std::time::Duration;\n"
-"\n"
-"fn main() {\n"
-" thread::spawn(|| {\n"
-" for i in 1..10 {\n"
-" println!(\"Count in thread: {i}!\");\n"
-" thread::sleep(Duration::from_millis(5));\n"
-" }\n"
-" });\n"
-"\n"
-" for i in 1..5 {\n"
-" println!(\"Main thread: {i}\");\n"
-" thread::sleep(Duration::from_millis(5));\n"
-" }\n"
-"}\n"
-"```"
+#: src/concurrency/threads.md:12
+msgid "\"Count in thread: {i}!\""
+msgstr ""
+
+#: src/concurrency/threads.md:18
+msgid "\"Main thread: {i}\""
msgstr ""
#: src/concurrency/threads.md:24
@@ -18732,22 +15634,8 @@ msgstr ""
msgid "Normal threads cannot borrow from their environment:"
msgstr "Los hilos normales no pueden tomar nada prestado de su entorno:"
-#: src/concurrency/scoped-threads.md:5
-msgid ""
-"```rust,editable,compile_fail\n"
-"use std::thread;\n"
-"\n"
-"fn foo() {\n"
-" let s = String::from(\"Hello\");\n"
-" thread::spawn(|| {\n"
-" println!(\"Length: {}\", s.len());\n"
-" });\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" foo();\n"
-"}\n"
-"```"
+#: src/concurrency/scoped-threads.md:11 src/concurrency/scoped-threads.md:30
+msgid "\"Length: {}\""
msgstr ""
#: src/concurrency/scoped-threads.md:20
@@ -18758,23 +15646,6 @@ msgstr ""
"Sin embargo, puedes usar un [hilo con ámbito](https://doc.rust-lang.org/std/"
"thread/fn.scope.html) para lo siguiente:"
-#: src/concurrency/scoped-threads.md:22
-msgid ""
-"```rust,editable\n"
-"use std::thread;\n"
-"\n"
-"fn main() {\n"
-" let s = String::from(\"Hello\");\n"
-"\n"
-" thread::scope(|scope| {\n"
-" scope.spawn(|| {\n"
-" println!(\"Length: {}\", s.len());\n"
-" });\n"
-" });\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/concurrency/scoped-threads.md:40
msgid ""
"The reason for that is that when the `thread::scope` function completes, all "
@@ -18801,29 +15672,12 @@ msgstr ""
"partes están conectadas a través del canal, pero solo se ven los puntos "
"finales."
-#: src/concurrency/channels.md:6
-msgid ""
-"```rust,editable\n"
-"use std::sync::mpsc;\n"
-"use std::thread;\n"
-"\n"
-"fn main() {\n"
-" let (tx, rx) = mpsc::channel();\n"
-"\n"
-" tx.send(10).unwrap();\n"
-" tx.send(20).unwrap();\n"
-"\n"
-" println!(\"Received: {:?}\", rx.recv());\n"
-" println!(\"Received: {:?}\", rx.recv());\n"
-"\n"
-" let tx2 = tx.clone();\n"
-" tx2.send(30).unwrap();\n"
-" println!(\"Received: {:?}\", rx.recv());\n"
-"}\n"
-"```"
+#: src/concurrency/channels.md:15 src/concurrency/channels.md:16
+#: src/concurrency/channels.md:20
+msgid "\"Received: {:?}\""
msgstr ""
-#: src/concurrency/channels.md:27
+#: src/concurrency/channels.md:26
msgid ""
"`mpsc` stands for Multi-Producer, Single-Consumer. `Sender` and `SyncSender` "
"implement `Clone` (so you can make multiple producers) but `Receiver` does "
@@ -18833,7 +15687,7 @@ msgstr ""
"consumidor único.) `Sender` y `SyncSender` implementan `Clone` (es decir, "
"puedes crear varios productores), pero `Receiver` no."
-#: src/concurrency/channels.md:29
+#: src/concurrency/channels.md:28
msgid ""
"`send()` and `recv()` return `Result`. If they return `Err`, it means the "
"counterpart `Sender` or `Receiver` is dropped and the channel is closed."
@@ -18845,31 +15699,24 @@ msgstr ""
msgid "You get an unbounded and asynchronous channel with `mpsc::channel()`:"
msgstr "Se obtiene un canal asíncrono y sin límites con `mpsc::channel()`:"
-#: src/concurrency/channels/unbounded.md:5
-msgid ""
-"```rust,editable\n"
-"use std::sync::mpsc;\n"
-"use std::thread;\n"
-"use std::time::Duration;\n"
-"\n"
-"fn main() {\n"
-" let (tx, rx) = mpsc::channel();\n"
-"\n"
-" thread::spawn(move || {\n"
-" let thread_id = thread::current().id();\n"
-" for i in 1..10 {\n"
-" tx.send(format!(\"Message {i}\")).unwrap();\n"
-" println!(\"{thread_id:?}: sent Message {i}\");\n"
-" }\n"
-" println!(\"{thread_id:?}: done\");\n"
-" });\n"
-" thread::sleep(Duration::from_millis(100));\n"
-"\n"
-" for msg in rx.iter() {\n"
-" println!(\"Main: got {msg}\");\n"
-" }\n"
-"}\n"
-"```"
+#: src/concurrency/channels/unbounded.md:16
+#: src/concurrency/channels/bounded.md:16
+msgid "\"Message {i}\""
+msgstr ""
+
+#: src/concurrency/channels/unbounded.md:17
+#: src/concurrency/channels/bounded.md:17
+msgid "\"{thread_id:?}: sent Message {i}\""
+msgstr ""
+
+#: src/concurrency/channels/unbounded.md:19
+#: src/concurrency/channels/bounded.md:19
+msgid "\"{thread_id:?}: done\""
+msgstr ""
+
+#: src/concurrency/channels/unbounded.md:24
+#: src/concurrency/channels/bounded.md:24
+msgid "\"Main: got {msg}\""
msgstr ""
#: src/concurrency/channels/bounded.md:3
@@ -18877,33 +15724,6 @@ msgid ""
"With bounded (synchronous) channels, `send` can block the current thread:"
msgstr "Con canales limitados (síncronos), `send` puede bloquear el hilo:"
-#: src/concurrency/channels/bounded.md:5
-msgid ""
-"```rust,editable\n"
-"use std::sync::mpsc;\n"
-"use std::thread;\n"
-"use std::time::Duration;\n"
-"\n"
-"fn main() {\n"
-" let (tx, rx) = mpsc::sync_channel(3);\n"
-"\n"
-" thread::spawn(move || {\n"
-" let thread_id = thread::current().id();\n"
-" for i in 1..10 {\n"
-" tx.send(format!(\"Message {i}\")).unwrap();\n"
-" println!(\"{thread_id:?}: sent Message {i}\");\n"
-" }\n"
-" println!(\"{thread_id:?}: done\");\n"
-" });\n"
-" thread::sleep(Duration::from_millis(100));\n"
-"\n"
-" for msg in rx.iter() {\n"
-" println!(\"Main: got {msg}\");\n"
-" }\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/concurrency/channels/bounded.md:31
msgid ""
"Calling `send` will block the current thread until there is space in the "
@@ -18936,8 +15756,12 @@ msgid "`Send` and `Sync`"
msgstr "`Send` y `Sync`"
#: src/concurrency/send-sync.md:3
+#, fuzzy
+#| msgid ""
+#| "How does Rust know to forbid shared access across thread? The answer is "
+#| "in two traits:"
msgid ""
-"How does Rust know to forbid shared access across thread? The answer is in "
+"How does Rust know to forbid shared access across threads? The answer is in "
"two traits:"
msgstr ""
"¿Cómo sabe Rust que debe prohibir el acceso compartido entre hilos? La "
@@ -19143,9 +15967,13 @@ msgstr ""
"mover a otro hilo:"
#: src/concurrency/send-sync/examples.md:31
+#, fuzzy
+#| msgid ""
+#| "`MutexGuard`: Uses OS level primitives which must be deallocated on "
+#| "the thread which created them."
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."
msgstr ""
"`MutexGuard`: utiliza primitivos de nivel SO que se deben desasignar en "
"el hilo que los creó."
@@ -19213,27 +16041,14 @@ msgstr ""
"[`Arc`](https://doc.rust-lang.org/std/sync/struct.Arc.html) permite el "
"acceso compartido de solo lectura a través de `Arc::clone`:"
-#: src/concurrency/shared_state/arc.md:5
-msgid ""
-"```rust,editable\n"
-"use std::thread;\n"
-"use std::sync::Arc;\n"
-"\n"
-"fn main() {\n"
-" let v = Arc::new(vec![10, 20, 30]);\n"
-" let mut handles = Vec::new();\n"
-" for _ in 1..5 {\n"
-" let v = Arc::clone(&v);\n"
-" handles.push(thread::spawn(move || {\n"
-" let thread_id = thread::current().id();\n"
-" println!(\"{thread_id:?}: {v:?}\");\n"
-" }));\n"
-" }\n"
-"\n"
-" handles.into_iter().for_each(|h| h.join().unwrap());\n"
-" println!(\"v: {v:?}\");\n"
-"}\n"
-"```"
+#: src/concurrency/shared_state/arc.md:16
+msgid "\"{thread_id:?}: {v:?}\""
+msgstr ""
+
+#: src/concurrency/shared_state/arc.md:21
+#: src/concurrency/shared_state/example.md:17
+#: src/concurrency/shared_state/example.md:45
+msgid "\"v: {v:?}\""
msgstr ""
#: src/concurrency/shared_state/arc.md:29
@@ -19287,23 +16102,9 @@ msgstr ""
"la exclusión mutua _y_ permite un acceso mutable a `T` a través de una "
"interfaz de solo lectura:"
-#: src/concurrency/shared_state/mutex.md:6
-msgid ""
-"```rust,editable\n"
-"use std::sync::Mutex;\n"
-"\n"
-"fn main() {\n"
-" let v = Mutex::new(vec![10, 20, 30]);\n"
-" println!(\"v: {:?}\", v.lock().unwrap());\n"
-"\n"
-" {\n"
-" let mut guard = v.lock().unwrap();\n"
-" guard.push(40);\n"
-" }\n"
-"\n"
-" println!(\"v: {:?}\", v.lock().unwrap());\n"
-"}\n"
-"```"
+#: src/concurrency/shared_state/mutex.md:11
+#: src/concurrency/shared_state/mutex.md:18
+msgid "\"v: {:?}\""
msgstr ""
#: src/concurrency/shared_state/mutex.md:22
@@ -19376,56 +16177,14 @@ msgstr ""
msgid "Let us see `Arc` and `Mutex` in action:"
msgstr "Veamos cómo funcionan `Arc` y `Mutex`:"
-#: src/concurrency/shared_state/example.md:5
-msgid ""
-"```rust,editable,compile_fail\n"
-"use std::thread;\n"
-"// use std::sync::{Arc, Mutex};\n"
-"\n"
-"fn main() {\n"
-" let v = vec![10, 20, 30];\n"
-" let handle = thread::spawn(|| {\n"
-" v.push(10);\n"
-" });\n"
-" v.push(1000);\n"
-"\n"
-" handle.join().unwrap();\n"
-" println!(\"v: {v:?}\");\n"
-"}\n"
-"```"
+#: src/concurrency/shared_state/example.md:6
+msgid "// use std::sync::{Arc, Mutex};\n"
msgstr ""
#: src/concurrency/shared_state/example.md:23
msgid "Possible solution:"
msgstr "Solución posible:"
-#: src/concurrency/shared_state/example.md:25
-msgid ""
-"```rust,editable\n"
-"use std::sync::{Arc, Mutex};\n"
-"use std::thread;\n"
-"\n"
-"fn main() {\n"
-" let v = Arc::new(Mutex::new(vec![10, 20, 30]));\n"
-"\n"
-" let v2 = Arc::clone(&v);\n"
-" let handle = thread::spawn(move || {\n"
-" let mut v2 = v2.lock().unwrap();\n"
-" v2.push(10);\n"
-" });\n"
-"\n"
-" {\n"
-" let mut v = v.lock().unwrap();\n"
-" v.push(1000);\n"
-" }\n"
-"\n"
-" handle.join().unwrap();\n"
-"\n"
-" println!(\"v: {v:?}\");\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/concurrency/shared_state/example.md:49
msgid "Notable parts:"
msgstr "Puntos a destacar:"
@@ -19514,49 +16273,91 @@ msgstr ""
"aparece más abajo en un archivo denominado `src/main.rs`, rellena los "
"espacios en blanco y comprueba que `cargo run` no presenta interbloqueos:"
-#: src/exercises/concurrency/dining-philosophers.md:19
+#: src/exercises/concurrency/dining-philosophers.md:28
+#: src/exercises/concurrency/dining-philosophers-async.md:23
msgid ""
-"```rust,compile_fail\n"
-"use std::sync::{mpsc, Arc, Mutex};\n"
-"use std::thread;\n"
-"use std::time::Duration;\n"
-"\n"
-"struct Fork;\n"
-"\n"
-"struct Philosopher {\n"
-" name: String,\n"
-" // left_fork: ...\n"
+"// left_fork: ...\n"
" // right_fork: ...\n"
" // thoughts: ...\n"
-"}\n"
-"\n"
-"impl Philosopher {\n"
-" fn think(&self) {\n"
-" self.thoughts\n"
-" .send(format!(\"Eureka! {} has a new idea!\", &self.name))\n"
-" .unwrap();\n"
-" }\n"
-"\n"
-" fn eat(&self) {\n"
-" // Pick up forks...\n"
-" println!(\"{} is eating...\", &self.name);\n"
-" thread::sleep(Duration::from_millis(10));\n"
-" }\n"
-"}\n"
-"\n"
-"static PHILOSOPHERS: &[&str] =\n"
-" &[\"Socrates\", \"Plato\", \"Aristotle\", \"Thales\", \"Pythagoras\"];\n"
-"\n"
-"fn main() {\n"
-" // Create forks\n"
-"\n"
-" // Create philosophers\n"
-"\n"
-" // Make each of them think and eat 100 times\n"
-"\n"
-" // Output their thoughts\n"
-"}\n"
-"```"
+msgstr ""
+
+#: src/exercises/concurrency/dining-philosophers.md:36
+#: src/exercises/concurrency/dining-philosophers-async.md:31
+#: src/exercises/concurrency/solutions-morning.md:24
+#: src/exercises/concurrency/solutions-afternoon.md:25
+msgid "\"Eureka! {} has a new idea!\""
+msgstr ""
+
+#: src/exercises/concurrency/dining-philosophers.md:41
+#: src/exercises/concurrency/dining-philosophers-async.md:36
+#: src/exercises/concurrency/solutions-afternoon.md:30
+msgid "// Pick up forks...\n"
+msgstr ""
+
+#: src/exercises/concurrency/dining-philosophers.md:42
+#: src/exercises/concurrency/dining-philosophers-async.md:37
+#: src/exercises/concurrency/solutions-morning.md:33
+#: src/exercises/concurrency/solutions-afternoon.md:37
+msgid "\"{} is eating...\""
+msgstr ""
+
+#: src/exercises/concurrency/dining-philosophers.md:48
+#: src/exercises/concurrency/dining-philosophers-async.md:43
+#: src/exercises/concurrency/solutions-morning.md:39
+#: src/exercises/concurrency/solutions-afternoon.md:45
+#, fuzzy
+#| msgid "HAL crates"
+msgid "\"Socrates\""
+msgstr "Crates HAL"
+
+#: src/exercises/concurrency/dining-philosophers.md:48
+#: src/exercises/concurrency/dining-philosophers-async.md:43
+#: src/exercises/concurrency/solutions-morning.md:39
+#: src/exercises/concurrency/solutions-afternoon.md:45
+msgid "\"Hypatia\""
+msgstr ""
+
+#: src/exercises/concurrency/dining-philosophers.md:48
+#: src/exercises/concurrency/dining-philosophers-async.md:43
+#: src/exercises/concurrency/solutions-morning.md:39
+#: src/exercises/concurrency/solutions-afternoon.md:45
+msgid "\"Plato\""
+msgstr ""
+
+#: src/exercises/concurrency/dining-philosophers.md:48
+#: src/exercises/concurrency/dining-philosophers-async.md:43
+#: src/exercises/concurrency/solutions-morning.md:39
+#: src/exercises/concurrency/solutions-afternoon.md:45
+msgid "\"Aristotle\""
+msgstr ""
+
+#: src/exercises/concurrency/dining-philosophers.md:48
+#: src/exercises/concurrency/dining-philosophers-async.md:43
+#: src/exercises/concurrency/solutions-morning.md:39
+#: src/exercises/concurrency/solutions-afternoon.md:45
+msgid "\"Pythagoras\""
+msgstr ""
+
+#: src/exercises/concurrency/dining-philosophers.md:51
+#: src/exercises/concurrency/dining-philosophers-async.md:47
+#: src/exercises/concurrency/solutions-afternoon.md:49
+msgid "// Create forks\n"
+msgstr ""
+
+#: src/exercises/concurrency/dining-philosophers.md:53
+#: src/exercises/concurrency/dining-philosophers-async.md:49
+#: src/exercises/concurrency/solutions-afternoon.md:53
+msgid "// Create philosophers\n"
+msgstr ""
+
+#: src/exercises/concurrency/dining-philosophers.md:55
+msgid "// Make each of them think and eat 100 times\n"
+msgstr ""
+
+#: src/exercises/concurrency/dining-philosophers.md:57
+#: src/exercises/concurrency/dining-philosophers-async.md:53
+#: src/exercises/concurrency/solutions-afternoon.md:88
+msgid "// Output their thoughts\n"
msgstr ""
#: src/exercises/concurrency/dining-philosophers.md:61
@@ -19594,15 +16395,6 @@ msgstr ""
"reqwest/). Crea un proyecto de Cargo y aplica `reqwest` como una dependencia "
"con:"
-#: src/exercises/concurrency/link-checker.md:11
-msgid ""
-"```shell\n"
-"cargo new link-checker\n"
-"cd link-checker\n"
-"cargo add --features blocking,rustls-tls reqwest\n"
-"```"
-msgstr ""
-
#: src/exercises/concurrency/link-checker.md:17
msgid ""
"If `cargo add` fails with `error: no such subcommand`, then please edit the "
@@ -19619,13 +16411,6 @@ msgstr ""
"También necesitarás una forma de encontrar enlaces. Podemos usar [`scraper`]"
"(https://docs.rs/scraper/) para eso:"
-#: src/exercises/concurrency/link-checker.md:22
-msgid ""
-"```shell\n"
-"cargo add scraper\n"
-"```"
-msgstr ""
-
#: src/exercises/concurrency/link-checker.md:26
msgid ""
"Finally, we'll need some way of handling errors. We use [`thiserror`]"
@@ -19634,16 +16419,6 @@ msgstr ""
"Por último, necesitaremos algún método para gestionar los errores. Para "
"ello, usaremos [`thiserror`](https://docs.rs/thiserror/):"
-#: src/exercises/concurrency/link-checker.md:29
-msgid ""
-"```shell\n"
-"cargo add thiserror\n"
-"```"
-msgstr ""
-"```shell\n"
-"cargo add thiserror\n"
-"```"
-
#: src/exercises/concurrency/link-checker.md:33
msgid ""
"The `cargo add` calls will update the `Cargo.toml` file to look like this:"
@@ -19693,154 +16468,48 @@ msgstr ""
msgid "Your `src/main.rs` file should look something like this:"
msgstr "El archivo `src/main.rs` debería tener un aspecto similar a este:"
-#: src/exercises/concurrency/link-checker.md:57
-msgid ""
-"```rust,compile_fail\n"
-"use reqwest::{blocking::Client, Url};\n"
-"use scraper::{Html, Selector};\n"
-"use thiserror::Error;\n"
-"\n"
-"#[derive(Error, Debug)]\n"
-"enum Error {\n"
-" #[error(\"request error: {0}\")]\n"
-" ReqwestError(#[from] reqwest::Error),\n"
-" #[error(\"bad http response: {0}\")]\n"
-" BadResponse(String),\n"
-"}\n"
-"\n"
-"#[derive(Debug)]\n"
-"struct CrawlCommand {\n"
-" url: Url,\n"
-" extract_links: bool,\n"
-"}\n"
-"\n"
-"fn visit_page(client: &Client, command: &CrawlCommand) -> Result, "
-"Error> {\n"
-" println!(\"Checking {:#}\", command.url);\n"
-" let response = client.get(command.url.clone()).send()?;\n"
-" if !response.status().is_success() {\n"
-" return Err(Error::BadResponse(response.status().to_string()));\n"
-" }\n"
-"\n"
-" let mut link_urls = Vec::new();\n"
-" if !command.extract_links {\n"
-" return Ok(link_urls);\n"
-" }\n"
-"\n"
-" let base_url = response.url().to_owned();\n"
-" let body_text = response.text()?;\n"
-" let document = Html::parse_document(&body_text);\n"
-"\n"
-" let selector = Selector::parse(\"a\").unwrap();\n"
-" let href_values = document\n"
-" .select(&selector)\n"
-" .filter_map(|element| element.value().attr(\"href\"));\n"
-" for href in href_values {\n"
-" match base_url.join(href) {\n"
-" Ok(link_url) => {\n"
-" link_urls.push(link_url);\n"
-" }\n"
-" Err(err) => {\n"
-" println!(\"On {base_url:#}: ignored unparsable {href:?}: "
-"{err}\");\n"
-" }\n"
-" }\n"
-" }\n"
-" Ok(link_urls)\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let client = Client::new();\n"
-" let start_url = Url::parse(\"https://www.google.org\").unwrap();\n"
-" let crawl_command = CrawlCommand{ url: start_url, extract_links: "
-"true };\n"
-" match visit_page(&client, &crawl_command) {\n"
-" Ok(links) => println!(\"Links: {links:#?}\"),\n"
-" Err(err) => println!(\"Could not extract links: {err:#}\"),\n"
-" }\n"
-"}\n"
-"```"
+#: src/exercises/concurrency/link-checker.md:64
+#: src/exercises/concurrency/solutions-morning.md:95
+msgid "\"request error: {0}\""
+msgstr ""
+
+#: src/exercises/concurrency/link-checker.md:66
+#: src/exercises/concurrency/solutions-morning.md:97
+msgid "\"bad http response: {0}\""
+msgstr ""
+
+#: src/exercises/concurrency/link-checker.md:77
+#: src/exercises/concurrency/solutions-morning.md:108
+msgid "\"Checking {:#}\""
+msgstr ""
+
+#: src/exercises/concurrency/link-checker.md:95
+#: src/exercises/concurrency/solutions-morning.md:126
+msgid "\"href\""
+msgstr ""
+
+#: src/exercises/concurrency/link-checker.md:102
+#: src/exercises/concurrency/solutions-morning.md:133
+msgid "\"On {base_url:#}: ignored unparsable {href:?}: {err}\""
+msgstr ""
+
+#: src/exercises/concurrency/link-checker.md:111
+#: src/exercises/concurrency/solutions-morning.md:246
+msgid "\"https://www.google.org\""
+msgstr ""
+
+#: src/exercises/concurrency/link-checker.md:114
+msgid "\"Links: {links:#?}\""
+msgstr ""
+
+#: src/exercises/concurrency/link-checker.md:115
+msgid "\"Could not extract links: {err:#}\""
msgstr ""
-"```rust,compile_fail\n"
-"use reqwest::{blocking::Client, Url};\n"
-"use scraper::{Html, Selector};\n"
-"use thiserror::Error;\n"
-"\n"
-"#[derive(Error, Debug)]\n"
-"enum Error {\n"
-" #[error(\"request error: {0}\")]\n"
-" ReqwestError(#[from] reqwest::Error),\n"
-" #[error(\"bad http response: {0}\")]\n"
-" BadResponse(String),\n"
-"}\n"
-"\n"
-"#[derive(Debug)]\n"
-"struct CrawlCommand {\n"
-" url: Url,\n"
-" extract_links: bool,\n"
-"}\n"
-"\n"
-"fn visit_page(client: &Client, command: &CrawlCommand) -> Result, "
-"Error> {\n"
-" println!(\"Checking {:#}\", command.url);\n"
-" let response = client.get(command.url.clone()).send()?;\n"
-" if !response.status().is_success() {\n"
-" return Err(Error::BadResponse(response.status().to_string()));\n"
-" }\n"
-"\n"
-" let mut link_urls = Vec::new();\n"
-" if !command.extract_links {\n"
-" return Ok(link_urls);\n"
-" }\n"
-"\n"
-" let base_url = response.url().to_owned();\n"
-" let body_text = response.text()?;\n"
-" let document = Html::parse_document(&body_text);\n"
-"\n"
-" let selector = Selector::parse(\"a\").unwrap();\n"
-" let href_values = document\n"
-" .select(&selector)\n"
-" .filter_map(|element| element.value().attr(\"href\"));\n"
-" for href in href_values {\n"
-" match base_url.join(href) {\n"
-" Ok(link_url) => {\n"
-" link_urls.push(link_url);\n"
-" }\n"
-" Err(err) => {\n"
-" println!(\"On {base_url:#}: ignored unparsable {href:?}: "
-"{err}\");\n"
-" }\n"
-" }\n"
-" }\n"
-" Ok(link_urls)\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let client = Client::new();\n"
-" let start_url = Url::parse(\"https://www.google.org\").unwrap();\n"
-" let crawl_command = CrawlCommand{ url: start_url, extract_links: "
-"true };\n"
-" match visit_page(&client, &crawl_command) {\n"
-" Ok(links) => println!(\"Links: {links:#?}\"),\n"
-" Err(err) => println!(\"Could not extract links: {err:#}\"),\n"
-" }\n"
-"}\n"
-"```"
#: src/exercises/concurrency/link-checker.md:120
msgid "Run the code in `src/main.rs` with"
msgstr "Ejecuta el código en `src/main.rs` con"
-#: src/exercises/concurrency/link-checker.md:122
-msgid ""
-"```shell\n"
-"cargo run\n"
-"```"
-msgstr ""
-"```shell\n"
-"cargo run\n"
-"```"
-
#: src/exercises/concurrency/link-checker.md:128
msgid ""
"Use threads to check the links in parallel: send the URLs to be checked to a "
@@ -19935,43 +16604,9 @@ msgstr ""
"En general, el código asíncrono de Rust se parece mucho al código secuencial "
"\"normal\":"
-#: src/async/async-await.md:5
-msgid ""
-"```rust,editable,compile_fail\n"
-"use futures::executor::block_on;\n"
-"\n"
-"async fn count_to(count: i32) {\n"
-" for i in 1..=count {\n"
-" println!(\"Count is: {i}!\");\n"
-" }\n"
-"}\n"
-"\n"
-"async fn async_main(count: i32) {\n"
-" count_to(count).await;\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" block_on(async_main(10));\n"
-"}\n"
-"```"
+#: src/async/async-await.md:10
+msgid "\"Count is: {i}!\""
msgstr ""
-"```rust,editable,compile_fail\n"
-"use futures::executor::block_on;\n"
-"\n"
-"async fn count_to(count: i32) {\n"
-" for i in 1..=count {\n"
-" println!(\"Count is: {i}!\");\n"
-" }\n"
-"}\n"
-"\n"
-"async fn async_main(count: i32) {\n"
-" count_to(count).await;\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" block_on(async_main(10));\n"
-"}\n"
-"```"
#: src/async/async-await.md:27
msgid ""
@@ -20041,25 +16676,6 @@ msgstr ""
"aún no se haya completado. Se puede sondear un futuro y `poll` devuelve un "
"[`Poll`](https://doc.rust-lang.org/std/task/enum.Poll.html)."
-#: src/async/futures.md:8
-msgid ""
-"```rust\n"
-"use std::pin::Pin;\n"
-"use std::task::Context;\n"
-"\n"
-"pub trait Future {\n"
-" type Output;\n"
-" fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll;\n"
-"}\n"
-"\n"
-"pub enum Poll {\n"
-" Ready(T),\n"
-" Pending,\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/async/futures.md:23
msgid ""
"An async function returns an `impl Future`. It's also possible (but "
@@ -20197,28 +16813,12 @@ msgstr "Una versión asíncrona de la biblioteca estándar."
msgid "A large ecosystem of libraries."
msgstr "Un amplio ecosistema de bibliotecas."
-#: src/async/runtimes/tokio.md:10
-msgid ""
-"```rust,editable,compile_fail\n"
-"use tokio::time;\n"
-"\n"
-"async fn count_to(count: i32) {\n"
-" for i in 1..=count {\n"
-" println!(\"Count in task: {i}!\");\n"
-" time::sleep(time::Duration::from_millis(5)).await;\n"
-" }\n"
-"}\n"
-"\n"
-"#[tokio::main]\n"
-"async fn main() {\n"
-" tokio::spawn(count_to(10));\n"
-"\n"
-" for i in 1..5 {\n"
-" println!(\"Main task: {i}\");\n"
-" time::sleep(time::Duration::from_millis(5)).await;\n"
-" }\n"
-"}\n"
-"```"
+#: src/async/runtimes/tokio.md:15
+msgid "\"Count in task: {i}!\""
+msgstr ""
+
+#: src/async/runtimes/tokio.md:25
+msgid "\"Main task: {i}\""
msgstr ""
#: src/async/runtimes/tokio.md:33
@@ -20275,48 +16875,28 @@ msgstr ""
"futuros secundarios , como una carrera de un temporizador y una operación de "
"E/S."
-#: src/async/tasks.md:10
-msgid ""
-"```rust,compile_fail\n"
-"use tokio::io::{self, AsyncReadExt, AsyncWriteExt};\n"
-"use tokio::net::TcpListener;\n"
-"\n"
-"#[tokio::main]\n"
-"async fn main() -> io::Result<()> {\n"
-" let listener = TcpListener::bind(\"127.0.0.1:6142\").await?;\n"
-"\tprintln!(\"listening on port 6142\");\n"
-"\n"
-" loop {\n"
-" let (mut socket, addr) = listener.accept().await?;\n"
-"\n"
-" println!(\"connection from {addr:?}\");\n"
-"\n"
-" tokio::spawn(async move {\n"
-" if let Err(e) = socket.write_all(b\"Who are you?\\n\").await {\n"
-" println!(\"socket error: {e:?}\");\n"
-" return;\n"
-" }\n"
-"\n"
-" let mut buf = vec![0; 1024];\n"
-" let reply = match socket.read(&mut buf).await {\n"
-" Ok(n) => {\n"
-" let name = std::str::from_utf8(&buf[..n]).unwrap()."
-"trim();\n"
-" format!(\"Thanks for dialing in, {name}!\\n\")\n"
-" }\n"
-" Err(e) => {\n"
-" println!(\"socket error: {e:?}\");\n"
-" return;\n"
-" }\n"
-" };\n"
-"\n"
-" if let Err(e) = socket.write_all(reply.as_bytes()).await {\n"
-" println!(\"socket error: {e:?}\");\n"
-" }\n"
-" });\n"
-" }\n"
-"}\n"
-"```"
+#: src/async/tasks.md:16
+msgid "\"127.0.0.1:6142\""
+msgstr ""
+
+#: src/async/tasks.md:17
+msgid "\"listening on port 6142\""
+msgstr ""
+
+#: src/async/tasks.md:22
+msgid "\"connection from {addr:?}\""
+msgstr ""
+
+#: src/async/tasks.md:25
+msgid "b\"Who are you?\\n\""
+msgstr ""
+
+#: src/async/tasks.md:26 src/async/tasks.md:37 src/async/tasks.md:43
+msgid "\"socket error: {e:?}\""
+msgstr ""
+
+#: src/async/tasks.md:34
+msgid "\"Thanks for dialing in, {name}!\\n\""
msgstr ""
#: src/async/tasks.md:52 src/async/control-flow/join.md:36
@@ -20357,36 +16937,24 @@ msgid ""
"Several crates have support for asynchronous channels. For instance `tokio`:"
msgstr "Varios crates admiten canales asíncronos. Por ejemplo, `tokio`:"
-#: src/async/channels.md:5
-msgid ""
-"```rust,editable,compile_fail\n"
-"use tokio::sync::mpsc::{self, Receiver};\n"
-"\n"
-"async fn ping_handler(mut input: Receiver<()>) {\n"
-" let mut count: usize = 0;\n"
-"\n"
-" while let Some(_) = input.recv().await {\n"
-" count += 1;\n"
-" println!(\"Received {count} pings so far.\");\n"
-" }\n"
-"\n"
-" println!(\"ping_handler complete\");\n"
-"}\n"
-"\n"
-"#[tokio::main]\n"
-"async fn main() {\n"
-" let (sender, receiver) = mpsc::channel(32);\n"
-" let ping_handler_task = tokio::spawn(ping_handler(receiver));\n"
-" for i in 0..10 {\n"
-" sender.send(()).await.expect(\"Failed to send ping.\");\n"
-" println!(\"Sent {} pings so far.\", i + 1);\n"
-" }\n"
-"\n"
-" drop(sender);\n"
-" ping_handler_task.await.expect(\"Something went wrong in ping handler "
-"task.\");\n"
-"}\n"
-"```"
+#: src/async/channels.md:13
+msgid "\"Received {count} pings so far.\""
+msgstr ""
+
+#: src/async/channels.md:16
+msgid "\"ping_handler complete\""
+msgstr ""
+
+#: src/async/channels.md:24
+msgid "\"Failed to send ping.\""
+msgstr ""
+
+#: src/async/channels.md:25
+msgid "\"Sent {} pings so far.\""
+msgstr ""
+
+#: src/async/channels.md:29
+msgid "\"Something went wrong in ping handler task.\""
msgstr ""
#: src/async/channels.md:35
@@ -20458,34 +17026,25 @@ msgstr ""
"devuelve una colección de sus resultados. Es similar a `Promise.all` en "
"JavaScript o `asyncio.gather` en Python."
-#: src/async/control-flow/join.md:7
-msgid ""
-"```rust,editable,compile_fail\n"
-"use anyhow::Result;\n"
-"use futures::future;\n"
-"use reqwest;\n"
-"use std::collections::HashMap;\n"
-"\n"
-"async fn size_of_page(url: &str) -> Result {\n"
-" let resp = reqwest::get(url).await?;\n"
-" Ok(resp.text().await?.len())\n"
-"}\n"
-"\n"
-"#[tokio::main]\n"
-"async fn main() {\n"
-" let urls: [&str; 4] = [\n"
-" \"https://google.com\",\n"
-" \"https://httpbin.org/ip\",\n"
-" \"https://play.rust-lang.org/\",\n"
-" \"BAD_URL\",\n"
-" ];\n"
-" let futures_iter = urls.into_iter().map(size_of_page);\n"
-" let results = future::join_all(futures_iter).await;\n"
-" let page_sizes_dict: HashMap<&str, Result> =\n"
-" urls.into_iter().zip(results.into_iter()).collect();\n"
-" println!(\"{:?}\", page_sizes_dict);\n"
-"}\n"
-"```"
+#: src/async/control-flow/join.md:21
+msgid "\"https://google.com\""
+msgstr ""
+
+#: src/async/control-flow/join.md:22
+msgid "\"https://httpbin.org/ip\""
+msgstr ""
+
+#: src/async/control-flow/join.md:23
+msgid "\"https://play.rust-lang.org/\""
+msgstr ""
+
+#: src/async/control-flow/join.md:24
+msgid "\"BAD_URL\""
+msgstr ""
+
+#: src/async/control-flow/join.md:30
+#: src/exercises/day-1/solutions-morning.md:78
+msgid "\"{:?}\""
msgstr ""
#: src/async/control-flow/join.md:38
@@ -20545,54 +17104,28 @@ msgstr ""
"future => statement`. Cuando `future` está listo, la instrucción se ejecuta "
"con las variables de `pattern` vinculadas al resultado de `future`."
-#: src/async/control-flow/select.md:13
-msgid ""
-"```rust,editable,compile_fail\n"
-"use tokio::sync::mpsc::{self, Receiver};\n"
-"use tokio::time::{sleep, Duration};\n"
-"\n"
-"#[derive(Debug, PartialEq)]\n"
-"enum Animal {\n"
-" Cat { name: String },\n"
-" Dog { name: String },\n"
-"}\n"
-"\n"
-"async fn first_animal_to_finish_race(\n"
-" mut cat_rcv: Receiver,\n"
-" mut dog_rcv: Receiver,\n"
-") -> Option {\n"
-" tokio::select! {\n"
-" cat_name = cat_rcv.recv() => Some(Animal::Cat { name: cat_name? }),\n"
-" dog_name = dog_rcv.recv() => Some(Animal::Dog { name: dog_name? })\n"
-" }\n"
-"}\n"
-"\n"
-"#[tokio::main]\n"
-"async fn main() {\n"
-" let (cat_sender, cat_receiver) = mpsc::channel(32);\n"
-" let (dog_sender, dog_receiver) = mpsc::channel(32);\n"
-" tokio::spawn(async move {\n"
-" sleep(Duration::from_millis(500)).await;\n"
-" cat_sender\n"
-" .send(String::from(\"Felix\"))\n"
-" .await\n"
-" .expect(\"Failed to send cat.\");\n"
-" });\n"
-" tokio::spawn(async move {\n"
-" sleep(Duration::from_millis(50)).await;\n"
-" dog_sender\n"
-" .send(String::from(\"Rex\"))\n"
-" .await\n"
-" .expect(\"Failed to send dog.\");\n"
-" });\n"
-"\n"
-" let winner = first_animal_to_finish_race(cat_receiver, dog_receiver)\n"
-" .await\n"
-" .expect(\"Failed to receive winner\");\n"
-"\n"
-" println!(\"Winner is {winner:?}\");\n"
-"}\n"
-"```"
+#: src/async/control-flow/select.md:40
+msgid "\"Felix\""
+msgstr ""
+
+#: src/async/control-flow/select.md:42
+msgid "\"Failed to send cat.\""
+msgstr ""
+
+#: src/async/control-flow/select.md:47
+msgid "\"Rex\""
+msgstr ""
+
+#: src/async/control-flow/select.md:49
+msgid "\"Failed to send dog.\""
+msgstr ""
+
+#: src/async/control-flow/select.md:54
+msgid "\"Failed to receive winner\""
+msgstr ""
+
+#: src/async/control-flow/select.md:56
+msgid "\"Winner is {winner:?}\""
msgstr ""
#: src/async/control-flow/select.md:62
@@ -20689,27 +17222,12 @@ msgstr ""
"tareas. Una solución alternativa y sencilla es utilizar métodos asíncronos "
"equivalentes siempre que sea posible."
-#: src/async/pitfalls/blocking-executor.md:7
-msgid ""
-"```rust,editable,compile_fail\n"
-"use futures::future::join_all;\n"
-"use std::time::Instant;\n"
-"\n"
-"async fn sleep_ms(start: &Instant, id: u64, duration_ms: u64) {\n"
-" std::thread::sleep(std::time::Duration::from_millis(duration_ms));\n"
-" println!(\n"
-" \"future {id} slept for {duration_ms}ms, finished after {}ms\",\n"
-" start.elapsed().as_millis()\n"
-" );\n"
-"}\n"
-"\n"
-"#[tokio::main(flavor = \"current_thread\")]\n"
-"async fn main() {\n"
-" let start = Instant::now();\n"
-" let sleep_futures = (1..=10).map(|t| sleep_ms(&start, t, t * 10));\n"
-" join_all(sleep_futures).await;\n"
-"}\n"
-"```"
+#: src/async/pitfalls/blocking-executor.md:14
+msgid "\"future {id} slept for {duration_ms}ms, finished after {}ms\""
+msgstr ""
+
+#: src/async/pitfalls/blocking-executor.md:19
+msgid "\"current_thread\""
msgstr ""
#: src/async/pitfalls/blocking-executor.md:29
@@ -20794,61 +17312,42 @@ msgstr ""
"usa el mismo futuro varias veces en un `select!`, se suelen producir "
"problemas en los valores fijados."
-#: src/async/pitfalls/pin.md:12
+#: src/async/pitfalls/pin.md:16
msgid ""
-"```rust,editable,compile_fail\n"
-"use tokio::sync::{mpsc, oneshot};\n"
-"use tokio::task::spawn;\n"
-"use tokio::time::{sleep, Duration};\n"
-"\n"
"// A work item. In this case, just sleep for the given time and respond\n"
"// with a message on the `respond_on` channel.\n"
-"#[derive(Debug)]\n"
-"struct Work {\n"
-" input: u32,\n"
-" respond_on: oneshot::Sender,\n"
-"}\n"
-"\n"
-"// A worker which listens for work on a queue and performs it.\n"
-"async fn worker(mut work_queue: mpsc::Receiver) {\n"
-" let mut iterations = 0;\n"
-" loop {\n"
-" tokio::select! {\n"
-" Some(work) = work_queue.recv() => {\n"
-" sleep(Duration::from_millis(10)).await; // Pretend to work.\n"
-" work.respond_on\n"
-" .send(work.input * 1000)\n"
-" .expect(\"failed to send response\");\n"
-" iterations += 1;\n"
-" }\n"
-" // TODO: report number of iterations every 100ms\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"// A requester which requests work and waits for it to complete.\n"
-"async fn do_work(work_queue: &mpsc::Sender, input: u32) -> u32 {\n"
-" let (tx, rx) = oneshot::channel();\n"
-" work_queue\n"
-" .send(Work {\n"
-" input,\n"
-" respond_on: tx,\n"
-" })\n"
-" .await\n"
-" .expect(\"failed to send on work queue\");\n"
-" rx.await.expect(\"failed waiting for response\")\n"
-"}\n"
-"\n"
-"#[tokio::main]\n"
-"async fn main() {\n"
-" let (tx, rx) = mpsc::channel(10);\n"
-" spawn(worker(rx));\n"
-" for i in 0..100 {\n"
-" let resp = do_work(&tx, i).await;\n"
-" println!(\"work result for iteration {i}: {resp}\");\n"
-" }\n"
-"}\n"
-"```"
+msgstr ""
+
+#: src/async/pitfalls/pin.md:24
+msgid "// A worker which listens for work on a queue and performs it.\n"
+msgstr ""
+
+#: src/async/pitfalls/pin.md:31
+msgid "// Pretend to work.\n"
+msgstr ""
+
+#: src/async/pitfalls/pin.md:34
+msgid "\"failed to send response\""
+msgstr ""
+
+#: src/async/pitfalls/pin.md:37
+msgid "// TODO: report number of iterations every 100ms\n"
+msgstr ""
+
+#: src/async/pitfalls/pin.md:41
+msgid "// A requester which requests work and waits for it to complete.\n"
+msgstr ""
+
+#: src/async/pitfalls/pin.md:51
+msgid "\"failed to send on work queue\""
+msgstr ""
+
+#: src/async/pitfalls/pin.md:52
+msgid "\"failed waiting for response\""
+msgstr ""
+
+#: src/async/pitfalls/pin.md:61
+msgid "\"work result for iteration {i}: {resp}\""
msgstr ""
#: src/async/pitfalls/pin.md:68
@@ -20881,19 +17380,6 @@ msgid ""
msgstr ""
"En su lugar, añade un `timeout_fut` que contenga ese futuro fuera de `loop`:"
-#: src/async/pitfalls/pin.md:79
-msgid ""
-"```rust,compile_fail\n"
-"let mut timeout_fut = sleep(Duration::from_millis(100));\n"
-"loop {\n"
-" select! {\n"
-" ..,\n"
-" _ = timeout_fut => { println!(..); },\n"
-" }\n"
-"}\n"
-"```"
-msgstr ""
-
#: src/async/pitfalls/pin.md:88
msgid ""
"This still doesn't work. Follow the compiler errors, adding `&mut` to the "
@@ -20904,20 +17390,7 @@ msgstr ""
"`timeout_fut` en `select!` para ir despejando el problema. A continuación, "
"usa `Box::pin`:"
-#: src/async/pitfalls/pin.md:92
-msgid ""
-"```rust,compile_fail\n"
-"let mut timeout_fut = Box::pin(sleep(Duration::from_millis(100)));\n"
-"loop {\n"
-" select! {\n"
-" ..,\n"
-" _ = &mut timeout_fut => { println!(..); },\n"
-" }\n"
-"}\n"
-"```"
-msgstr ""
-
-#: src/async/pitfalls/pin.md:102
+#: src/async/pitfalls/pin.md:102
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 "
@@ -20966,50 +17439,12 @@ msgstr ""
"El crate [async_trait](https://docs.rs/async-trait/latest/async_trait/) "
"proporciona una solución mediante una macro:"
-#: src/async/pitfalls/async-traits.md:7
-msgid ""
-"```rust,editable,compile_fail\n"
-"use async_trait::async_trait;\n"
-"use std::time::Instant;\n"
-"use tokio::time::{sleep, Duration};\n"
-"\n"
-"#[async_trait]\n"
-"trait Sleeper {\n"
-" async fn sleep(&self);\n"
-"}\n"
-"\n"
-"struct FixedSleeper {\n"
-" sleep_ms: u64,\n"
-"}\n"
-"\n"
-"#[async_trait]\n"
-"impl Sleeper for FixedSleeper {\n"
-" async fn sleep(&self) {\n"
-" sleep(Duration::from_millis(self.sleep_ms)).await;\n"
-" }\n"
-"}\n"
-"\n"
-"async fn run_all_sleepers_multiple_times(sleepers: Vec>, "
-"n_times: usize) {\n"
-" for _ in 0..n_times {\n"
-" println!(\"running all sleepers..\");\n"
-" for sleeper in &sleepers {\n"
-" let start = Instant::now();\n"
-" sleeper.sleep().await;\n"
-" println!(\"slept for {}ms\", start.elapsed().as_millis());\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"#[tokio::main]\n"
-"async fn main() {\n"
-" let sleepers: Vec> = vec![\n"
-" Box::new(FixedSleeper { sleep_ms: 50 }),\n"
-" Box::new(FixedSleeper { sleep_ms: 100 }),\n"
-" ];\n"
-" run_all_sleepers_multiple_times(sleepers, 5).await;\n"
-"}\n"
-"```"
+#: src/async/pitfalls/async-traits.md:30
+msgid "\"running all sleepers..\""
+msgstr ""
+
+#: src/async/pitfalls/async-traits.md:34
+msgid "\"slept for {}ms\""
msgstr ""
#: src/async/pitfalls/async-traits.md:51
@@ -21056,72 +17491,18 @@ msgstr ""
"incluso cuando se cancelen los futuros. Por ejemplo, no debería sufrir "
"interbloqueos o perder datos."
-#: src/async/pitfalls/cancellation.md:8
-msgid ""
-"```rust,editable,compile_fail\n"
-"use std::io::{self, ErrorKind};\n"
-"use std::time::Duration;\n"
-"use tokio::io::{AsyncReadExt, AsyncWriteExt, DuplexStream};\n"
-"\n"
-"struct LinesReader {\n"
-" stream: DuplexStream,\n"
-"}\n"
-"\n"
-"impl LinesReader {\n"
-" fn new(stream: DuplexStream) -> Self {\n"
-" Self { stream }\n"
-" }\n"
-"\n"
-" async fn next(&mut self) -> io::Result> {\n"
-" let mut bytes = Vec::new();\n"
-" let mut buf = [0];\n"
-" while self.stream.read(&mut buf[..]).await? != 0 {\n"
-" bytes.push(buf[0]);\n"
-" if buf[0] == b'\\n' {\n"
-" break;\n"
-" }\n"
-" }\n"
-" if bytes.is_empty() {\n"
-" return Ok(None)\n"
-" }\n"
-" let s = String::from_utf8(bytes)\n"
-" .map_err(|_| io::Error::new(ErrorKind::InvalidData, \"not "
-"UTF-8\"))?;\n"
-" Ok(Some(s))\n"
-" }\n"
-"}\n"
-"\n"
-"async fn slow_copy(source: String, mut dest: DuplexStream) -> std::io::"
-"Result<()> {\n"
-" for b in source.bytes() {\n"
-" dest.write_u8(b).await?;\n"
-" tokio::time::sleep(Duration::from_millis(10)).await\n"
-" }\n"
-" Ok(())\n"
-"}\n"
-"\n"
-"#[tokio::main]\n"
-"async fn main() -> std::io::Result<()> {\n"
-" let (client, server) = tokio::io::duplex(5);\n"
-" let handle = tokio::spawn(slow_copy(\"hi\\nthere\\n\".to_owned(), "
-"client));\n"
-"\n"
-" let mut lines = LinesReader::new(server);\n"
-" let mut interval = tokio::time::interval(Duration::from_millis(60));\n"
-" loop {\n"
-" tokio::select! {\n"
-" _ = interval.tick() => println!(\"tick!\"),\n"
-" line = lines.next() => if let Some(l) = line? {\n"
-" print!(\"{}\", l)\n"
-" } else {\n"
-" break\n"
-" },\n"
-" }\n"
-" }\n"
-" handle.await.unwrap()?;\n"
-" Ok(())\n"
-"}\n"
-"```"
+#: src/async/pitfalls/cancellation.md:35
+#, fuzzy
+#| msgid "UTF-8"
+msgid "\"not UTF-8\""
+msgstr "UTF-8"
+
+#: src/async/pitfalls/cancellation.md:51
+msgid "\"hi\\nthere\\n\""
+msgstr ""
+
+#: src/async/pitfalls/cancellation.md:57
+msgid "\"tick!\""
msgstr ""
#: src/async/pitfalls/cancellation.md:72
@@ -21159,28 +17540,8 @@ msgstr ""
"`LinesReader` se puede configurar para que no se cancele marcando `buf` como "
"parte del _struct_:"
-#: src/async/pitfalls/cancellation.md:83
-msgid ""
-"```rust,compile_fail\n"
-"struct LinesReader {\n"
-" stream: DuplexStream,\n"
-" bytes: Vec,\n"
-" buf: [u8; 1],\n"
-"}\n"
-"\n"
-"impl LinesReader {\n"
-" fn new(stream: DuplexStream) -> Self {\n"
-" Self { stream, bytes: Vec::new(), buf: [0] }\n"
-" }\n"
-" async fn next(&mut self) -> io::Result> {\n"
-" // prefix buf and bytes with self.\n"
-" // ...\n"
-" let raw = std::mem::take(&mut self.bytes);\n"
-" let s = String::from_utf8(raw)\n"
-" // ...\n"
-" }\n"
-"}\n"
-"```"
+#: src/async/pitfalls/cancellation.md:95
+msgid "// prefix buf and bytes with self.\n"
msgstr ""
#: src/async/pitfalls/cancellation.md:104
@@ -21261,52 +17622,9 @@ msgstr ""
"aparece más abajo en un archivo denominado `src/main.rs`, rellena los "
"espacios en blanco y comprueba que `cargo run` no presenta interbloqueos:"
-#: src/exercises/concurrency/dining-philosophers-async.md:13
-msgid ""
-"```rust,compile_fail\n"
-"use std::sync::Arc;\n"
-"use tokio::time;\n"
-"use tokio::sync::mpsc::{self, Sender};\n"
-"use tokio::sync::Mutex;\n"
-"\n"
-"struct Fork;\n"
-"\n"
-"struct Philosopher {\n"
-" name: String,\n"
-" // left_fork: ...\n"
-" // right_fork: ...\n"
-" // thoughts: ...\n"
-"}\n"
-"\n"
-"impl Philosopher {\n"
-" async fn think(&self) {\n"
-" self.thoughts\n"
-" .send(format!(\"Eureka! {} has a new idea!\", &self.name))."
-"await\n"
-" .unwrap();\n"
-" }\n"
-"\n"
-" async fn eat(&self) {\n"
-" // Pick up forks...\n"
-" println!(\"{} is eating...\", &self.name);\n"
-" time::sleep(time::Duration::from_millis(5)).await;\n"
-" }\n"
-"}\n"
-"\n"
-"static PHILOSOPHERS: &[&str] =\n"
-" &[\"Socrates\", \"Plato\", \"Aristotle\", \"Thales\", \"Pythagoras\"];\n"
-"\n"
-"#[tokio::main]\n"
-"async fn main() {\n"
-" // Create forks\n"
-"\n"
-" // Create philosophers\n"
-"\n"
-" // Make them think and eat\n"
-"\n"
-" // Output their thoughts\n"
-"}\n"
-"```"
+#: src/exercises/concurrency/dining-philosophers-async.md:51
+#: src/exercises/concurrency/solutions-afternoon.md:77
+msgid "// Make them think and eat\n"
msgstr ""
#: src/exercises/concurrency/dining-philosophers-async.md:57
@@ -21375,7 +17693,9 @@ msgid "Create a new Cargo project and add the following dependencies:"
msgstr "Crea un proyecto de Cargo y añade las siguientes dependencias:"
#: src/exercises/concurrency/chat-app.md:15
-msgid "`Cargo.toml`:"
+#, fuzzy
+#| msgid "`Cargo.toml`:"
+msgid "_Cargo.toml_:"
msgstr "`Cargo.toml`:"
#: src/exercises/concurrency/chat-app.md:19
@@ -21497,82 +17817,47 @@ msgstr ""
"tarea es completar estos archivos como se describe a continuación. "
#: src/exercises/concurrency/chat-app.md:59
-#: src/exercises/concurrency/solutions-afternoon.md:123
-msgid "`src/bin/server.rs`:"
+#: src/exercises/concurrency/solutions-afternoon.md:99
+#, fuzzy
+#| msgid "`src/bin/server.rs`:"
+msgid "_src/bin/server.rs_:"
msgstr "`src/bin/server.rs`:"
-#: src/exercises/concurrency/chat-app.md:63
-msgid ""
-"```rust,compile_fail\n"
-"use futures_util::sink::SinkExt;\n"
-"use futures_util::stream::StreamExt;\n"
-"use std::error::Error;\n"
-"use std::net::SocketAddr;\n"
-"use tokio::net::{TcpListener, TcpStream};\n"
-"use tokio::sync::broadcast::{channel, Sender};\n"
-"use tokio_websockets::{Message, ServerBuilder, WebsocketStream};\n"
-"\n"
-"async fn handle_connection(\n"
-" addr: SocketAddr,\n"
-" mut ws_stream: WebsocketStream,\n"
-" bcast_tx: Sender,\n"
-") -> Result<(), Box> {\n"
-"\n"
-" // TODO: For a hint, see the description of the task below.\n"
-"\n"
-"}\n"
-"\n"
-"#[tokio::main]\n"
-"async fn main() -> Result<(), Box> {\n"
-" let (bcast_tx, _) = channel(16);\n"
-"\n"
-" let listener = TcpListener::bind(\"127.0.0.1:2000\").await?;\n"
-" println!(\"listening on port 2000\");\n"
-"\n"
-" loop {\n"
-" let (socket, addr) = listener.accept().await?;\n"
-" println!(\"New connection from {addr:?}\");\n"
-" let bcast_tx = bcast_tx.clone();\n"
-" tokio::spawn(async move {\n"
-" // Wrap the raw TCP stream into a websocket.\n"
-" let ws_stream = ServerBuilder::new().accept(socket).await?;\n"
-"\n"
-" handle_connection(addr, ws_stream, bcast_tx).await\n"
-" });\n"
-" }\n"
-"}\n"
-"```"
+#: src/exercises/concurrency/chat-app.md:78
+#: src/exercises/concurrency/chat-app.md:125
+msgid "// TODO: For a hint, see the description of the task below.\n"
+msgstr ""
+
+#: src/exercises/concurrency/chat-app.md:86
+#: src/exercises/concurrency/solutions-afternoon.md:149
+msgid "\"127.0.0.1:2000\""
+msgstr ""
+
+#: src/exercises/concurrency/chat-app.md:87
+#: src/exercises/concurrency/solutions-afternoon.md:150
+msgid "\"listening on port 2000\""
+msgstr ""
+
+#: src/exercises/concurrency/chat-app.md:91
+#: src/exercises/concurrency/solutions-afternoon.md:154
+msgid "\"New connection from {addr:?}\""
+msgstr ""
+
+#: src/exercises/concurrency/chat-app.md:94
+#: src/exercises/concurrency/solutions-afternoon.md:157
+msgid "// Wrap the raw TCP stream into a websocket.\n"
msgstr ""
#: src/exercises/concurrency/chat-app.md:103
-#: src/exercises/concurrency/solutions-afternoon.md:210
-msgid "`src/bin/client.rs`:"
+#: src/exercises/concurrency/solutions-afternoon.md:166
+#, fuzzy
+#| msgid "`src/bin/client.rs`:"
+msgid "_src/bin/client.rs_:"
msgstr "`src/bin/client.rs`:"
-#: src/exercises/concurrency/chat-app.md:107
-msgid ""
-"```rust,compile_fail\n"
-"use futures_util::stream::StreamExt;\n"
-"use futures_util::SinkExt;\n"
-"use http::Uri;\n"
-"use tokio::io::{AsyncBufReadExt, BufReader};\n"
-"use tokio_websockets::{ClientBuilder, Message};\n"
-"\n"
-"#[tokio::main]\n"
-"async fn main() -> Result<(), tokio_websockets::Error> {\n"
-" let (mut ws_stream, _) =\n"
-" ClientBuilder::from_uri(Uri::from_static(\"ws://127.0.0.1:2000\"))\n"
-" .connect()\n"
-" .await?;\n"
-"\n"
-" let stdin = tokio::io::stdin();\n"
-" let mut stdin = BufReader::new(stdin).lines();\n"
-"\n"
-"\n"
-" // TODO: For a hint, see the description of the task below.\n"
-"\n"
-"}\n"
-"```"
+#: src/exercises/concurrency/chat-app.md:117
+#: src/exercises/concurrency/solutions-afternoon.md:178
+msgid "\"ws://127.0.0.1:2000\""
msgstr ""
#: src/exercises/concurrency/chat-app.md:130
@@ -21583,24 +17868,10 @@ msgstr "Ejecutar los binarios"
msgid "Run the server with:"
msgstr "Ejecuta el servidor con:"
-#: src/exercises/concurrency/chat-app.md:133
-msgid ""
-"```shell\n"
-"cargo run --bin server\n"
-"```"
-msgstr ""
-
#: src/exercises/concurrency/chat-app.md:137
msgid "and the client with:"
msgstr "y el cliente con:"
-#: src/exercises/concurrency/chat-app.md:139
-msgid ""
-"```shell\n"
-"cargo run --bin client\n"
-"```"
-msgstr ""
-
#: src/exercises/concurrency/chat-app.md:145
msgid "Implement the `handle_connection` function in `src/bin/server.rs`."
msgstr "Implementa la función `handle_connection` en `src/bin/server.rs`."
@@ -21659,161 +17930,515 @@ msgstr ""
"mejorarlo, [ponte en contacto con nosotros en GitHub](https://github.com/"
"google/comprehensive-rust/discussions). Nos encantaría saber tu opinión."
-#: src/other-resources.md:1
-msgid "Other Rust Resources"
-msgstr "Otros recursos de Rust"
+#: src/glossary.md:3
+msgid ""
+"The following is a glossary which aims to give a short definition of many "
+"Rust terms. For translations, this also serves to connect the term back to "
+"the English original."
+msgstr ""
-#: src/other-resources.md:3
+#: src/glossary.md:30
msgid ""
-"The Rust community has created a wealth of high-quality and free resources "
-"online."
+"allocate: \n"
+"Dynamic memory allocation on [the heap](memory-management/stack-vs-heap.md)."
msgstr ""
-"La comunidad de Rust ha creado una gran cantidad de recursos online sin "
-"coste y de gran calidad."
-#: src/other-resources.md:6
-msgid "Official Documentation"
-msgstr "Documentación oficial"
+#: src/glossary.md:32
+msgid "argument:"
+msgstr ""
-#: src/other-resources.md:8
-msgid "The Rust project hosts many resources. These cover Rust in general:"
+#: src/glossary.md:33
+msgid ""
+"Bare-metal Rust: \n"
+"Low-level Rust development, often deployed to a system without an operating "
+"system. See [Bare-metal Rust](bare-metal.md)."
msgstr ""
-"El proyecto Rust cuenta con muchos recursos. Estos tratan sobre Rust en "
-"general:"
-#: src/other-resources.md:10
+#: src/glossary.md:36
msgid ""
-"[The Rust Programming Language](https://doc.rust-lang.org/book/): the "
-"canonical free book about Rust. Covers the language in detail and includes a "
-"few projects for people to build."
+"block: \n"
+"See [Blocks](control-flow/blocks.md) and _scope_."
msgstr ""
-"[The Rust Programming Language](https://doc.rust-lang.org/book/): el libro "
-"canónico sobre Rust sin coste alguno. Trata el lenguaje de forma detallada e "
-"incluye algunos proyectos que los usuarios pueden compilar."
-#: src/other-resources.md:13
+#: src/glossary.md:38
msgid ""
-"[Rust By Example](https://doc.rust-lang.org/rust-by-example/): covers the "
-"Rust syntax via a series of examples which showcase different constructs. "
-"Sometimes includes small exercises where you are asked to expand on the code "
-"in the examples."
+"borrow: \n"
+"See [Borrowing](ownership/borrowing.md)."
msgstr ""
-"[Rust by Example](https://doc.rust-lang.org/rust-by-example/): trata la "
-"sintaxis de Rust a través de una serie de ejemplos que muestran distintas "
-"construcciones. A veces incluye pequeños ejercicios en los que se te pide "
-"que amplíes el código de los ejemplos."
-#: src/other-resources.md:17
+#: src/glossary.md:40
msgid ""
-"[Rust Standard Library](https://doc.rust-lang.org/std/): full documentation "
-"of the standard library for Rust."
+"borrow checker: \n"
+"The part of the Rust compiler which checks that all borrows are valid."
msgstr ""
-"[La biblioteca estándar de Rust](https://doc.rust-lang.org/std/): "
-"documentación completa de la biblioteca estándar de Rust."
-#: src/other-resources.md:19
+#: src/glossary.md:42
msgid ""
-"[The Rust Reference](https://doc.rust-lang.org/reference/): an incomplete "
-"book which describes the Rust grammar and memory model."
+"brace: \n"
+"`{` and `}`. Also called _curly brace_, they delimit _blocks_."
msgstr ""
-"[The Rust Reference](https://doc.rust-lang.org/reference/): un libro "
-"incompleto que describe la gramática y el modelo de memoria de Rust."
-#: src/other-resources.md:22
-msgid "More specialized guides hosted on the official Rust site:"
-msgstr "Consulta guías más especializadas en el sitio oficial de Rust:"
+#: src/glossary.md:44
+msgid "build:"
+msgstr ""
-#: src/other-resources.md:24
+#: src/glossary.md:45
+msgid "call:"
+msgstr ""
+
+#: src/glossary.md:46
msgid ""
-"[The Rustonomicon](https://doc.rust-lang.org/nomicon/): covers unsafe Rust, "
-"including working with raw pointers and interfacing with other languages "
-"(FFI)."
+"channel: \n"
+"Used to safely pass messages [between threads](concurrency/channels.md)."
msgstr ""
-"[The Rustonomicon](https://doc.rust-lang.org/nomicon/): trata de Rust "
-"inseguro, incluido cómo trabajar con punteros sin formato e interactuar con "
-"otros lenguajes (FFI)."
-#: src/other-resources.md:27
+#: src/glossary.md:48
msgid ""
-"[Asynchronous Programming in Rust](https://rust-lang.github.io/async-book/): "
-"covers the new asynchronous programming model which was introduced after the "
-"Rust Book was written."
+"Comprehensive Rust 🦀: \n"
+"The courses here are jointly called Comprehensive Rust 🦀."
msgstr ""
-"[Asynchronous Programming in Rust](https://rust-lang.github.io/async-book/): "
-"incluye el nuevo modelo de programación asíncrona que se introdujo después "
-"de que se escribiera el libro de Rust."
-#: src/other-resources.md:30
+#: src/glossary.md:50
+#, fuzzy
+#| msgid "Concurrency: Morning"
+msgid "concurrency:"
+msgstr "Concurrencia: mañana"
+
+#: src/glossary.md:51
msgid ""
-"[The Embedded Rust Book](https://doc.rust-lang.org/stable/embedded-book/): "
-"an introduction to using Rust on embedded devices without an operating "
-"system."
+"Concurrency in Rust: \n"
+"See [Concurrency in Rust](concurrency.md)."
msgstr ""
-"[The Embedded Rust Book](https://doc.rust-lang.org/stable/embedded-book/): "
-"una introducción sobre el uso de Rust en dispositivos integrados sin sistema "
-"operativo."
-#: src/other-resources.md:33
-msgid "Unofficial Learning Material"
-msgstr "Material de formación no oficial"
+#: src/glossary.md:53
+#, fuzzy
+#| msgid "Constant"
+msgid "constant:"
+msgstr "Constante"
-#: src/other-resources.md:35
-msgid "A small selection of other guides and tutorial for Rust:"
-msgstr "Una pequeña selección de otras guías y tutoriales sobre Rust:"
+#: src/glossary.md:54
+#, fuzzy
+#| msgid "Control Flow"
+msgid "control flow:"
+msgstr "Control de Flujo"
-#: src/other-resources.md:37
-msgid ""
-"[Learn Rust the Dangerous Way](http://cliffle.com/p/dangerust/): covers Rust "
-"from the perspective of low-level C programmers."
+#: src/glossary.md:55
+msgid "crash:"
msgstr ""
-"[Learn Rust the Dangerous Way](http://cliffle.com/p/dangerust/): trata Rust "
-"desde la perspectiva de los programadores de C de bajo nivel."
-#: src/other-resources.md:39
-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."
+#: src/glossary.md:56
+#, fuzzy
+#| msgid "`Duration`"
+msgid "enumeration:"
+msgstr "`Duration`"
+
+#: src/glossary.md:57
+#, fuzzy
+#| msgid "`Error`"
+msgid "error:"
+msgstr "`Error`"
+
+#: src/glossary.md:58
+#, fuzzy
+#| msgid "Error Handling"
+msgid "error handling:"
+msgstr "Manejo de Errores"
+
+#: src/glossary.md:59
+#, fuzzy
+#| msgid "Exercises"
+msgid "exercise:"
+msgstr "Ejercicios"
+
+#: src/glossary.md:60
+#, fuzzy
+#| msgid "Functions"
+msgid "function:"
+msgstr "Funciones"
+
+#: src/glossary.md:61
+#, fuzzy
+#| msgid "Garbage Collection"
+msgid "garbage collector:"
+msgstr "Recolección de memoria residual"
+
+#: src/glossary.md:62
+#, fuzzy
+#| msgid "Generics"
+msgid "generics:"
+msgstr "Genéricos"
+
+#: src/glossary.md:63
+msgid "immutable:"
msgstr ""
-"[Rust for Embedded C Programmers](https://docs.opentitan.org/doc/ug/"
-"rust_for_c/): explica Rust desde la perspectiva de los desarrolladores que "
-"escriben _firmware_ en C."
-#: src/other-resources.md:42
-msgid ""
-"[Rust for professionals](https://overexact.com/rust-for-professionals/): "
-"covers the syntax of Rust using side-by-side comparisons with other "
-"languages such as C, C++, Java, JavaScript, and Python."
+#: src/glossary.md:64
+#, fuzzy
+#| msgid "Integration Tests"
+msgid "integration test:"
+msgstr "Pruebas de Integración"
+
+#: src/glossary.md:65
+msgid "keyword:"
msgstr ""
-"[Rust for professonals](https://overexact.com/rust-for-professionals/): "
-"trata la sintaxis de Rust comparándola con otros lenguajes, como C, C++, "
-"Java, JavaScript y Python."
-#: src/other-resources.md:45
-msgid ""
-"[Rust on Exercism](https://exercism.org/tracks/rust): 100+ exercises to help "
-"you learn Rust."
+#: src/glossary.md:66
+#, fuzzy
+#| msgid "Library"
+msgid "library:"
+msgstr "Biblioteca"
+
+#: src/glossary.md:67
+msgid "macro:"
msgstr ""
-"[Rust on Exercism](https://exercism.org/tracks/rust): más de 100 ejercicios "
-"para aprender Rust."
-#: src/other-resources.md:47
-msgid ""
-"[Ferrous Teaching Material](https://ferrous-systems.github.io/teaching-"
-"material/index.html): a series of small presentations covering both basic "
-"and advanced part of the Rust language. Other topics such as WebAssembly, "
-"and async/await are also covered."
+#: src/glossary.md:68
+#, fuzzy
+#| msgid "Calling Unsafe Functions"
+msgid "main function:"
+msgstr "Llamar Funciones Unsafe (Inseguras)"
+
+#: src/glossary.md:69
+msgid "match:"
msgstr ""
-"[Ferrous Teaching Material](https://ferrous-systems.github.io/teaching-"
-"material/index.html): una serie de pequeñas presentaciones que cubren tanto "
-"la parte básica como la parte más avanzada del lenguaje Rust. También se "
-"tratan otros temas como WebAssembly y async/await."
-#: src/other-resources.md:52
-msgid ""
-"[Beginner's Series to Rust](https://docs.microsoft.com/en-us/shows/beginners-"
-"series-to-rust/) and [Take your first steps with Rust](https://docs."
-"microsoft.com/en-us/learn/paths/rust-first-steps/): two Rust guides aimed at "
+#: src/glossary.md:70
+#, fuzzy
+#| msgid "Memory leaks."
+msgid "memory leak:"
+msgstr "Pérdidas de memoria."
+
+#: src/glossary.md:71
+#, fuzzy
+#| msgid "Methods"
+msgid "method:"
+msgstr "Métodos"
+
+#: src/glossary.md:72
+#, fuzzy
+#| msgid "Modules"
+msgid "module:"
+msgstr "Módulos"
+
+#: src/glossary.md:73
+msgid "move:"
+msgstr ""
+
+#: src/glossary.md:74
+#, fuzzy
+#| msgid "Can be mutable"
+msgid "mutable:"
+msgstr "Puede ser mutable"
+
+#: src/glossary.md:75
+#, fuzzy
+#| msgid "Ownership"
+msgid "ownership:"
+msgstr "Ownership"
+
+#: src/glossary.md:76
+msgid "panic:"
+msgstr ""
+
+#: src/glossary.md:77
+msgid "parameter:"
+msgstr ""
+
+#: src/glossary.md:78
+msgid "pattern:"
+msgstr ""
+
+#: src/glossary.md:79
+msgid "payload:"
+msgstr ""
+
+#: src/glossary.md:80
+msgid "program:"
+msgstr ""
+
+#: src/glossary.md:81
+msgid "programming language:"
+msgstr ""
+
+#: src/glossary.md:82
+#, fuzzy
+#| msgid "Driver"
+msgid "receiver:"
+msgstr "Conductor"
+
+#: src/glossary.md:83
+msgid "reference counting:"
+msgstr ""
+
+#: src/glossary.md:84
+msgid "return:"
+msgstr ""
+
+#: src/glossary.md:85
+#, fuzzy
+#| msgid "Rustdoc"
+msgid "Rust:"
+msgstr "Rustdoc"
+
+#: src/glossary.md:86
+msgid ""
+"Rust Fundamentals: \n"
+"Days 1 to 3 of this course."
+msgstr ""
+
+#: src/glossary.md:88
+msgid ""
+"Rust in Android: \n"
+"See [Rust in Android](android.md)."
+msgstr ""
+
+#: src/glossary.md:90
+msgid "safe:"
+msgstr ""
+
+#: src/glossary.md:91
+msgid "scope:"
+msgstr ""
+
+#: src/glossary.md:92
+#, fuzzy
+#| msgid "Standard Library"
+msgid "standard library:"
+msgstr "Biblioteca estándar"
+
+#: src/glossary.md:93
+#, fuzzy
+#| msgid "`static`"
+msgid "static:"
+msgstr "`static`"
+
+#: src/glossary.md:94
+#, fuzzy
+#| msgid "String"
+msgid "string:"
+msgstr "String"
+
+#: src/glossary.md:95
+#, fuzzy
+#| msgid "Structs"
+msgid "struct:"
+msgstr "Structs"
+
+#: src/glossary.md:96
+msgid "test:"
+msgstr ""
+
+#: src/glossary.md:97
+#, fuzzy
+#| msgid "Threads"
+msgid "thread:"
+msgstr "Hilos"
+
+#: src/glossary.md:98
+msgid "thread safety:"
+msgstr ""
+
+#: src/glossary.md:99
+#, fuzzy
+#| msgid "Traits"
+msgid "trait:"
+msgstr "Traits"
+
+#: src/glossary.md:100
+msgid "type:"
+msgstr ""
+
+#: src/glossary.md:101
+#, fuzzy
+#| msgid "Type Inference"
+msgid "type inference:"
+msgstr "Inferencia de tipos"
+
+#: src/glossary.md:102
+#, fuzzy
+#| msgid "No undefined behavior at runtime:"
+msgid "undefined behavior:"
+msgstr "No hay comportamientos indefinidos en _runtime_:"
+
+#: src/glossary.md:103
+#, fuzzy
+#| msgid "Unions"
+msgid "union:"
+msgstr "Uniones"
+
+#: src/glossary.md:104
+#, fuzzy
+#| msgid "Unit Tests"
+msgid "unit test:"
+msgstr "Pruebas Unitarias"
+
+#: src/glossary.md:105
+#, fuzzy
+#| msgid "Yes (unsafe)"
+msgid "unsafe:"
+msgstr "Sí (inseguro)"
+
+#: src/glossary.md:106
+#, fuzzy
+#| msgid "Variables"
+msgid "variable:\\"
+msgstr "Variables"
+
+#: src/other-resources.md:1
+msgid "Other Rust Resources"
+msgstr "Otros recursos de Rust"
+
+#: src/other-resources.md:3
+msgid ""
+"The Rust community has created a wealth of high-quality and free resources "
+"online."
+msgstr ""
+"La comunidad de Rust ha creado una gran cantidad de recursos online sin "
+"coste y de gran calidad."
+
+#: src/other-resources.md:6
+msgid "Official Documentation"
+msgstr "Documentación oficial"
+
+#: src/other-resources.md:8
+msgid "The Rust project hosts many resources. These cover Rust in general:"
+msgstr ""
+"El proyecto Rust cuenta con muchos recursos. Estos tratan sobre Rust en "
+"general:"
+
+#: src/other-resources.md:10
+msgid ""
+"[The Rust Programming Language](https://doc.rust-lang.org/book/): the "
+"canonical free book about Rust. Covers the language in detail and includes a "
+"few projects for people to build."
+msgstr ""
+"[The Rust Programming Language](https://doc.rust-lang.org/book/): el libro "
+"canónico sobre Rust sin coste alguno. Trata el lenguaje de forma detallada e "
+"incluye algunos proyectos que los usuarios pueden compilar."
+
+#: src/other-resources.md:13
+msgid ""
+"[Rust By Example](https://doc.rust-lang.org/rust-by-example/): covers the "
+"Rust syntax via a series of examples which showcase different constructs. "
+"Sometimes includes small exercises where you are asked to expand on the code "
+"in the examples."
+msgstr ""
+"[Rust by Example](https://doc.rust-lang.org/rust-by-example/): trata la "
+"sintaxis de Rust a través de una serie de ejemplos que muestran distintas "
+"construcciones. A veces incluye pequeños ejercicios en los que se te pide "
+"que amplíes el código de los ejemplos."
+
+#: src/other-resources.md:17
+msgid ""
+"[Rust Standard Library](https://doc.rust-lang.org/std/): full documentation "
+"of the standard library for Rust."
+msgstr ""
+"[La biblioteca estándar de Rust](https://doc.rust-lang.org/std/): "
+"documentación completa de la biblioteca estándar de Rust."
+
+#: src/other-resources.md:19
+msgid ""
+"[The Rust Reference](https://doc.rust-lang.org/reference/): an incomplete "
+"book which describes the Rust grammar and memory model."
+msgstr ""
+"[The Rust Reference](https://doc.rust-lang.org/reference/): un libro "
+"incompleto que describe la gramática y el modelo de memoria de Rust."
+
+#: src/other-resources.md:22
+msgid "More specialized guides hosted on the official Rust site:"
+msgstr "Consulta guías más especializadas en el sitio oficial de Rust:"
+
+#: src/other-resources.md:24
+msgid ""
+"[The Rustonomicon](https://doc.rust-lang.org/nomicon/): covers unsafe Rust, "
+"including working with raw pointers and interfacing with other languages "
+"(FFI)."
+msgstr ""
+"[The Rustonomicon](https://doc.rust-lang.org/nomicon/): trata de Rust "
+"inseguro, incluido cómo trabajar con punteros sin formato e interactuar con "
+"otros lenguajes (FFI)."
+
+#: src/other-resources.md:27
+msgid ""
+"[Asynchronous Programming in Rust](https://rust-lang.github.io/async-book/): "
+"covers the new asynchronous programming model which was introduced after the "
+"Rust Book was written."
+msgstr ""
+"[Asynchronous Programming in Rust](https://rust-lang.github.io/async-book/): "
+"incluye el nuevo modelo de programación asíncrona que se introdujo después "
+"de que se escribiera el libro de Rust."
+
+#: src/other-resources.md:30
+msgid ""
+"[The Embedded Rust Book](https://doc.rust-lang.org/stable/embedded-book/): "
+"an introduction to using Rust on embedded devices without an operating "
+"system."
+msgstr ""
+"[The Embedded Rust Book](https://doc.rust-lang.org/stable/embedded-book/): "
+"una introducción sobre el uso de Rust en dispositivos integrados sin sistema "
+"operativo."
+
+#: src/other-resources.md:33
+msgid "Unofficial Learning Material"
+msgstr "Material de formación no oficial"
+
+#: src/other-resources.md:35
+msgid "A small selection of other guides and tutorial for Rust:"
+msgstr "Una pequeña selección de otras guías y tutoriales sobre Rust:"
+
+#: src/other-resources.md:37
+msgid ""
+"[Learn Rust the Dangerous Way](http://cliffle.com/p/dangerust/): covers Rust "
+"from the perspective of low-level C programmers."
+msgstr ""
+"[Learn Rust the Dangerous Way](http://cliffle.com/p/dangerust/): trata Rust "
+"desde la perspectiva de los programadores de C de bajo nivel."
+
+#: src/other-resources.md:39
+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."
+msgstr ""
+"[Rust for Embedded C Programmers](https://docs.opentitan.org/doc/ug/"
+"rust_for_c/): explica Rust desde la perspectiva de los desarrolladores que "
+"escriben _firmware_ en C."
+
+#: src/other-resources.md:42
+msgid ""
+"[Rust for professionals](https://overexact.com/rust-for-professionals/): "
+"covers the syntax of Rust using side-by-side comparisons with other "
+"languages such as C, C++, Java, JavaScript, and Python."
+msgstr ""
+"[Rust for professonals](https://overexact.com/rust-for-professionals/): "
+"trata la sintaxis de Rust comparándola con otros lenguajes, como C, C++, "
+"Java, JavaScript y Python."
+
+#: src/other-resources.md:45
+msgid ""
+"[Rust on Exercism](https://exercism.org/tracks/rust): 100+ exercises to help "
+"you learn Rust."
+msgstr ""
+"[Rust on Exercism](https://exercism.org/tracks/rust): más de 100 ejercicios "
+"para aprender Rust."
+
+#: src/other-resources.md:47
+msgid ""
+"[Ferrous Teaching Material](https://ferrous-systems.github.io/teaching-"
+"material/index.html): a series of small presentations covering both basic "
+"and advanced part of the Rust language. Other topics such as WebAssembly, "
+"and async/await are also covered."
+msgstr ""
+"[Ferrous Teaching Material](https://ferrous-systems.github.io/teaching-"
+"material/index.html): una serie de pequeñas presentaciones que cubren tanto "
+"la parte básica como la parte más avanzada del lenguaje Rust. También se "
+"tratan otros temas como WebAssembly y async/await."
+
+#: src/other-resources.md:52
+msgid ""
+"[Beginner's Series to Rust](https://docs.microsoft.com/en-us/shows/beginners-"
+"series-to-rust/) and [Take your first steps with Rust](https://docs."
+"microsoft.com/en-us/learn/paths/rust-first-steps/): two Rust guides aimed at "
"new developers. The first is a set of 35 videos and the second is a set of "
"11 modules which covers Rust syntax and basic constructs."
msgstr ""
@@ -21908,6 +18533,15 @@ msgstr ""
"imagen de [CXX](https://cxx.rs/). Consulta el directorio `third_party/cxx/` "
"para obtener más información, incluidos los términos de la licencia."
+#: src/credits.md:34
+msgid ""
+"The [Why Rust? - An Example in C](why-rust/an-example-in-c.md) section has "
+"been taken from the presentation slides of [Colin Finck's Master Thesis]"
+"(https://colinfinck.de/Master_Thesis_Colin_Finck.pdf). It has been "
+"relicensed under the terms of the Apache 2.0 license for this course by the "
+"author."
+msgstr ""
+
#: src/exercises/solutions.md:3
msgid "You will find solutions to the exercises on the following pages."
msgstr "En las páginas siguientes encontrarás las soluciones a los ejercicios."
@@ -21922,16 +18556,6 @@ msgstr ""
"com/google/comprehensive-rust/discussions). Ponte en contacto con nosotros "
"si tienes una solución distinta o mejor de la que se presenta aquí."
-#: src/exercises/solutions.md:10
-msgid ""
-"**Note:** Please ignore the `// ANCHOR: label` and `// ANCHOR_END: label` "
-"comments you see in the solutions. They are there to make it possible to re-"
-"use parts of the solutions as the exercises."
-msgstr ""
-"**Nota:** Ignora los comentarios `// ANCHOR: label` y `// ANCHOR_END: label` "
-"que aparecen en las soluciones. Están ahí para que sea posible reutilizar "
-"algunas partes de las soluciones de los ejercicios."
-
#: src/exercises/day-1/solutions-morning.md:1
msgid "Day 1 Morning Exercises"
msgstr "Día 1: Ejercicios de la Mañana"
@@ -21940,86 +18564,20 @@ msgstr "Día 1: Ejercicios de la Mañana"
msgid "([back to exercise](for-loops.md))"
msgstr "([Volver al ejercicio](for-loops.md))"
-#: src/exercises/day-1/solutions-morning.md:7
-msgid ""
-"```rust\n"
-"// Copyright 2022 Google LLC\n"
-"//\n"
-"// Licensed under the Apache License, Version 2.0 (the \"License\");\n"
-"// you may not use this file except in compliance with the License.\n"
-"// You may obtain a copy of the License at\n"
-"//\n"
-"// http://www.apache.org/licenses/LICENSE-2.0\n"
-"//\n"
-"// Unless required by applicable law or agreed to in writing, software\n"
-"// distributed under the License is distributed on an \"AS IS\" BASIS,\n"
-"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
-"// See the License for the specific language governing permissions and\n"
-"// limitations under the License.\n"
-"\n"
-"// ANCHOR: transpose\n"
-"fn transpose(matrix: [[i32; 3]; 3]) -> [[i32; 3]; 3] {\n"
-" // ANCHOR_END: transpose\n"
-" let mut result = [[0; 3]; 3];\n"
-" for i in 0..3 {\n"
-" for j in 0..3 {\n"
-" result[j][i] = matrix[i][j];\n"
-" }\n"
-" }\n"
-" return result;\n"
-"}\n"
-"\n"
-"// ANCHOR: pretty_print\n"
-"fn pretty_print(matrix: &[[i32; 3]; 3]) {\n"
-" // ANCHOR_END: pretty_print\n"
-" for row in matrix {\n"
-" println!(\"{row:?}\");\n"
-" }\n"
-"}\n"
-"\n"
-"// ANCHOR: tests\n"
-"#[test]\n"
-"fn test_transpose() {\n"
-" let matrix = [\n"
-" [101, 102, 103], //\n"
-" [201, 202, 203],\n"
-" [301, 302, 303],\n"
-" ];\n"
-" let transposed = transpose(matrix);\n"
-" assert_eq!(\n"
-" transposed,\n"
-" [\n"
-" [101, 201, 301], //\n"
-" [102, 202, 302],\n"
-" [103, 203, 303],\n"
-" ]\n"
-" );\n"
-"}\n"
-"// ANCHOR_END: tests\n"
-"\n"
-"// ANCHOR: main\n"
-"fn main() {\n"
-" let matrix = [\n"
-" [101, 102, 103], // <-- the comment makes rustfmt add a newline\n"
-" [201, 202, 203],\n"
-" [301, 302, 303],\n"
-" ];\n"
-"\n"
-" println!(\"matrix:\");\n"
-" pretty_print(&matrix);\n"
-"\n"
-" let transposed = transpose(matrix);\n"
-" println!(\"transposed:\");\n"
-" pretty_print(&transposed);\n"
-"}\n"
-"```"
+#: src/exercises/day-1/solutions-morning.md:20
+msgid "\"{row:?}\""
msgstr ""
-#: src/exercises/day-1/solutions-morning.md:78
+#: src/exercises/day-1/solutions-morning.md:27
+#: src/exercises/day-1/solutions-morning.md:35
+msgid "//\n"
+msgstr ""
+
+#: src/exercises/day-1/solutions-morning.md:57
msgid "Bonus question"
msgstr "Pregunta extra"
-#: src/exercises/day-1/solutions-morning.md:80
+#: src/exercises/day-1/solutions-morning.md:59
msgid ""
"It requires more advanced concepts. It might seem that we could use a slice-"
"of-slices (`&[&[i32]]`) as the input type to transpose and thus make our "
@@ -22033,7 +18591,7 @@ msgstr ""
"resultado devuelto no puede ser `&[&[i32]]`, ya que necesita ser el "
"propietario de los datos que devuelve."
-#: src/exercises/day-1/solutions-morning.md:82
+#: src/exercises/day-1/solutions-morning.md:61
msgid ""
"You can attempt to use something like `Vec>`, but this doesn't work "
"out-of-the-box either: it's hard to convert from `Vec>` to "
@@ -22043,7 +18601,7 @@ msgstr ""
"funciona desde el principio: es difícil cambiar de `Vec>` a "
"`&[&[i32]]`, por lo que tampoco puedes usar `pretty_print` de forma sencilla."
-#: src/exercises/day-1/solutions-morning.md:84
+#: src/exercises/day-1/solutions-morning.md:63
msgid ""
"Once we get to traits and generics, we'll be able to use the [`std::convert::"
"AsRef`](https://doc.rust-lang.org/std/convert/trait.AsRef.html) trait to "
@@ -22053,37 +18611,27 @@ msgstr ""
"convert::AsRef`](https://doc.rust-lang.org/std/convert/trait.AsRef.html) "
"para abstraer cualquier elemento que se pueda referenciar, como un slice."
-#: src/exercises/day-1/solutions-morning.md:86
-msgid ""
-"```rust\n"
-"use std::convert::AsRef;\n"
-"use std::fmt::Debug;\n"
-"\n"
-"fn pretty_print(matrix: Matrix)\n"
-"where\n"
-" T: Debug,\n"
-" // A line references a slice of items\n"
-" Line: AsRef<[T]>,\n"
-" // A matrix references a slice of lines\n"
-" Matrix: AsRef<[Line]>\n"
-"{\n"
-" for row in matrix.as_ref() {\n"
-" println!(\"{:?}\", row.as_ref());\n"
-" }\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" // &[&[i32]]\n"
-" pretty_print(&[&[1, 2, 3], &[4, 5, 6], &[7, 8, 9]]);\n"
-" // [[&str; 2]; 2]\n"
-" pretty_print([[\"a\", \"b\"], [\"c\", \"d\"]]);\n"
-" // Vec>\n"
-" pretty_print(vec![vec![1, 2], vec![3, 4]]);\n"
-"}\n"
-"```"
+#: src/exercises/day-1/solutions-morning.md:72
+msgid "// A line references a slice of items\n"
+msgstr ""
+
+#: src/exercises/day-1/solutions-morning.md:74
+msgid "// A matrix references a slice of lines\n"
msgstr ""
-#: src/exercises/day-1/solutions-morning.md:113
+#: src/exercises/day-1/solutions-morning.md:83
+msgid "// &[&[i32]]\n"
+msgstr ""
+
+#: src/exercises/day-1/solutions-morning.md:85
+msgid "// [[&str; 2]; 2]\n"
+msgstr ""
+
+#: src/exercises/day-1/solutions-morning.md:87
+msgid "// Vec>\n"
+msgstr ""
+
+#: src/exercises/day-1/solutions-morning.md:92
msgid ""
"In addition, the type itself would not enforce that the child slices are of "
"the same length, so such variable could contain an invalid matrix."
@@ -22100,107 +18648,24 @@ msgstr "Día 1: Ejercicios de la Tarde"
msgid "([back to exercise](luhn.md))"
msgstr "([volver al ejercicio](luhn.md))"
-#: src/exercises/day-1/solutions-afternoon.md:7
-msgid ""
-"```rust\n"
-"// Copyright 2022 Google LLC\n"
-"//\n"
-"// Licensed under the Apache License, Version 2.0 (the \"License\");\n"
-"// you may not use this file except in compliance with the License.\n"
-"// You may obtain a copy of the License at\n"
-"//\n"
-"// http://www.apache.org/licenses/LICENSE-2.0\n"
-"//\n"
-"// Unless required by applicable law or agreed to in writing, software\n"
-"// distributed under the License is distributed on an \"AS IS\" BASIS,\n"
-"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
-"// See the License for the specific language governing permissions and\n"
-"// limitations under the License.\n"
-"\n"
-"// ANCHOR: luhn\n"
-"pub fn luhn(cc_number: &str) -> bool {\n"
-" // ANCHOR_END: luhn\n"
-" let mut digits_seen = 0;\n"
-" let mut sum = 0;\n"
-" for (i, ch) in cc_number.chars().rev().filter(|&ch| ch != ' ')."
-"enumerate() {\n"
-" match ch.to_digit(10) {\n"
-" Some(d) => {\n"
-" sum += if i % 2 == 1 {\n"
-" let dd = d * 2;\n"
-" dd / 10 + dd % 10\n"
-" } else {\n"
-" d\n"
-" };\n"
-" digits_seen += 1;\n"
-" }\n"
-" None => return false,\n"
-" }\n"
-" }\n"
-"\n"
-" if digits_seen < 2 {\n"
-" return false;\n"
-" }\n"
-"\n"
-" sum % 10 == 0\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let cc_number = \"1234 5678 1234 5670\";\n"
-" println!(\n"
-" \"Is {cc_number} a valid credit card number? {}\",\n"
-" if luhn(cc_number) { \"yes\" } else { \"no\" }\n"
-" );\n"
-"}\n"
-"\n"
-"// ANCHOR: unit-tests\n"
-"#[test]\n"
-"fn test_non_digit_cc_number() {\n"
-" assert!(!luhn(\"foo\"));\n"
-" assert!(!luhn(\"foo 0 0\"));\n"
-"}\n"
-"\n"
-"#[test]\n"
-"fn test_empty_cc_number() {\n"
-" assert!(!luhn(\"\"));\n"
-" assert!(!luhn(\" \"));\n"
-" assert!(!luhn(\" \"));\n"
-" assert!(!luhn(\" \"));\n"
-"}\n"
-"\n"
-"#[test]\n"
-"fn test_single_digit_cc_number() {\n"
-" assert!(!luhn(\"0\"));\n"
-"}\n"
-"\n"
-"#[test]\n"
-"fn test_two_digit_cc_number() {\n"
-" assert!(luhn(\" 0 0 \"));\n"
-"}\n"
-"\n"
-"#[test]\n"
-"fn test_valid_cc_number() {\n"
-" assert!(luhn(\"4263 9826 4026 9299\"));\n"
-" assert!(luhn(\"4539 3195 0343 6467\"));\n"
-" assert!(luhn(\"7992 7398 713\"));\n"
-"}\n"
-"\n"
-"#[test]\n"
-"fn test_invalid_cc_number() {\n"
-" assert!(!luhn(\"4223 9826 4026 9299\"));\n"
-" assert!(!luhn(\"4539 3195 0343 6476\"));\n"
-" assert!(!luhn(\"8273 1232 7352 0569\"));\n"
-"}\n"
-"// ANCHOR_END: unit-tests\n"
-"```"
+#: src/exercises/day-1/solutions-afternoon.md:40
+msgid "\"1234 5678 1234 5670\""
+msgstr ""
+
+#: src/exercises/day-1/solutions-afternoon.md:42
+msgid "\"Is {cc_number} a valid credit card number? {}\""
msgstr ""
-#: src/exercises/day-1/solutions-afternoon.md:98
+#: src/exercises/day-1/solutions-afternoon.md:86
msgid "Pattern matching"
msgstr "Correspondencia de Patrones"
-#: src/exercises/day-1/solutions-afternoon.md:100
-msgid "TBD."
+#: src/exercises/day-1/solutions-afternoon.md:211
+msgid "\"expr: {:?}\""
+msgstr ""
+
+#: src/exercises/day-1/solutions-afternoon.md:212
+msgid "\"result: {:?}\""
msgstr ""
#: src/exercises/day-2/solutions-morning.md:1
@@ -22215,203 +18680,32 @@ msgstr "Diseñando una Librería"
msgid "([back to exercise](book-library.md))"
msgstr "([volver al ejercicio](book-library.md))"
-#: src/exercises/day-2/solutions-morning.md:7
+#: src/exercises/day-2/solutions-morning.md:54
+msgid "\"{}, published in {}\""
+msgstr ""
+
+#: src/exercises/day-2/solutions-morning.md:59
msgid ""
-"```rust\n"
-"// Copyright 2022 Google LLC\n"
-"//\n"
-"// Licensed under the Apache License, Version 2.0 (the \"License\");\n"
-"// you may not use this file except in compliance with the License.\n"
-"// You may obtain a copy of the License at\n"
-"//\n"
-"// http://www.apache.org/licenses/LICENSE-2.0\n"
-"//\n"
-"// Unless required by applicable law or agreed to in writing, software\n"
-"// distributed under the License is distributed on an \"AS IS\" BASIS,\n"
-"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
-"// See the License for the specific language governing permissions and\n"
-"// limitations under the License.\n"
-"\n"
-"// ANCHOR: setup\n"
-"struct Library {\n"
-" books: Vec,\n"
-"}\n"
-"\n"
-"struct Book {\n"
-" title: String,\n"
-" year: u16,\n"
-"}\n"
-"\n"
-"impl Book {\n"
-" // This is a constructor, used below.\n"
-" fn new(title: &str, year: u16) -> Book {\n"
-" Book {\n"
-" title: String::from(title),\n"
-" year,\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"// Implement the methods below. Update the `self` parameter to\n"
-"// indicate the method's required level of ownership over the object:\n"
-"//\n"
-"// - `&self` for shared read-only access,\n"
-"// - `&mut self` for unique and mutable access,\n"
-"// - `self` for unique access by value.\n"
-"impl Library {\n"
-" // ANCHOR_END: setup\n"
-"\n"
-" // ANCHOR: Library_new\n"
-" fn new() -> Library {\n"
-" // ANCHOR_END: Library_new\n"
-" Library { books: Vec::new() }\n"
-" }\n"
-"\n"
-" // ANCHOR: Library_len\n"
-" //fn len(self) -> usize {\n"
-" // todo!(\"Return the length of `self.books`\")\n"
-" //}\n"
-" // ANCHOR_END: Library_len\n"
-" fn len(&self) -> usize {\n"
-" self.books.len()\n"
-" }\n"
-"\n"
-" // ANCHOR: Library_is_empty\n"
-" //fn is_empty(self) -> bool {\n"
-" // todo!(\"Return `true` if `self.books` is empty\")\n"
-" //}\n"
-" // ANCHOR_END: Library_is_empty\n"
-" fn is_empty(&self) -> bool {\n"
-" self.books.is_empty()\n"
-" }\n"
-"\n"
-" // ANCHOR: Library_add_book\n"
-" //fn add_book(self, book: Book) {\n"
-" // todo!(\"Add a new book to `self.books`\")\n"
-" //}\n"
-" // ANCHOR_END: Library_add_book\n"
-" fn add_book(&mut self, book: Book) {\n"
-" self.books.push(book)\n"
-" }\n"
-"\n"
-" // ANCHOR: Library_print_books\n"
-" //fn print_books(self) {\n"
-" // todo!(\"Iterate over `self.books` and each book's title and "
-"year\")\n"
-" //}\n"
-" // ANCHOR_END: Library_print_books\n"
-" fn print_books(&self) {\n"
-" for book in &self.books {\n"
-" println!(\"{}, published in {}\", book.title, book.year);\n"
-" }\n"
-" }\n"
-"\n"
-" // ANCHOR: Library_oldest_book\n"
-" //fn oldest_book(self) -> Option<&Book> {\n"
-" // todo!(\"Return a reference to the oldest book (if any)\")\n"
-" //}\n"
-" // ANCHOR_END: Library_oldest_book\n"
-" fn oldest_book(&self) -> Option<&Book> {\n"
-" // Using a closure and a built-in method:\n"
+"// Using a closure and a built-in method:\n"
" // self.books.iter().min_by_key(|book| book.year)\n"
-"\n"
-" // Longer hand-written solution:\n"
-" let mut oldest: Option<&Book> = None;\n"
-" for book in self.books.iter() {\n"
-" if oldest.is_none() || book.year < oldest.unwrap().year {\n"
-" oldest = Some(book);\n"
-" }\n"
-" }\n"
-"\n"
-" oldest\n"
-" }\n"
-"}\n"
-"\n"
-"// ANCHOR: main\n"
-"// This shows the desired behavior. Uncomment the code below and\n"
-"// implement the missing methods. You will need to update the\n"
-"// method signatures, including the \"self\" parameter! You may\n"
-"// also need to update the variable bindings within main.\n"
-"fn main() {\n"
-" let library = Library::new();\n"
-"\n"
-" //println!(\"The library is empty: library.is_empty() -> {}\", library."
-"is_empty());\n"
-" //\n"
-" //library.add_book(Book::new(\"Lord of the Rings\", 1954));\n"
-" //library.add_book(Book::new(\"Alice's Adventures in Wonderland\", "
-"1865));\n"
-" //\n"
-" //println!(\"The library is no longer empty: library.is_empty() -> {}\", "
-"library.is_empty());\n"
-" //\n"
-" //\n"
-" //library.print_books();\n"
-" //\n"
-" //match library.oldest_book() {\n"
-" // Some(book) => println!(\"The oldest book is {}\", book.title),\n"
-" // None => println!(\"The library is empty!\"),\n"
-" //}\n"
-" //\n"
-" //println!(\"The library has {} books\", library.len());\n"
-" //library.print_books();\n"
-"}\n"
-"// ANCHOR_END: main\n"
-"\n"
-"#[test]\n"
-"fn test_library_len() {\n"
-" let mut library = Library::new();\n"
-" assert_eq!(library.len(), 0);\n"
-" assert!(library.is_empty());\n"
-"\n"
-" library.add_book(Book::new(\"Lord of the Rings\", 1954));\n"
-" library.add_book(Book::new(\"Alice's Adventures in Wonderland\", "
-"1865));\n"
-" assert_eq!(library.len(), 2);\n"
-" assert!(!library.is_empty());\n"
-"}\n"
-"\n"
-"#[test]\n"
-"fn test_library_is_empty() {\n"
-" let mut library = Library::new();\n"
-" assert!(library.is_empty());\n"
-"\n"
-" library.add_book(Book::new(\"Lord of the Rings\", 1954));\n"
-" assert!(!library.is_empty());\n"
-"}\n"
-"\n"
-"#[test]\n"
-"fn test_library_print_books() {\n"
-" let mut library = Library::new();\n"
-" library.add_book(Book::new(\"Lord of the Rings\", 1954));\n"
-" library.add_book(Book::new(\"Alice's Adventures in Wonderland\", "
-"1865));\n"
-" // We could try and capture stdout, but let us just call the\n"
+msgstr ""
+
+#: src/exercises/day-2/solutions-morning.md:62
+msgid "// Longer hand-written solution:\n"
+msgstr ""
+
+#: src/exercises/day-2/solutions-morning.md:127
+msgid ""
+"// We could try and capture stdout, but let us just call the\n"
" // method to start with.\n"
-" library.print_books();\n"
-"}\n"
-"\n"
-"#[test]\n"
-"fn test_library_oldest_book() {\n"
-" let mut library = Library::new();\n"
-" assert!(library.oldest_book().is_none());\n"
-"\n"
-" library.add_book(Book::new(\"Lord of the Rings\", 1954));\n"
-" assert_eq!(\n"
-" library.oldest_book().map(|b| b.title.as_str()),\n"
-" Some(\"Lord of the Rings\")\n"
-" );\n"
-"\n"
-" library.add_book(Book::new(\"Alice's Adventures in Wonderland\", "
-"1865));\n"
-" assert_eq!(\n"
-" library.oldest_book().map(|b| b.title.as_str()),\n"
-" Some(\"Alice's Adventures in Wonderland\")\n"
-" );\n"
-"}\n"
-"```"
msgstr ""
+#: src/exercises/day-2/solutions-morning.md:153
+#, fuzzy
+#| msgid "([back to exercise](chat-app.md))"
+msgid "([back to exercise](health-statistics.md))"
+msgstr "([volver al ejercicio](chat-app.md))"
+
#: src/exercises/day-2/solutions-afternoon.md:1
msgid "Day 2 Afternoon Exercises"
msgstr "Día 2: Ejercicios de la tarde"
@@ -22420,40 +18714,18 @@ msgstr "Día 2: Ejercicios de la tarde"
msgid "([back to exercise](strings-iterators.md))"
msgstr "([volver al ejercicio](strings-iterators.md))"
-#: src/exercises/day-2/solutions-afternoon.md:7
+#: src/exercises/day-2/solutions-afternoon.md:10
+#: src/exercises/day-2/solutions-afternoon.md:12
+msgid "'/'"
+msgstr ""
+
+#: src/exercises/day-2/solutions-afternoon.md:16
+msgid "\"*\""
+msgstr ""
+
+#: src/exercises/day-2/solutions-afternoon.md:22
msgid ""
-"```rust\n"
-"// Copyright 2022 Google LLC\n"
-"//\n"
-"// Licensed under the Apache License, Version 2.0 (the \"License\");\n"
-"// you may not use this file except in compliance with the License.\n"
-"// You may obtain a copy of the License at\n"
-"//\n"
-"// http://www.apache.org/licenses/LICENSE-2.0\n"
-"//\n"
-"// Unless required by applicable law or agreed to in writing, software\n"
-"// distributed under the License is distributed on an \"AS IS\" BASIS,\n"
-"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
-"// See the License for the specific language governing permissions and\n"
-"// limitations under the License.\n"
-"\n"
-"// ANCHOR: prefix_matches\n"
-"pub fn prefix_matches(prefix: &str, request_path: &str) -> bool {\n"
-" // ANCHOR_END: prefix_matches\n"
-"\n"
-" let mut request_segments = request_path.split('/');\n"
-"\n"
-" for prefix_segment in prefix.split('/') {\n"
-" let Some(request_segment) = request_segments.next() else {\n"
-" return false;\n"
-" };\n"
-" if request_segment != prefix_segment && prefix_segment != \"*\" {\n"
-" return false;\n"
-" }\n"
-" }\n"
-" true\n"
-"\n"
-" // Alternatively, Iterator::zip() lets us iterate simultaneously over "
+"// Alternatively, Iterator::zip() lets us iterate simultaneously over "
"prefix\n"
" // and request segments. The zip() iterator is finished as soon as one "
"of\n"
@@ -22464,49 +18736,6 @@ msgid ""
" // to produce an iterator that returns Some(str) for each pattern "
"segments,\n"
" // and then returns None indefinitely.\n"
-"}\n"
-"\n"
-"// ANCHOR: unit-tests\n"
-"#[test]\n"
-"fn test_matches_without_wildcard() {\n"
-" assert!(prefix_matches(\"/v1/publishers\", \"/v1/publishers\"));\n"
-" assert!(prefix_matches(\"/v1/publishers\", \"/v1/publishers/"
-"abc-123\"));\n"
-" assert!(prefix_matches(\"/v1/publishers\", \"/v1/publishers/abc/"
-"books\"));\n"
-"\n"
-" assert!(!prefix_matches(\"/v1/publishers\", \"/v1\"));\n"
-" assert!(!prefix_matches(\"/v1/publishers\", \"/v1/publishersBooks\"));\n"
-" assert!(!prefix_matches(\"/v1/publishers\", \"/v1/parent/"
-"publishers\"));\n"
-"}\n"
-"\n"
-"#[test]\n"
-"fn test_matches_with_wildcard() {\n"
-" assert!(prefix_matches(\n"
-" \"/v1/publishers/*/books\",\n"
-" \"/v1/publishers/foo/books\"\n"
-" ));\n"
-" assert!(prefix_matches(\n"
-" \"/v1/publishers/*/books\",\n"
-" \"/v1/publishers/bar/books\"\n"
-" ));\n"
-" assert!(prefix_matches(\n"
-" \"/v1/publishers/*/books\",\n"
-" \"/v1/publishers/foo/books/book1\"\n"
-" ));\n"
-"\n"
-" assert!(!prefix_matches(\"/v1/publishers/*/books\", \"/v1/"
-"publishers\"));\n"
-" assert!(!prefix_matches(\n"
-" \"/v1/publishers/*/books\",\n"
-" \"/v1/publishers/foo/booksByAuthor\"\n"
-" ));\n"
-"}\n"
-"// ANCHOR_END: unit-tests\n"
-"\n"
-"fn main() {}\n"
-"```"
msgstr ""
#: src/exercises/day-3/solutions-morning.md:1
@@ -22517,285 +18746,54 @@ msgstr "Día 3: Ejercicios de la mañana"
msgid "([back to exercise](simple-gui.md))"
msgstr "([volver al ejercicio](simple-gui.md))"
-#: src/exercises/day-3/solutions-morning.md:7
+#: src/exercises/day-3/solutions-morning.md:75
+msgid "// Add 4 paddings for borders\n"
+msgstr ""
+
+#: src/exercises/day-3/solutions-morning.md:87
msgid ""
-"```rust\n"
-"// Copyright 2022 Google LLC\n"
-"//\n"
-"// Licensed under the Apache License, Version 2.0 (the \"License\");\n"
-"// you may not use this file except in compliance with the License.\n"
-"// You may obtain a copy of the License at\n"
-"//\n"
-"// http://www.apache.org/licenses/LICENSE-2.0\n"
-"//\n"
-"// Unless required by applicable law or agreed to in writing, software\n"
-"// distributed under the License is distributed on an \"AS IS\" BASIS,\n"
-"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
-"// See the License for the specific language governing permissions and\n"
-"// limitations under the License.\n"
-"\n"
-"// ANCHOR: setup\n"
-"pub trait Widget {\n"
-" /// Natural width of `self`.\n"
-" fn width(&self) -> usize;\n"
-"\n"
-" /// Draw the widget into a buffer.\n"
-" fn draw_into(&self, buffer: &mut dyn std::fmt::Write);\n"
-"\n"
-" /// Draw the widget on standard output.\n"
-" fn draw(&self) {\n"
-" let mut buffer = String::new();\n"
-" self.draw_into(&mut buffer);\n"
-" println!(\"{buffer}\");\n"
-" }\n"
-"}\n"
-"\n"
-"pub struct Label {\n"
-" label: String,\n"
-"}\n"
-"\n"
-"impl Label {\n"
-" fn new(label: &str) -> Label {\n"
-" Label {\n"
-" label: label.to_owned(),\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"pub struct Button {\n"
-" label: Label,\n"
-" callback: Box,\n"
-"}\n"
-"\n"
-"impl Button {\n"
-" fn new(label: &str, callback: Box) -> Button {\n"
-" Button {\n"
-" label: Label::new(label),\n"
-" callback,\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"pub struct Window {\n"
-" title: String,\n"
-" widgets: Vec>,\n"
-"}\n"
-"\n"
-"impl Window {\n"
-" fn new(title: &str) -> Window {\n"
-" Window {\n"
-" title: title.to_owned(),\n"
-" widgets: Vec::new(),\n"
-" }\n"
-" }\n"
-"\n"
-" fn add_widget(&mut self, widget: Box) {\n"
-" self.widgets.push(widget);\n"
-" }\n"
-"\n"
-" fn inner_width(&self) -> usize {\n"
-" std::cmp::max(\n"
-" self.title.chars().count(),\n"
-" self.widgets.iter().map(|w| w.width()).max().unwrap_or(0),\n"
-" )\n"
-" }\n"
-"}\n"
-"\n"
-"// ANCHOR_END: setup\n"
-"\n"
-"// ANCHOR: Window-width\n"
-"impl Widget for Window {\n"
-" fn width(&self) -> usize {\n"
-" // ANCHOR_END: Window-width\n"
-" // Add 4 paddings for borders\n"
-" self.inner_width() + 4\n"
-" }\n"
-"\n"
-" // ANCHOR: Window-draw_into\n"
-" fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n"
-" // ANCHOR_END: Window-draw_into\n"
-" let mut inner = String::new();\n"
-" for widget in &self.widgets {\n"
-" widget.draw_into(&mut inner);\n"
-" }\n"
-"\n"
-" let inner_width = self.inner_width();\n"
-"\n"
-" // TODO: after learning about error handling, you can change\n"
+"// TODO: after learning about error handling, you can change\n"
" // draw_into to return Result<(), std::fmt::Error>. Then use\n"
" // the ?-operator here instead of .unwrap().\n"
-" writeln!(buffer, \"+-{:- usize {\n"
-" // ANCHOR_END: Button-width\n"
-" self.label.width() + 8 // add a bit of padding\n"
-" }\n"
-"\n"
-" // ANCHOR: Button-draw_into\n"
-" fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n"
-" // ANCHOR_END: Button-draw_into\n"
-" let width = self.width();\n"
-" let mut label = String::new();\n"
-" self.label.draw_into(&mut label);\n"
-"\n"
-" writeln!(buffer, \"+{:- usize {\n"
-" // ANCHOR_END: Label-width\n"
-" self.label\n"
-" .lines()\n"
-" .map(|line| line.chars().count())\n"
-" .max()\n"
-" .unwrap_or(0)\n"
-" }\n"
-"\n"
-" // ANCHOR: Label-draw_into\n"
-" fn draw_into(&self, buffer: &mut dyn std::fmt::Write) {\n"
-" // ANCHOR_END: Label-draw_into\n"
-" writeln!(buffer, \"{}\", &self.label).unwrap();\n"
-" }\n"
-"}\n"
-"\n"
-"// ANCHOR: main\n"
-"fn main() {\n"
-" let mut window = Window::new(\"Rust GUI Demo 1.23\");\n"
-" window.add_widget(Box::new(Label::new(\"This is a small text GUI demo."
-"\")));\n"
-" window.add_widget(Box::new(Button::new(\n"
-" \"Click me!\",\n"
-" Box::new(|| println!(\"You clicked the button!\")),\n"
-" )));\n"
-" window.draw();\n"
-"}\n"
-"// ANCHOR_END: main\n"
-"```"
msgstr ""
-#: src/exercises/day-3/solutions-morning.md:177
+#: src/exercises/day-3/solutions-morning.md:90
+#: src/exercises/day-3/solutions-morning.md:96
+msgid "\"+-{:- Point {\n"
-" Point { x, y }\n"
-" }\n"
-"\n"
-" pub fn magnitude(self) -> f64 {\n"
-" f64::from(self.x.pow(2) + self.y.pow(2)).sqrt()\n"
-" }\n"
-"\n"
-" pub fn dist(self, other: Point) -> f64 {\n"
-" (self - other).magnitude()\n"
-" }\n"
-"}\n"
-"\n"
-"impl std::ops::Add for Point {\n"
-" type Output = Self;\n"
-"\n"
-" fn add(self, other: Self) -> Self::Output {\n"
-" Self {\n"
-" x: self.x + other.x,\n"
-" y: self.y + other.y,\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"impl std::ops::Sub for Point {\n"
-" type Output = Self;\n"
-"\n"
-" fn sub(self, other: Self) -> Self::Output {\n"
-" Self {\n"
-" x: self.x - other.x,\n"
-" y: self.y - other.y,\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"// ANCHOR: Polygon\n"
-"pub struct Polygon {\n"
-" // ANCHOR_END: Polygon\n"
-" points: Vec,\n"
-"}\n"
-"\n"
-"// ANCHOR: Polygon-impl\n"
-"impl Polygon {\n"
-" // ANCHOR_END: Polygon-impl\n"
-" pub fn new() -> Polygon {\n"
-" Polygon { points: Vec::new() }\n"
-" }\n"
-"\n"
-" pub fn add_point(&mut self, point: Point) {\n"
-" self.points.push(point);\n"
-" }\n"
-"\n"
-" pub fn left_most_point(&self) -> Option {\n"
-" self.points.iter().min_by_key(|p| p.x).copied()\n"
-" }\n"
-"\n"
-" pub fn iter(&self) -> impl Iterator- {\n"
-" self.points.iter()\n"
-" }\n"
-"\n"
-" pub fn length(&self) -> f64 {\n"
-" if self.points.is_empty() {\n"
-" return 0.0;\n"
-" }\n"
-"\n"
-" let mut result = 0.0;\n"
-" let mut last_point = self.points[0];\n"
-" for point in &self.points[1..] {\n"
-" result += last_point.dist(*point);\n"
-" last_point = *point;\n"
-" }\n"
-" result += last_point.dist(self.points[0]);\n"
-" result\n"
-" // Alternatively, Iterator::zip() lets us iterate over the points as "
-"pairs\n"
+"// Alternatively, Iterator::zip() lets us iterate over the points as pairs\n"
" // but we need to pair each point with the next one, and the last "
"point\n"
" // with the first point. The zip() iterator is finished as soon as "
@@ -22805,135 +18803,6 @@ msgid ""
" // with Iterator::skip to create the second iterator for the zip and "
"using map \n"
" // and sum to calculate the total length.\n"
-" }\n"
-"}\n"
-"\n"
-"// ANCHOR: Circle\n"
-"pub struct Circle {\n"
-" // ANCHOR_END: Circle\n"
-" center: Point,\n"
-" radius: i32,\n"
-"}\n"
-"\n"
-"// ANCHOR: Circle-impl\n"
-"impl Circle {\n"
-" // ANCHOR_END: Circle-impl\n"
-" pub fn new(center: Point, radius: i32) -> Circle {\n"
-" Circle { center, radius }\n"
-" }\n"
-"\n"
-" pub fn circumference(&self) -> f64 {\n"
-" 2.0 * std::f64::consts::PI * f64::from(self.radius)\n"
-" }\n"
-"\n"
-" pub fn dist(&self, other: &Self) -> f64 {\n"
-" self.center.dist(other.center)\n"
-" }\n"
-"}\n"
-"\n"
-"// ANCHOR: Shape\n"
-"pub enum Shape {\n"
-" Polygon(Polygon),\n"
-" Circle(Circle),\n"
-"}\n"
-"// ANCHOR_END: Shape\n"
-"\n"
-"impl From
for Shape {\n"
-" fn from(poly: Polygon) -> Self {\n"
-" Shape::Polygon(poly)\n"
-" }\n"
-"}\n"
-"\n"
-"impl From for Shape {\n"
-" fn from(circle: Circle) -> Self {\n"
-" Shape::Circle(circle)\n"
-" }\n"
-"}\n"
-"\n"
-"impl Shape {\n"
-" pub fn perimeter(&self) -> f64 {\n"
-" match self {\n"
-" Shape::Polygon(poly) => poly.length(),\n"
-" Shape::Circle(circle) => circle.circumference(),\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"// ANCHOR: unit-tests\n"
-"#[cfg(test)]\n"
-"mod tests {\n"
-" use super::*;\n"
-"\n"
-" fn round_two_digits(x: f64) -> f64 {\n"
-" (x * 100.0).round() / 100.0\n"
-" }\n"
-"\n"
-" #[test]\n"
-" fn test_point_magnitude() {\n"
-" let p1 = Point::new(12, 13);\n"
-" assert_eq!(round_two_digits(p1.magnitude()), 17.69);\n"
-" }\n"
-"\n"
-" #[test]\n"
-" fn test_point_dist() {\n"
-" let p1 = Point::new(10, 10);\n"
-" let p2 = Point::new(14, 13);\n"
-" assert_eq!(round_two_digits(p1.dist(p2)), 5.00);\n"
-" }\n"
-"\n"
-" #[test]\n"
-" fn test_point_add() {\n"
-" let p1 = Point::new(16, 16);\n"
-" let p2 = p1 + Point::new(-4, 3);\n"
-" assert_eq!(p2, Point::new(12, 19));\n"
-" }\n"
-"\n"
-" #[test]\n"
-" fn test_polygon_left_most_point() {\n"
-" let p1 = Point::new(12, 13);\n"
-" let p2 = Point::new(16, 16);\n"
-"\n"
-" let mut poly = Polygon::new();\n"
-" poly.add_point(p1);\n"
-" poly.add_point(p2);\n"
-" assert_eq!(poly.left_most_point(), Some(p1));\n"
-" }\n"
-"\n"
-" #[test]\n"
-" fn test_polygon_iter() {\n"
-" let p1 = Point::new(12, 13);\n"
-" let p2 = Point::new(16, 16);\n"
-"\n"
-" let mut poly = Polygon::new();\n"
-" poly.add_point(p1);\n"
-" poly.add_point(p2);\n"
-"\n"
-" let points = poly.iter().cloned().collect::>();\n"
-" assert_eq!(points, vec![Point::new(12, 13), Point::new(16, 16)]);\n"
-" }\n"
-"\n"
-" #[test]\n"
-" fn test_shape_perimeters() {\n"
-" let mut poly = Polygon::new();\n"
-" poly.add_point(Point::new(12, 13));\n"
-" poly.add_point(Point::new(17, 11));\n"
-" poly.add_point(Point::new(16, 16));\n"
-" let shapes = vec![\n"
-" Shape::from(poly),\n"
-" Shape::from(Circle::new(Point::new(10, 20), 5)),\n"
-" ];\n"
-" let perimeters = shapes\n"
-" .iter()\n"
-" .map(Shape::perimeter)\n"
-" .map(round_two_digits)\n"
-" .collect::>();\n"
-" assert_eq!(perimeters, vec![15.48, 31.42]);\n"
-" }\n"
-"}\n"
-"// ANCHOR_END: unit-tests\n"
-"\n"
-"fn main() {}\n"
-"```"
msgstr ""
#: src/exercises/day-3/solutions-afternoon.md:1
@@ -22944,196 +18813,81 @@ msgstr "Día 3: Ejercicios de la Tarde"
msgid "([back to exercise](safe-ffi-wrapper.md))"
msgstr "([volver al ejercicio](safe-ffi-wrapper.md))"
-#: src/exercises/day-3/solutions-afternoon.md:7
+#: src/exercises/day-3/solutions-afternoon.md:77
+msgid "\"Invalid path: {err}\""
+msgstr ""
+
+#: src/exercises/day-3/solutions-afternoon.md:78
+msgid "// SAFETY: path.as_ptr() cannot be NULL.\n"
+msgstr ""
+
+#: src/exercises/day-3/solutions-afternoon.md:81
+msgid "\"Could not open {:?}\""
+msgstr ""
+
+#: src/exercises/day-3/solutions-afternoon.md:91
msgid ""
-"```rust\n"
-"// Copyright 2022 Google LLC\n"
-"//\n"
-"// Licensed under the Apache License, Version 2.0 (the \"License\");\n"
-"// you may not use this file except in compliance with the License.\n"
-"// You may obtain a copy of the License at\n"
-"//\n"
-"// http://www.apache.org/licenses/LICENSE-2.0\n"
-"//\n"
-"// Unless required by applicable law or agreed to in writing, software\n"
-"// distributed under the License is distributed on an \"AS IS\" BASIS,\n"
-"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
-"// See the License for the specific language governing permissions and\n"
-"// limitations under the License.\n"
-"\n"
-"// ANCHOR: ffi\n"
-"mod ffi {\n"
-" use std::os::raw::{c_char, c_int};\n"
-" #[cfg(not(target_os = \"macos\"))]\n"
-" use std::os::raw::{c_long, c_ulong, c_ushort, c_uchar};\n"
-"\n"
-" // Opaque type. See https://doc.rust-lang.org/nomicon/ffi.html.\n"
-" #[repr(C)]\n"
-" pub struct DIR {\n"
-" _data: [u8; 0],\n"
-" _marker: core::marker::PhantomData<(*mut u8, core::marker::"
-"PhantomPinned)>,\n"
-" }\n"
-"\n"
-" // Layout according to the Linux man page for readdir(3), where ino_t "
-"and\n"
-" // off_t are resolved according to the definitions in\n"
-" // /usr/include/x86_64-linux-gnu/{sys/types.h, bits/typesizes.h}.\n"
-" #[cfg(not(target_os = \"macos\"))]\n"
-" #[repr(C)]\n"
-" pub struct dirent {\n"
-" pub d_ino: c_ulong,\n"
-" pub d_off: c_long,\n"
-" pub d_reclen: c_ushort,\n"
-" pub d_type: c_uchar,\n"
-" pub d_name: [c_char; 256],\n"
-" }\n"
-"\n"
-" // Layout according to the macOS man page for dir(5).\n"
-" #[cfg(all(target_os = \"macos\"))]\n"
-" #[repr(C)]\n"
-" pub struct dirent {\n"
-" pub d_fileno: u64,\n"
-" pub d_seekoff: u64,\n"
-" pub d_reclen: u16,\n"
-" pub d_namlen: u16,\n"
-" pub d_type: u8,\n"
-" pub d_name: [c_char; 1024],\n"
-" }\n"
-"\n"
-" extern \"C\" {\n"
-" pub fn opendir(s: *const c_char) -> *mut DIR;\n"
-"\n"
-" #[cfg(not(all(target_os = \"macos\", target_arch = \"x86_64\")))]\n"
-" pub fn readdir(s: *mut DIR) -> *const dirent;\n"
-"\n"
-" // See https://github.com/rust-lang/libc/issues/414 and the section "
-"on\n"
-" // _DARWIN_FEATURE_64_BIT_INODE in the macOS man page for stat(2).\n"
-" //\n"
-" // \"Platforms that existed before these updates were available\" "
-"refers\n"
-" // to macOS (as opposed to iOS / wearOS / etc.) on Intel and "
-"PowerPC.\n"
-" #[cfg(all(target_os = \"macos\", target_arch = \"x86_64\"))]\n"
-" #[link_name = \"readdir$INODE64\"]\n"
-" pub fn readdir(s: *mut DIR) -> *const dirent;\n"
-"\n"
-" pub fn closedir(s: *mut DIR) -> c_int;\n"
-" }\n"
-"}\n"
-"\n"
-"use std::ffi::{CStr, CString, OsStr, OsString};\n"
-"use std::os::unix::ffi::OsStrExt;\n"
-"\n"
-"#[derive(Debug)]\n"
-"struct DirectoryIterator {\n"
-" path: CString,\n"
-" dir: *mut ffi::DIR,\n"
-"}\n"
-"// ANCHOR_END: ffi\n"
-"\n"
-"// ANCHOR: DirectoryIterator\n"
-"impl DirectoryIterator {\n"
-" fn new(path: &str) -> Result {\n"
-" // Call opendir and return a Ok value if that worked,\n"
-" // otherwise return Err with a message.\n"
-" // ANCHOR_END: DirectoryIterator\n"
-" let path = CString::new(path).map_err(|err| format!(\"Invalid path: "
-"{err}\"))?;\n"
-" // SAFETY: path.as_ptr() cannot be NULL.\n"
-" let dir = unsafe { ffi::opendir(path.as_ptr()) };\n"
-" if dir.is_null() {\n"
-" Err(format!(\"Could not open {:?}\", path))\n"
-" } else {\n"
-" Ok(DirectoryIterator { path, dir })\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"// ANCHOR: Iterator\n"
-"impl Iterator for DirectoryIterator {\n"
-" type Item = OsString;\n"
-" fn next(&mut self) -> Option {\n"
-" // Keep calling readdir until we get a NULL pointer back.\n"
-" // ANCHOR_END: Iterator\n"
+"// Keep calling readdir until we get a NULL pointer back.\n"
" // SAFETY: self.dir is never NULL.\n"
-" let dirent = unsafe { ffi::readdir(self.dir) };\n"
-" if dirent.is_null() {\n"
-" // We have reached the end of the directory.\n"
-" return None;\n"
-" }\n"
-" // SAFETY: dirent is not NULL and dirent.d_name is NUL\n"
+msgstr ""
+
+#: src/exercises/day-3/solutions-afternoon.md:95
+msgid "// We have reached the end of the directory.\n"
+msgstr ""
+
+#: src/exercises/day-3/solutions-afternoon.md:98
+msgid ""
+"// SAFETY: dirent is not NULL and dirent.d_name is NUL\n"
" // terminated.\n"
-" let d_name = unsafe { CStr::from_ptr((*dirent).d_name.as_ptr()) };\n"
-" let os_str = OsStr::from_bytes(d_name.to_bytes());\n"
-" Some(os_str.to_owned())\n"
-" }\n"
-"}\n"
-"\n"
-"// ANCHOR: Drop\n"
-"impl Drop for DirectoryIterator {\n"
-" fn drop(&mut self) {\n"
-" // Call closedir as needed.\n"
-" // ANCHOR_END: Drop\n"
-" if !self.dir.is_null() {\n"
-" // SAFETY: self.dir is not NULL.\n"
-" if unsafe { ffi::closedir(self.dir) } != 0 {\n"
-" panic!(\"Could not close {:?}\", self.path);\n"
-" }\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"// ANCHOR: main\n"
-"fn main() -> Result<(), String> {\n"
-" let iter = DirectoryIterator::new(\".\")?;\n"
-" println!(\"files: {:#?}\", iter.collect::>());\n"
-" Ok(())\n"
-"}\n"
-"// ANCHOR_END: main\n"
-"\n"
-"#[cfg(test)]\n"
-"mod tests {\n"
-" use super::*;\n"
-" use std::error::Error;\n"
-"\n"
-" #[test]\n"
-" fn test_nonexisting_directory() {\n"
-" let iter = DirectoryIterator::new(\"no-such-directory\");\n"
-" assert!(iter.is_err());\n"
-" }\n"
-"\n"
-" #[test]\n"
-" fn test_empty_directory() -> Result<(), Box> {\n"
-" let tmp = tempfile::TempDir::new()?;\n"
-" let iter = DirectoryIterator::new(\n"
-" tmp.path().to_str().ok_or(\"Non UTF-8 character in path\")?,\n"
-" )?;\n"
-" let mut entries = iter.collect::>();\n"
-" entries.sort();\n"
-" assert_eq!(entries, &[\".\", \"..\"]);\n"
-" Ok(())\n"
-" }\n"
-"\n"
-" #[test]\n"
-" fn test_nonempty_directory() -> Result<(), Box> {\n"
-" let tmp = tempfile::TempDir::new()?;\n"
-" std::fs::write(tmp.path().join(\"foo.txt\"), \"The Foo "
-"Diaries\\n\")?;\n"
-" std::fs::write(tmp.path().join(\"bar.png\"), \"\\n\")?;\n"
-" std::fs::write(tmp.path().join(\"crab.rs\"), \"//! Crab\\n\")?;\n"
-" let iter = DirectoryIterator::new(\n"
-" tmp.path().to_str().ok_or(\"Non UTF-8 character in path\")?,\n"
-" )?;\n"
-" let mut entries = iter.collect::>();\n"
-" entries.sort();\n"
-" assert_eq!(entries, &[\".\", \"..\", \"bar.png\", \"crab.rs\", \"foo."
-"txt\"]);\n"
-" Ok(())\n"
-" }\n"
-"}\n"
-"```"
+msgstr ""
+
+#: src/exercises/day-3/solutions-afternoon.md:110
+msgid "// SAFETY: self.dir is not NULL.\n"
+msgstr ""
+
+#: src/exercises/day-3/solutions-afternoon.md:112
+msgid "\"Could not close {:?}\""
+msgstr ""
+
+#: src/exercises/day-3/solutions-afternoon.md:131
+msgid "\"no-such-directory\""
+msgstr ""
+
+#: src/exercises/day-3/solutions-afternoon.md:139
+#: src/exercises/day-3/solutions-afternoon.md:154
+msgid "\"Non UTF-8 character in path\""
+msgstr ""
+
+#: src/exercises/day-3/solutions-afternoon.md:143
+#: src/exercises/day-3/solutions-afternoon.md:158
+msgid "\"..\""
+msgstr ""
+
+#: src/exercises/day-3/solutions-afternoon.md:150
+#: src/exercises/day-3/solutions-afternoon.md:158
+msgid "\"foo.txt\""
+msgstr ""
+
+#: src/exercises/day-3/solutions-afternoon.md:150
+msgid "\"The Foo Diaries\\n\""
+msgstr ""
+
+#: src/exercises/day-3/solutions-afternoon.md:151
+#: src/exercises/day-3/solutions-afternoon.md:158
+msgid "\"bar.png\""
+msgstr ""
+
+#: src/exercises/day-3/solutions-afternoon.md:151
+msgid "\"\\n\""
+msgstr ""
+
+#: src/exercises/day-3/solutions-afternoon.md:152
+#: src/exercises/day-3/solutions-afternoon.md:158
+msgid "\"crab.rs\""
+msgstr ""
+
+#: src/exercises/day-3/solutions-afternoon.md:152
+msgid "\"//! Crab\\n\""
msgstr ""
#: src/exercises/bare-metal/solutions-morning.md:1
@@ -23144,171 +18898,30 @@ msgstr "Rust Bare Metal: Ejercicio de la Mañana"
msgid "([back to exercise](compass.md))"
msgstr "([volver al ejercicio](compass.md))"
-#: src/exercises/bare-metal/solutions-morning.md:7
+#: src/exercises/bare-metal/solutions-morning.md:40
+msgid "// Set up the I2C controller and Inertial Measurement Unit.\n"
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-morning.md:41
+msgid "\"Setting up IMU...\""
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-morning.md:49
+msgid "// Set up display and timer.\n"
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-morning.md:59
+msgid "// Read compass data and log it to the serial port.\n"
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-morning.md:67
+msgid "\"{},{},{}\\t{},{},{}\""
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-morning.md:103
msgid ""
-"```rust,compile_fail\n"
-"// Copyright 2023 Google LLC\n"
-"//\n"
-"// Licensed under the Apache License, Version 2.0 (the \"License\");\n"
-"// you may not use this file except in compliance with the License.\n"
-"// You may obtain a copy of the License at\n"
-"//\n"
-"// http://www.apache.org/licenses/LICENSE-2.0\n"
-"//\n"
-"// Unless required by applicable law or agreed to in writing, software\n"
-"// distributed under the License is distributed on an \"AS IS\" BASIS,\n"
-"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
-"// See the License for the specific language governing permissions and\n"
-"// limitations under the License.\n"
-"\n"
-"// ANCHOR: top\n"
-"#![no_main]\n"
-"#![no_std]\n"
-"\n"
-"extern crate panic_halt as _;\n"
-"\n"
-"use core::fmt::Write;\n"
-"use cortex_m_rt::entry;\n"
-"// ANCHOR_END: top\n"
-"use core::cmp::{max, min};\n"
-"use lsm303agr::{AccelOutputDataRate, Lsm303agr, MagOutputDataRate};\n"
-"use microbit::display::blocking::Display;\n"
-"use microbit::hal::prelude::*;\n"
-"use microbit::hal::twim::Twim;\n"
-"use microbit::hal::uarte::{Baudrate, Parity, Uarte};\n"
-"use microbit::hal::Timer;\n"
-"use microbit::pac::twim0::frequency::FREQUENCY_A;\n"
-"use microbit::Board;\n"
-"\n"
-"const COMPASS_SCALE: i32 = 30000;\n"
-"const ACCELEROMETER_SCALE: i32 = 700;\n"
-"\n"
-"// ANCHOR: main\n"
-"#[entry]\n"
-"fn main() -> ! {\n"
-" let board = Board::take().unwrap();\n"
-"\n"
-" // Configure serial port.\n"
-" let mut serial = Uarte::new(\n"
-" board.UARTE0,\n"
-" board.uart.into(),\n"
-" Parity::EXCLUDED,\n"
-" Baudrate::BAUD115200,\n"
-" );\n"
-"\n"
-" // Set up the I2C controller and Inertial Measurement Unit.\n"
-" // ANCHOR_END: main\n"
-" writeln!(serial, \"Setting up IMU...\").unwrap();\n"
-" let i2c = Twim::new(board.TWIM0, board.i2c_internal.into(), FREQUENCY_A::"
-"K100);\n"
-" let mut imu = Lsm303agr::new_with_i2c(i2c);\n"
-" imu.init().unwrap();\n"
-" imu.set_mag_odr(MagOutputDataRate::Hz50).unwrap();\n"
-" imu.set_accel_odr(AccelOutputDataRate::Hz50).unwrap();\n"
-" let mut imu = imu.into_mag_continuous().ok().unwrap();\n"
-"\n"
-" // Set up display and timer.\n"
-" let mut timer = Timer::new(board.TIMER0);\n"
-" let mut display = Display::new(board.display_pins);\n"
-"\n"
-" let mut mode = Mode::Compass;\n"
-" let mut button_pressed = false;\n"
-"\n"
-" // ANCHOR: loop\n"
-" writeln!(serial, \"Ready.\").unwrap();\n"
-"\n"
-" loop {\n"
-" // Read compass data and log it to the serial port.\n"
-" // ANCHOR_END: loop\n"
-" while !(imu.mag_status().unwrap().xyz_new_data\n"
-" && imu.accel_status().unwrap().xyz_new_data)\n"
-" {}\n"
-" let compass_reading = imu.mag_data().unwrap();\n"
-" let accelerometer_reading = imu.accel_data().unwrap();\n"
-" writeln!(\n"
-" serial,\n"
-" \"{},{},{}\\t{},{},{}\",\n"
-" compass_reading.x,\n"
-" compass_reading.y,\n"
-" compass_reading.z,\n"
-" accelerometer_reading.x,\n"
-" accelerometer_reading.y,\n"
-" accelerometer_reading.z,\n"
-" )\n"
-" .unwrap();\n"
-"\n"
-" let mut image = [[0; 5]; 5];\n"
-" let (x, y) = match mode {\n"
-" Mode::Compass => (\n"
-" scale(-compass_reading.x, -COMPASS_SCALE, COMPASS_SCALE, 0, "
-"4) as usize,\n"
-" scale(compass_reading.y, -COMPASS_SCALE, COMPASS_SCALE, 0, "
-"4) as usize,\n"
-" ),\n"
-" Mode::Accelerometer => (\n"
-" scale(\n"
-" accelerometer_reading.x,\n"
-" -ACCELEROMETER_SCALE,\n"
-" ACCELEROMETER_SCALE,\n"
-" 0,\n"
-" 4,\n"
-" ) as usize,\n"
-" scale(\n"
-" -accelerometer_reading.y,\n"
-" -ACCELEROMETER_SCALE,\n"
-" ACCELEROMETER_SCALE,\n"
-" 0,\n"
-" 4,\n"
-" ) as usize,\n"
-" ),\n"
-" };\n"
-" image[y][x] = 255;\n"
-" display.show(&mut timer, image, 100);\n"
-"\n"
-" // If button A is pressed, switch to the next mode and briefly blink "
-"all LEDs on.\n"
-" if board.buttons.button_a.is_low().unwrap() {\n"
-" if !button_pressed {\n"
-" mode = mode.next();\n"
-" display.show(&mut timer, [[255; 5]; 5], 200);\n"
-" }\n"
-" button_pressed = true;\n"
-" } else {\n"
-" button_pressed = false;\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"#[derive(Copy, Clone, Debug, Eq, PartialEq)]\n"
-"enum Mode {\n"
-" Compass,\n"
-" Accelerometer,\n"
-"}\n"
-"\n"
-"impl Mode {\n"
-" fn next(self) -> Self {\n"
-" match self {\n"
-" Self::Compass => Self::Accelerometer,\n"
-" Self::Accelerometer => Self::Compass,\n"
-" }\n"
-" }\n"
-"}\n"
-"\n"
-"fn scale(value: i32, min_in: i32, max_in: i32, min_out: i32, max_out: i32) -"
-"> i32 {\n"
-" let range_in = max_in - min_in;\n"
-" let range_out = max_out - min_out;\n"
-" cap(\n"
-" min_out + range_out * (value - min_in) / range_in,\n"
-" min_out,\n"
-" max_out,\n"
-" )\n"
-"}\n"
-"\n"
-"fn cap(value: i32, min_value: i32, max_value: i32) -> i32 {\n"
-" max(min_value, min(value, max_value))\n"
-"}\n"
-"```"
+"// If button A is pressed, switch to the next mode and briefly blink all "
+"LEDs on.\n"
msgstr ""
#: src/exercises/bare-metal/solutions-afternoon.md:5
@@ -23316,213 +18929,103 @@ msgid "([back to exercise](rtc.md))"
msgstr "([volver al ejercicio](rtc.md))"
#: src/exercises/bare-metal/solutions-afternoon.md:7
-msgid "`main.rs`:"
+#, fuzzy
+#| msgid "`main.rs`:"
+msgid "_main.rs_:"
msgstr "`main.rs`:"
-#: src/exercises/bare-metal/solutions-afternoon.md:9
+#: src/exercises/bare-metal/solutions-afternoon.md:36
+msgid "/// Base address of the PL031 RTC.\n"
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-afternoon.md:38
+msgid "/// The IRQ used by the PL031 RTC.\n"
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-afternoon.md:57
msgid ""
-"```rust,compile_fail\n"
-"// Copyright 2023 Google LLC\n"
-"//\n"
-"// Licensed under the Apache License, Version 2.0 (the \"License\");\n"
-"// you may not use this file except in compliance with the License.\n"
-"// You may obtain a copy of the License at\n"
-"//\n"
-"// http://www.apache.org/licenses/LICENSE-2.0\n"
-"//\n"
-"// Unless required by applicable law or agreed to in writing, software\n"
-"// distributed under the License is distributed on an \"AS IS\" BASIS,\n"
-"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
-"// See the License for the specific language governing permissions and\n"
-"// limitations under the License.\n"
-"\n"
-"// ANCHOR: top\n"
-"#![no_main]\n"
-"#![no_std]\n"
-"\n"
-"mod exceptions;\n"
-"mod logger;\n"
-"mod pl011;\n"
-"// ANCHOR_END: top\n"
-"mod pl031;\n"
-"\n"
-"use crate::pl031::Rtc;\n"
-"use arm_gic::gicv3::{IntId, Trigger};\n"
-"use arm_gic::{irq_enable, wfi};\n"
-"use chrono::{TimeZone, Utc};\n"
-"use core::hint::spin_loop;\n"
-"// ANCHOR: imports\n"
-"use crate::pl011::Uart;\n"
-"use arm_gic::gicv3::GicV3;\n"
-"use core::panic::PanicInfo;\n"
-"use log::{error, info, trace, LevelFilter};\n"
-"use smccc::psci::system_off;\n"
-"use smccc::Hvc;\n"
-"\n"
-"/// Base addresses of the GICv3.\n"
-"const GICD_BASE_ADDRESS: *mut u64 = 0x800_0000 as _;\n"
-"const GICR_BASE_ADDRESS: *mut u64 = 0x80A_0000 as _;\n"
-"\n"
-"/// Base address of the primary PL011 UART.\n"
-"const PL011_BASE_ADDRESS: *mut u32 = 0x900_0000 as _;\n"
-"// ANCHOR_END: imports\n"
-"\n"
-"/// Base address of the PL031 RTC.\n"
-"const PL031_BASE_ADDRESS: *mut u32 = 0x901_0000 as _;\n"
-"/// The IRQ used by the PL031 RTC.\n"
-"const PL031_IRQ: IntId = IntId::spi(2);\n"
-"\n"
-"// ANCHOR: main\n"
-"#[no_mangle]\n"
-"extern \"C\" fn main(x0: u64, x1: u64, x2: u64, x3: u64) {\n"
-" // Safe because `PL011_BASE_ADDRESS` is the base address of a PL011 "
-"device,\n"
-" // and nothing else accesses that address range.\n"
-" let uart = unsafe { Uart::new(PL011_BASE_ADDRESS) };\n"
-" logger::init(uart, LevelFilter::Trace).unwrap();\n"
-"\n"
-" info!(\"main({:#x}, {:#x}, {:#x}, {:#x})\", x0, x1, x2, x3);\n"
-"\n"
-" // Safe because `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"
-" let mut gic = unsafe { GicV3::new(GICD_BASE_ADDRESS, "
-"GICR_BASE_ADDRESS) };\n"
-" gic.setup();\n"
-" // ANCHOR_END: main\n"
-"\n"
-" // Safe because `PL031_BASE_ADDRESS` is the base address of a PL031 "
-"device,\n"
+"// Safe because `PL031_BASE_ADDRESS` is the base address of a PL031 device,\n"
" // and nothing else accesses that address range.\n"
-" let mut rtc = unsafe { Rtc::new(PL031_BASE_ADDRESS) };\n"
-" let timestamp = rtc.read();\n"
-" let time = Utc.timestamp_opt(timestamp.into(), 0).unwrap();\n"
-" info!(\"RTC: {time}\");\n"
-"\n"
-" GicV3::set_priority_mask(0xff);\n"
-" gic.set_interrupt_priority(PL031_IRQ, 0x80);\n"
-" gic.set_trigger(PL031_IRQ, Trigger::Level);\n"
-" irq_enable();\n"
-" gic.enable_interrupt(PL031_IRQ, true);\n"
-"\n"
-" // Wait for 3 seconds, without interrupts.\n"
-" let target = timestamp + 3;\n"
-" rtc.set_match(target);\n"
-" info!(\n"
-" \"Waiting for {}\",\n"
-" Utc.timestamp_opt(target.into(), 0).unwrap()\n"
-" );\n"
-" trace!(\n"
-" \"matched={}, interrupt_pending={}\",\n"
-" rtc.matched(),\n"
-" rtc.interrupt_pending()\n"
-" );\n"
-" while !rtc.matched() {\n"
-" spin_loop();\n"
-" }\n"
-" trace!(\n"
-" \"matched={}, interrupt_pending={}\",\n"
-" rtc.matched(),\n"
-" rtc.interrupt_pending()\n"
-" );\n"
-" info!(\"Finished waiting\");\n"
-"\n"
-" // Wait another 3 seconds for an interrupt.\n"
-" let target = timestamp + 6;\n"
-" info!(\n"
-" \"Waiting for {}\",\n"
-" Utc.timestamp_opt(target.into(), 0).unwrap()\n"
-" );\n"
-" rtc.set_match(target);\n"
-" rtc.clear_interrupt();\n"
-" rtc.enable_interrupt(true);\n"
-" trace!(\n"
-" \"matched={}, interrupt_pending={}\",\n"
-" rtc.matched(),\n"
-" rtc.interrupt_pending()\n"
-" );\n"
-" while !rtc.interrupt_pending() {\n"
-" wfi();\n"
-" }\n"
-" trace!(\n"
-" \"matched={}, interrupt_pending={}\",\n"
-" rtc.matched(),\n"
-" rtc.interrupt_pending()\n"
-" );\n"
-" info!(\"Finished waiting\");\n"
-"\n"
-" // ANCHOR: main_end\n"
-" system_off::().unwrap();\n"
-"}\n"
-"\n"
-"#[panic_handler]\n"
-"fn panic(info: &PanicInfo) -> ! {\n"
-" error!(\"{info}\");\n"
-" system_off::().unwrap();\n"
-" loop {}\n"
-"}\n"
-"// ANCHOR_END: main_end\n"
-"```"
msgstr ""
-#: src/exercises/bare-metal/solutions-afternoon.md:149
-msgid "`pl031.rs`:"
+#: src/exercises/bare-metal/solutions-afternoon.md:62
+msgid "\"RTC: {time}\""
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-afternoon.md:70
+msgid "// Wait for 3 seconds, without interrupts.\n"
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-afternoon.md:74
+#: src/exercises/bare-metal/solutions-afternoon.md:95
+msgid "\"Waiting for {}\""
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-afternoon.md:78
+#: src/exercises/bare-metal/solutions-afternoon.md:86
+#: src/exercises/bare-metal/solutions-afternoon.md:102
+#: src/exercises/bare-metal/solutions-afternoon.md:110
+msgid "\"matched={}, interrupt_pending={}\""
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-afternoon.md:90
+#: src/exercises/bare-metal/solutions-afternoon.md:114
+msgid "\"Finished waiting\""
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-afternoon.md:92
+msgid "// Wait another 3 seconds for an interrupt.\n"
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-afternoon.md:127
+#, fuzzy
+#| msgid "`pl031.rs`:"
+msgid "_pl031.rs_:"
msgstr "`pl031.rs`:"
-#: src/exercises/bare-metal/solutions-afternoon.md:151
+#: src/exercises/bare-metal/solutions-afternoon.md:134
+msgid "/// Data register\n"
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-afternoon.md:136
+msgid "/// Match register\n"
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-afternoon.md:138
+msgid "/// Load register\n"
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-afternoon.md:140
+msgid "/// Control register\n"
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-afternoon.md:143
+msgid "/// Interrupt Mask Set or Clear register\n"
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-afternoon.md:146
+msgid "/// Raw Interrupt Status\n"
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-afternoon.md:149
+msgid "/// Masked Interrupt Status\n"
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-afternoon.md:152
+msgid "/// Interrupt Clear Register\n"
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-afternoon.md:156
+#, fuzzy
+#| msgid "We will write a driver for the PL031 real-time clock device."
+msgid "/// Driver for a PL031 real-time clock.\n"
+msgstr ""
+"Escribiremos un controlador para el dispositivo de reloj en tiempo real "
+"PL031."
+
+#: src/exercises/bare-metal/solutions-afternoon.md:164
msgid ""
-"```rust\n"
-"// Copyright 2023 Google LLC\n"
-"//\n"
-"// Licensed under the Apache License, Version 2.0 (the \"License\");\n"
-"// you may not use this file except in compliance with the License.\n"
-"// You may obtain a copy of the License at\n"
-"//\n"
-"// http://www.apache.org/licenses/LICENSE-2.0\n"
-"//\n"
-"// Unless required by applicable law or agreed to in writing, software\n"
-"// distributed under the License is distributed on an \"AS IS\" BASIS,\n"
-"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
-"// See the License for the specific language governing permissions and\n"
-"// limitations under the License.\n"
-"\n"
-"use core::ptr::{addr_of, addr_of_mut};\n"
-"\n"
-"#[repr(C, align(4))]\n"
-"struct Registers {\n"
-" /// Data register\n"
-" dr: u32,\n"
-" /// Match register\n"
-" mr: u32,\n"
-" /// Load register\n"
-" lr: u32,\n"
-" /// Control register\n"
-" cr: u8,\n"
-" _reserved0: [u8; 3],\n"
-" /// Interrupt Mask Set or Clear register\n"
-" imsc: u8,\n"
-" _reserved1: [u8; 3],\n"
-" /// Raw Interrupt Status\n"
-" ris: u8,\n"
-" _reserved2: [u8; 3],\n"
-" /// Masked Interrupt Status\n"
-" mis: u8,\n"
-" _reserved3: [u8; 3],\n"
-" /// Interrupt Clear Register\n"
-" icr: u8,\n"
-" _reserved4: [u8; 3],\n"
-"}\n"
-"\n"
-"/// Driver for a PL031 real-time clock.\n"
-"#[derive(Debug)]\n"
-"pub struct Rtc {\n"
-" registers: *mut Registers,\n"
-"}\n"
-"\n"
-"impl Rtc {\n"
-" /// Constructs a new instance of the RTC driver for a PL031 device at "
-"the\n"
+"/// Constructs a new instance of the RTC driver for a PL031 device at the\n"
" /// given base address.\n"
" ///\n"
" /// # Safety\n"
@@ -23532,672 +19035,1130 @@ msgid ""
" /// PL031 device, which must be mapped into the address space of the "
"process\n"
" /// as device memory and not have any other aliases.\n"
-" pub unsafe fn new(base_address: *mut u32) -> Self {\n"
-" Self {\n"
-" registers: base_address as *mut Registers,\n"
-" }\n"
-" }\n"
-"\n"
-" /// Reads the current RTC value.\n"
-" pub fn read(&self) -> u32 {\n"
-" // Safe because we know that self.registers points to the control\n"
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-afternoon.md:178
+msgid "/// Reads the current RTC value.\n"
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-afternoon.md:180
+#: src/exercises/bare-metal/solutions-afternoon.md:188
+#: src/exercises/bare-metal/solutions-afternoon.md:196
+#: src/exercises/bare-metal/solutions-afternoon.md:207
+#: src/exercises/bare-metal/solutions-afternoon.md:219
+#: src/exercises/bare-metal/solutions-afternoon.md:226
+msgid ""
+"// Safe because we know that self.registers points to the control\n"
" // registers of a PL031 device which is appropriately mapped.\n"
-" unsafe { addr_of!((*self.registers).dr).read_volatile() }\n"
-" }\n"
-"\n"
-" /// Writes a match value. When the RTC value matches this then an "
-"interrupt\n"
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-afternoon.md:185
+msgid ""
+"/// Writes a match value. When the RTC value matches this then an interrupt\n"
" /// will be generated (if it is enabled).\n"
-" pub fn set_match(&mut self, value: u32) {\n"
-" // Safe because we know that self.registers points to the control\n"
-" // registers of a PL031 device which is appropriately mapped.\n"
-" unsafe { addr_of_mut!((*self.registers).mr).write_volatile(value) }\n"
-" }\n"
-"\n"
-" /// Returns whether the match register matches the RTC value, whether or "
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-afternoon.md:193
+msgid ""
+"/// Returns whether the match register matches the RTC value, whether or "
"not\n"
" /// the interrupt is enabled.\n"
-" pub fn matched(&self) -> bool {\n"
-" // Safe because we know that self.registers points to the control\n"
-" // registers of a PL031 device which is appropriately mapped.\n"
-" let ris = unsafe { addr_of!((*self.registers).ris)."
-"read_volatile() };\n"
-" (ris & 0x01) != 0\n"
-" }\n"
-"\n"
-" /// Returns whether there is currently an interrupt pending.\n"
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-afternoon.md:202
+msgid ""
+"/// Returns whether there is currently an interrupt pending.\n"
" ///\n"
" /// This should be true if and only if `matched` returns true and the\n"
" /// interrupt is masked.\n"
-" pub fn interrupt_pending(&self) -> bool {\n"
-" // Safe because we know that self.registers points to the control\n"
-" // registers of a PL031 device which is appropriately mapped.\n"
-" let ris = unsafe { addr_of!((*self.registers).mis)."
-"read_volatile() };\n"
-" (ris & 0x01) != 0\n"
-" }\n"
-"\n"
-" /// Sets or clears the interrupt mask.\n"
+msgstr ""
+
+#: src/exercises/bare-metal/solutions-afternoon.md:213
+msgid ""
+"/// Sets or clears the interrupt mask.\n"
" ///\n"
" /// When the mask is true the interrupt is enabled; when it is false "
"the\n"
" /// interrupt is disabled.\n"
-" pub fn enable_interrupt(&mut self, mask: bool) {\n"
-" let imsc = if mask { 0x01 } else { 0x00 };\n"
-" // Safe because we know that self.registers points to the control\n"
-" // registers of a PL031 device which is appropriately mapped.\n"
-" unsafe { addr_of_mut!((*self.registers).imsc)."
-"write_volatile(imsc) }\n"
-" }\n"
-"\n"
-" /// Clears a pending interrupt, if any.\n"
-" pub fn clear_interrupt(&mut self) {\n"
-" // Safe because we know that self.registers points to the control\n"
-" // registers of a PL031 device which is appropriately mapped.\n"
-" unsafe { addr_of_mut!((*self.registers).icr).write_volatile(0x01) }\n"
-" }\n"
-"}\n"
-"\n"
-"// Safe because it just contains a pointer to device memory, which can be\n"
-"// accessed from any context.\n"
-"unsafe impl Send for Rtc {}\n"
-"```"
msgstr ""
-#: src/exercises/concurrency/solutions-morning.md:1
-msgid "Concurrency Morning Exercise"
-msgstr "Concurrencia: Ejercicios de la Mañana"
+#: src/exercises/bare-metal/solutions-afternoon.md:224
+msgid "/// Clears a pending interrupt, if any.\n"
+msgstr ""
+
+#: src/exercises/concurrency/solutions-morning.md:1
+msgid "Concurrency Morning Exercise"
+msgstr "Concurrencia: Ejercicios de la Mañana"
+
+#: src/exercises/concurrency/solutions-morning.md:5
+msgid "([back to exercise](dining-philosophers.md))"
+msgstr "([volver al ejercicio](dining-philosophers.md))"
+
+#: src/exercises/concurrency/solutions-morning.md:29
+msgid "\"{} is trying to eat\""
+msgstr ""
+
+#: src/exercises/concurrency/solutions-morning.md:53
+msgid ""
+"// To avoid a deadlock, we have to break the symmetry\n"
+" // somewhere. This will swap the forks without deinitializing\n"
+" // either of them.\n"
+msgstr ""
+
+#: src/exercises/concurrency/solutions-morning.md:77
+msgid "\"{thought}\""
+msgstr ""
+
+#: src/exercises/concurrency/solutions-morning.md:82
+msgid "Link Checker"
+msgstr "Comprobador de Enlaces"
+
+#: src/exercises/concurrency/solutions-morning.md:84
+msgid "([back to exercise](link-checker.md))"
+msgstr "([volver al ejercicio](link-checker.md))"
+
+#: src/exercises/concurrency/solutions-morning.md:155
+msgid ""
+"/// Determine whether links within the given page should be extracted.\n"
+msgstr ""
+
+#: src/exercises/concurrency/solutions-morning.md:163
+msgid ""
+"/// Mark the given page as visited, returning false if it had already\n"
+" /// been visited.\n"
+msgstr ""
+
+#: src/exercises/concurrency/solutions-morning.md:189
+msgid "// The sender got dropped. No more commands coming in.\n"
+msgstr ""
+
+#: src/exercises/concurrency/solutions-morning.md:230
+msgid "\"Got crawling error: {:#}\""
+msgstr ""
+
+#: src/exercises/concurrency/solutions-morning.md:248
+msgid "\"Bad URLs: {:#?}\""
+msgstr ""
+
+#: src/exercises/concurrency/solutions-afternoon.md:1
+msgid "Concurrency Afternoon Exercise"
+msgstr "Concurrencia: Ejercicios de la Tarde"
+
+#: src/exercises/concurrency/solutions-afternoon.md:5
+msgid "([back to exercise](dining-philosophers-async.md))"
+msgstr "([volver al ejercicio](dining-philosophers-async.md))"
+
+#: src/exercises/concurrency/solutions-afternoon.md:32
+msgid ""
+"// Add a delay before picking the second fork to allow the execution\n"
+" // to transfer to another task\n"
+msgstr ""
+
+#: src/exercises/concurrency/solutions-afternoon.md:40
+msgid "// The locks are dropped here\n"
+msgstr ""
+
+#: src/exercises/concurrency/solutions-afternoon.md:60
+msgid ""
+"// To avoid a deadlock, we have to break the symmetry\n"
+" // somewhere. This will swap the forks without deinitializing\n"
+" // either of them.\n"
+msgstr ""
+
+#: src/exercises/concurrency/solutions-afternoon.md:74
+msgid "// tx is dropped here, so we don't need to explicitly drop it later\n"
+msgstr ""
+
+#: src/exercises/concurrency/solutions-afternoon.md:90
+msgid "\"Here is a thought: {thought}\""
+msgstr ""
+
+#: src/exercises/concurrency/solutions-afternoon.md:97
+msgid "([back to exercise](chat-app.md))"
+msgstr "([volver al ejercicio](chat-app.md))"
+
+#: src/exercises/concurrency/solutions-afternoon.md:117
+msgid "\"Welcome to chat! Type a message\""
+msgstr ""
+
+#: src/exercises/concurrency/solutions-afternoon.md:121
+#, fuzzy
+#| msgid ""
+#| "Hint: As before, use `tokio::select!` in a continuous loop for "
+#| "concurrently performing two tasks: (1) reading user messages from "
+#| "standard input and sending them to the server, and (2) receiving messages "
+#| "from the server, and displaying them for the user."
+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 ""
+"Sugerencia: al igual que antes, usa `tokio::select!` en un bucle continuo "
+"para realizar dos tareas simultáneamente: (1) leer los mensajes del usuario "
+"desde la entrada estándar y enviarlos al servidor, y (2) recibir mensajes "
+"del servidor y mostrárselos al usuario."
+
+#: src/exercises/concurrency/solutions-afternoon.md:130
+msgid "\"From client {addr:?} {text:?}\""
+msgstr ""
+
+#: src/exercises/concurrency/solutions-afternoon.md:185
+msgid "// Continuous loop for concurrently sending and receiving messages.\n"
+msgstr ""
+
+#: src/exercises/concurrency/solutions-afternoon.md:192
+msgid "\"From server: {}\""
+msgstr ""
+
+#, fuzzy
+#~ msgid "Pattern Matching (TBD)"
+#~ msgstr "Correspondencia de Patrones"
+
+#~ 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 ""
+#~ "Recomendamos usar [VS Code](https://code.visualstudio.com/) para editar "
+#~ "el código (aunque cualquier editor compatible con LSP funciona con [rust-"
+#~ "analyzer](https://rust-analyzer.github.io/))."
+
+#~ 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 ""
+#~ "A algunos compañeros también les gusta usar la familia [JetBrains]"
+#~ "(https://www.jetbrains.com/clion/) de IDEs, que hacen sus propios "
+#~ "análisis, pero también tienen inconvenientes. Si lo prefieres, puedes "
+#~ "instalar el [Rust Plugin](https://www.jetbrains.com/rust/). Ten en cuenta "
+#~ "que, a partir de enero del 2023, la depuración solo funciona en la "
+#~ "versión CLion del paquete de JetBrains IDEA."
+
+#~ msgid ""
+#~ "```rust,editable\n"
+#~ "fn main() {\n"
+#~ " println!(\"Edit me!\");\n"
+#~ "}\n"
+#~ "```"
+#~ msgstr ""
+#~ "```rust,editable\n"
+#~ "fn main() {\n"
+#~ " println!(\"Edit me!\");\n"
+#~ "}\n"
+#~ "```"
+
+#~ 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.69.0 (84c898d65 2023-04-16)\n"
+#~ "% cargo --version\n"
+#~ "cargo 1.69.0 (6e9a83356 2023-04-12)\n"
+#~ "```"
+
+#~ msgid ""
+#~ "```shell\n"
+#~ "$ cargo new exercise\n"
+#~ " Created binary (application) `exercise` package\n"
+#~ "```"
+#~ msgstr ""
+#~ "```shell\n"
+#~ "$ cargo new exercise\n"
+#~ " Created binary (application) `exercise` package\n"
+#~ "```"
+
+#~ msgid ""
+#~ "```shell\n"
+#~ "$ cd exercise\n"
+#~ "$ cargo run\n"
+#~ " Compiling exercise v0.1.0 (/home/mgeisler/tmp/exercise)\n"
+#~ " Finished dev [unoptimized + debuginfo] target(s) in 0.75s\n"
+#~ " Running `target/debug/exercise`\n"
+#~ "Hello, world!\n"
+#~ "```"
+#~ msgstr ""
+#~ "```shell\n"
+#~ "$ cd exercise\n"
+#~ "$ cargo run\n"
+#~ " Compiling exercise v0.1.0 (/home/mgeisler/tmp/exercise)\n"
+#~ " Finished dev [unoptimized + debuginfo] target(s) in 0.75s\n"
+#~ " Running `target/debug/exercise`\n"
+#~ "Hola Mundo!\n"
+#~ "```"
+
+#~ msgid ""
+#~ "```rust\n"
+#~ "fn main() {\n"
+#~ " println!(\"Edit me!\");\n"
+#~ "}\n"
+#~ "```"
+#~ msgstr ""
+#~ "```rust\n"
+#~ "fn main() {\n"
+#~ " println!(\"Edit me!\");\n"
+#~ "}\n"
+#~ "```"
+
+#~ msgid ""
+#~ "```shell\n"
+#~ "$ cargo run\n"
+#~ " Compiling exercise v0.1.0 (/home/mgeisler/tmp/exercise)\n"
+#~ " Finished dev [unoptimized + debuginfo] target(s) in 0.24s\n"
+#~ " Running `target/debug/exercise`\n"
+#~ "Edit me!\n"
+#~ "```"
+#~ msgstr ""
+#~ "```shell\n"
+#~ "$ cargo run\n"
+#~ " Compiling exercise v0.1.0 (/home/mgeisler/tmp/exercise)\n"
+#~ " Finished dev [unoptimized + debuginfo] target(s) in 0.24s\n"
+#~ " Running `target/debug/ejercicio`\n"
+#~ "Modifícame!\n"
+#~ "```"
+
+#~ msgid ""
+#~ "```rust,editable\n"
+#~ "fn main() {\n"
+#~ " println!(\"Hello 🌍!\");\n"
+#~ "}\n"
+#~ "```"
+#~ msgstr ""
+#~ "```rust,editable\n"
+#~ "fn main() {\n"
+#~ " println!(\"Hola 🌍!\");\n"
+#~ "}\n"
+#~ "```"
+
+#~ 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() { // Punto de entrada del programa\n"
+#~ " let mut x: i32 = 6; // Variable mutable vinculante\n"
+#~ " print!(\"{x}\"); // Macro para printing, como printf\n"
+#~ " while x != 1 { // Sin paréntesis alrededor de las expresiones\n"
+#~ " if x % 2 == 0 { // Operaciones matemáticas como en otros "
+#~ "lenguajes\n"
+#~ " x = x / 2;\n"
+#~ " } else {\n"
+#~ " x = 3 * x + 1;\n"
+#~ " }\n"
+#~ " print!(\" -> {x}\");\n"
+#~ " }\n"
+#~ " println!();\n"
+#~ "}\n"
+#~ "```"
+
+#~ msgid ""
+#~ "```rust,editable,compile_fail\n"
+#~ "fn new(width: u32, height: u32) -> Rectangle {\n"
+#~ " Rectangle { width, height }\n"
+#~ "}\n"
+#~ "```"
+#~ msgstr ""
+#~ "```rust,editable,compile_fail\n"
+#~ "fn new(width: u32, height: u32) -> Rectangle {\n"
+#~ " Rectangle { width, height }\n"
+#~ "}\n"
+#~ "```"
+
+#~ msgid ""
+#~ "```rust,editable\n"
+#~ "fn generate_random_number() -> i32 {\n"
+#~ " // Implementation based on https://xkcd.com/221/\n"
+#~ " 4 // Chosen by fair dice roll. Guaranteed to be random.\n"
+#~ "}\n"
+#~ "\n"
+#~ "#[derive(Debug)]\n"
+#~ "enum CoinFlip {\n"
+#~ " Heads,\n"
+#~ " Tails,\n"
+#~ "}\n"
+#~ "\n"
+#~ "fn flip_coin() -> CoinFlip {\n"
+#~ " let random_number = generate_random_number();\n"
+#~ " if random_number % 2 == 0 {\n"
+#~ " return CoinFlip::Heads;\n"
+#~ " } else {\n"
+#~ " return CoinFlip::Tails;\n"
+#~ " }\n"
+#~ "}\n"
+#~ "\n"
+#~ "fn main() {\n"
+#~ " println!(\"You got: {:?}\", flip_coin());\n"
+#~ "}\n"
+#~ "```"
+#~ msgstr ""
+#~ "```rust,editable\n"
+#~ "fn generate_random_number() -> i32 {\n"
+#~ " // Implementation based on https://xkcd.com/221/\n"
+#~ " 4 // Chosen by fair dice roll. Guaranteed to be random.\n"
+#~ "}\n"
+#~ "\n"
+#~ "#[derive(Debug)]\n"
+#~ "enum CoinFlip {\n"
+#~ " Heads,\n"
+#~ " Tails,\n"
+#~ "}\n"
+#~ "\n"
+#~ "fn flip_coin() -> CoinFlip {\n"
+#~ " let random_number = generate_random_number();\n"
+#~ " if random_number % 2 == 0 {\n"
+#~ " return CoinFlip::Heads;\n"
+#~ " } else {\n"
+#~ " return CoinFlip::Tails;\n"
+#~ " }\n"
+#~ "}\n"
+#~ "\n"
+#~ "fn main() {\n"
+#~ " println!(\"You got: {:?}\", flip_coin());\n"
+#~ "}\n"
+#~ "```"
+
+#~ msgid ""
+#~ "```c++\n"
+#~ "void say_hello(std::unique_ptr person) {\n"
+#~ " std::cout << \"Hello \" << person->name << std::endl;\n"
+#~ "}\n"
+#~ "```"
+#~ msgstr ""
+#~ "```c++\n"
+#~ "void say_hello(std::unique_ptr person) {\n"
+#~ " std::cout << \"Hola \" << person->name << std::endl;\n"
+#~ "}\n"
+#~ "```"
+
+#~ msgid ""
+#~ "```java\n"
+#~ "void sayHello(Person person) {\n"
+#~ " System.out.println(\"Hello \" + person.getName());\n"
+#~ "}\n"
+#~ "```"
+#~ msgstr ""
+#~ "```java\n"
+#~ "void sayHello(Person person) {\n"
+#~ " System.out.println(\"Hola \" + person.getName());\n"
+#~ "}\n"
+#~ "```"
+
+#~ msgid ""
+#~ "```rust,editable\n"
+#~ "fn main() {\n"
+#~ " let s1: String = String::from(\"Hello!\");\n"
+#~ " let s2: String = s1;\n"
+#~ " println!(\"s2: {s2}\");\n"
+#~ " // println!(\"s1: {s1}\");\n"
+#~ "}\n"
+#~ "```"
+#~ msgstr ""
+#~ "```rust,editable\n"
+#~ "fn main() {\n"
+#~ " let s1: String = String::from(\"Hola!\");\n"
+#~ " let s2: String = s1;\n"
+#~ " println!(\"s2: {s2}\");\n"
+#~ " // println!(\"s1: {s1}\");\n"
+#~ "}\n"
+#~ "```"
+
+#~ msgid ""
+#~ "```c++\n"
+#~ "std::string s1 = \"Cpp\";\n"
+#~ "std::string s2 = s1; // Duplicate the data in s1.\n"
+#~ "```"
+#~ msgstr ""
+#~ "```c++\n"
+#~ "std::string s1 = \"Cpp\";\n"
+#~ "std::string s2 = s1; // Duplicar datos en s1.\n"
+#~ "```"
+
+#~ msgid ""
+#~ "```bob\n"
+#~ " Stack Heap\n"
+#~ ".- - - - - - - - - - - - - -. .- - - - - - - - - - - -.\n"
+#~ ": : : :\n"
+#~ ": s1 : : :\n"
+#~ ": +-----------+-------+ : : +----+----+----+ :\n"
+#~ ": | ptr | o---+---+--+--+-->| C | p | p | :\n"
+#~ ": | len | 3 | : : +----+----+----+ :\n"
+#~ ": | capacity | 3 | : : :\n"
+#~ ": +-----------+-------+ : : :\n"
+#~ ": : `- - - - - - - - - - - -'\n"
+#~ "`- - - - - - - - - - - - - -'\n"
+#~ "```"
+#~ msgstr ""
+#~ "```bob\n"
+#~ " _Stack_ _Heap_\n"
+#~ ".- - - - - - - - - - - - - -. .- - - - - - - - - - - -.\n"
+#~ ": : : :\n"
+#~ ": s1 : : :\n"
+#~ ": +-----------+-------+ : : +----+----+----+ :\n"
+#~ ": | ptr | o---+---+--+--+-->| C | p | p | :\n"
+#~ ": | len | 3 | : : +----+----+----+ :\n"
+#~ ": | capacity | 3 | : : :\n"
+#~ ": +-----------+-------+ : : :\n"
+#~ ": : `- - - - - - - - - - - -'\n"
+#~ "`- - - - - - - - - - - - - -'\n"
+#~ "```"
+
+#~ msgid ""
+#~ "```bob\n"
+#~ " Stack Heap\n"
+#~ ".- - - - - - - - - - - - - -. .- - - - - - - - - - - -.\n"
+#~ ": : : :\n"
+#~ ": s1 : : :\n"
+#~ ": +-----------+-------+ : : +----+----+----+ :\n"
+#~ ": | ptr | o---+---+--+--+-->| C | p | p | :\n"
+#~ ": | len | 3 | : : +----+----+----+ :\n"
+#~ ": | capacity | 3 | : : :\n"
+#~ ": +-----------+-------+ : : :\n"
+#~ ": : : :\n"
+#~ ": s2 : : :\n"
+#~ ": +-----------+-------+ : : +----+----+----+ :\n"
+#~ ": | ptr | o---+---+-----+-->| C | p | p | :\n"
+#~ ": | len | 3 | : : +----+----+----+ :\n"
+#~ ": | capacity | 3 | : : :\n"
+#~ ": +-----------+-------+ : : :\n"
+#~ ": : `- - - - - - - - - - - -'\n"
+#~ "`- - - - - - - - - - - - - -'\n"
+#~ "```"
+#~ msgstr ""
+#~ "```bob\n"
+#~ " _Stack_ _Heap_\n"
+#~ ".- - - - - - - - - - - - - -. .- - - - - - - - - - - -.\n"
+#~ ": : : :\n"
+#~ ": s1 : : :\n"
+#~ ": +-----------+-------+ : : +----+----+----+ :\n"
+#~ ": | ptr | o---+---+--+--+-->| C | p | p | :\n"
+#~ ": | len | 3 | : : +----+----+----+ :\n"
+#~ ": | capacity | 3 | : : :\n"
+#~ ": +-----------+-------+ : : :\n"
+#~ ": : : :\n"
+#~ ": s2 : : :\n"
+#~ ": +-----------+-------+ : : +----+----+----+ :\n"
+#~ ": | ptr | o---+---+-----+-->| C | p | p | :\n"
+#~ ": | len | 3 | : : +----+----+----+ :\n"
+#~ ": | capacity | 3 | : : :\n"
+#~ ": +-----------+-------+ : : :\n"
+#~ ": : `- - - - - - - - - - - -'\n"
+#~ "`- - - - - - - - - - - - - -'\n"
+#~ "```"
+
+#~ msgid "[Solution](solutions-afternoon.md#designing-a-library)"
+#~ msgstr "[Soluciones](solutions-afternoon.md#designing-a-library)"
+
+#~ msgid "`binary_search` returns `Result`."
+#~ msgstr "`binary_search` devuelve `Result`."
+
+#~ msgid "If found, `Result::Ok` holds the index where the element is found."
+#~ msgstr ""
+#~ "Si se encuentra, `Result::Ok` contiene el índice donde se halla el "
+#~ "elemento."
+
+#~ msgid ""
+#~ "Otherwise, `Result::Err` contains the index where such an element should "
+#~ "be inserted."
+#~ msgstr ""
+#~ "De lo contrario, `Result::Err` contendrá el índice donde se debe insertar "
+#~ "dicho elemento."
+
+#~ msgid ""
+#~ "```bob\n"
+#~ " Stack Heap\n"
+#~ ".- - - - - - -. .- - - - - - -.\n"
+#~ ": : : :\n"
+#~ ": five : : :\n"
+#~ ": +-----+ : : +-----+ :\n"
+#~ ": | o---|---+-----+-->| 5 | :\n"
+#~ ": +-----+ : : +-----+ :\n"
+#~ ": : : :\n"
+#~ ": : : :\n"
+#~ "`- - - - - - -' `- - - - - - -'\n"
+#~ "```"
+#~ msgstr ""
+#~ "```bob\n"
+#~ " _Stack_ _Heap_\n"
+#~ ".- - - - - - -. .- - - - - - -.\n"
+#~ ": : : :\n"
+#~ ": five : : :\n"
+#~ ": +-----+ : : +-----+ :\n"
+#~ ": | o---|---+-----+-->| 5 | :\n"
+#~ ": +-----+ : : +-----+ :\n"
+#~ ": : : :\n"
+#~ ": : : :\n"
+#~ "`- - - - - - -' `- - - - - - -'\n"
+#~ "```"
+
+#~ msgid ""
+#~ "```rust,editable,compile_fail\n"
+#~ "trait NotEquals: Equals {\n"
+#~ " fn not_equals(&self, other: &Self) -> bool {\n"
+#~ " !self.equals(other)\n"
+#~ " }\n"
+#~ "}\n"
+#~ "```"
+#~ msgstr ""
+#~ "```rust,editable,compile_fail\n"
+#~ "trait NotEquals: Equals {\n"
+#~ " fn not_equals(&self, other: &Self) -> bool {\n"
+#~ " !self.equals(other)\n"
+#~ " }\n"
+#~ "}\n"
+#~ "```"
+
+#~ msgid ""
+#~ "`Button`: has a `label` and a callback function which is invoked when the "
+#~ "button is pressed."
+#~ msgstr ""
+#~ "`Button`: tiene una `label` y una función de retrollamada que se invoca "
+#~ "cuando se pulsa el botón."
+
+#~ msgid ""
+#~ "```javascript\n"
+#~ "rust_binary {\n"
+#~ " name: \"hello_rust_with_dep\",\n"
+#~ " crate_name: \"hello_rust_with_dep\",\n"
+#~ " srcs: [\"src/main.rs\"],\n"
+#~ " rustlibs: [\n"
+#~ " \"libgreetings\",\n"
+#~ " \"libtextwrap\",\n"
+#~ " ],\n"
+#~ " prefer_rlib: true,\n"
+#~ "}\n"
+#~ "\n"
+#~ "rust_library {\n"
+#~ " name: \"libgreetings\",\n"
+#~ " crate_name: \"greetings\",\n"
+#~ " srcs: [\"src/lib.rs\"],\n"
+#~ "}\n"
+#~ "```"
+#~ msgstr ""
+#~ "```javascript\n"
+#~ "rust_binary {\n"
+#~ " name: \"hello_rust_with_dep\",\n"
+#~ " crate_name: \"hello_rust_with_dep\",\n"
+#~ " srcs: [\"src/main.rs\"],\n"
+#~ " rustlibs: [\n"
+#~ " \"libgreetings\",\n"
+#~ " \"libtextwrap\",\n"
+#~ " ],\n"
+#~ " prefer_rlib: true,\n"
+#~ "}\n"
+#~ "\n"
+#~ "rust_library {\n"
+#~ " name: \"libgreetings\",\n"
+#~ " crate_name: \"greetings\",\n"
+#~ " srcs: [\"src/lib.rs\"],\n"
+#~ "}\n"
+#~ "```"
+
+#~ msgid ""
+#~ "```rust,ignore\n"
+#~ "//! Rust demo.\n"
+#~ "\n"
+#~ "use greetings::greeting;\n"
+#~ "use textwrap::fill;\n"
+#~ "\n"
+#~ "/// Prints a greeting to standard output.\n"
+#~ "fn main() {\n"
+#~ " println!(\"{}\", fill(&greeting(\"Bob\"), 24));\n"
+#~ "}\n"
+#~ "```"
+#~ msgstr ""
+#~ "```rust,ignore\n"
+#~ "//! Rust demo.\n"
+#~ "\n"
+#~ "use greetings::greeting;\n"
+#~ "use textwrap::fill;\n"
+#~ "\n"
+#~ "/// Imprime un saludo en una salida estándar.\n"
+#~ "fn main() {\n"
+#~ " println!(\"{}\", fill(&greeting(\"Bob\"), 24));\n"
+#~ "}\n"
+#~ "```"
+
+#~ msgid ""
+#~ "```rust,ignore\n"
+#~ "//! Greeting library.\n"
+#~ "\n"
+#~ "/// Greet `name`.\n"
+#~ "pub fn greeting(name: &str) -> String {\n"
+#~ " format!(\"Hello {name}, it is very nice to meet you!\")\n"
+#~ "}\n"
+#~ "```"
+#~ msgstr ""
+#~ "```rust,ignore\n"
+#~ "//! Greeting library.\n"
+#~ "\n"
+#~ "/// Saludar a `name`.\n"
+#~ "pub fn greeting(name: &str) -> String {\n"
+#~ " format!(\"Hello {name}, it is very nice to meet you!\")\n"
+#~ "}\n"
+#~ "```"
+
+#~ msgid ""
+#~ "```java\n"
+#~ "package com.example.birthdayservice;\n"
+#~ "\n"
+#~ "/** Birthday service interface. */\n"
+#~ "interface IBirthdayService {\n"
+#~ " /** Generate a Happy Birthday message. */\n"
+#~ " String wishHappyBirthday(String name, int years);\n"
+#~ "}\n"
+#~ "```"
+#~ msgstr ""
+#~ "```java\n"
+#~ "package com.example.birthdayservice;\n"
+#~ "\n"
+#~ "/** Birthday service interface. */\n"
+#~ "interface IBirthdayService {\n"
+#~ " /** Generate a Happy Birthday message. */\n"
+#~ " String wishHappyBirthday(String name, int years);\n"
+#~ "}\n"
+#~ "```"
+
+#~ msgid ""
+#~ "```javascript\n"
+#~ "aidl_interface {\n"
+#~ " name: \"com.example.birthdayservice\",\n"
+#~ " srcs: [\"com/example/birthdayservice/*.aidl\"],\n"
+#~ " unstable: true,\n"
+#~ " backend: {\n"
+#~ " rust: { // Rust is not enabled by default\n"
+#~ " enabled: true,\n"
+#~ " },\n"
+#~ " },\n"
+#~ "}\n"
+#~ "```"
+#~ msgstr ""
+#~ "```javascript\n"
+#~ "aidl_interface {\n"
+#~ " name: \"com.example.birthdayservice\",\n"
+#~ " srcs: [\"com/example/birthdayservice/*.aidl\"],\n"
+#~ " unstable: true,\n"
+#~ " backend: {\n"
+#~ " rust: { // Rust is not enabled by default\n"
+#~ " enabled: true,\n"
+#~ " },\n"
+#~ " },\n"
+#~ "}\n"
+#~ "```"
+
+#~ msgid ""
+#~ "```bash\n"
+#~ "sudo apt install gcc-aarch64-linux-gnu gdb-multiarch libudev-dev picocom "
+#~ "pkg-config qemu-system-arm\n"
+#~ "rustup update\n"
+#~ "rustup target add aarch64-unknown-none thumbv7em-none-eabihf\n"
+#~ "rustup component add llvm-tools-preview\n"
+#~ "cargo install cargo-binutils cargo-embed\n"
+#~ "```"
+#~ msgstr ""
+#~ "```bash\n"
+#~ "sudo apt install gcc-aarch64-linux-gnu gdb-multiarch libudev-dev picocom "
+#~ "pkg-config qemu-system-arm\n"
+#~ "rustup update\n"
+#~ "rustup target add aarch64-unknown-none thumbv7em-none-eabihf\n"
+#~ "rustup component add llvm-tools-preview\n"
+#~ "cargo install cargo-binutils cargo-embed\n"
+#~ "```"
+
+#~ msgid ""
+#~ "```bash\n"
+#~ "echo 'SUBSYSTEM==\"usb\", ATTR{idVendor}==\"0d28\", MODE=\"0664\", "
+#~ "GROUP=\"plugdev\"' |\\\n"
+#~ " sudo tee /etc/udev/rules.d/50-microbit.rules\n"
+#~ "sudo udevadm control --reload-rules\n"
+#~ "```"
+#~ msgstr ""
+#~ "```bash\n"
+#~ "echo 'SUBSYSTEM==\"usb\", ATTR{idVendor}==\"0d28\", MODE=\"0664\", "
+#~ "GROUP=\"plugdev\"' |\\\n"
+#~ " sudo tee /etc/udev/rules.d/50-microbit.rules\n"
+#~ "sudo udevadm control --reload-rules\n"
+#~ "```"
-#: src/exercises/concurrency/solutions-morning.md:5
-msgid "([back to exercise](dining-philosophers.md))"
-msgstr "([volver al ejercicio](dining-philosophers.md))"
+#~ msgid ""
+#~ "```bash\n"
+#~ "xcode-select --install\n"
+#~ "brew install gdb picocom qemu\n"
+#~ "brew install --cask gcc-aarch64-embedded\n"
+#~ "rustup update\n"
+#~ "rustup target add aarch64-unknown-none thumbv7em-none-eabihf\n"
+#~ "rustup component add llvm-tools-preview\n"
+#~ "cargo install cargo-binutils cargo-embed\n"
+#~ "```"
+#~ msgstr ""
+#~ "```bash\n"
+#~ "xcode-select --install\n"
+#~ "brew install gdb picocom qemu\n"
+#~ "brew install --cask gcc-aarch64-embedded\n"
+#~ "rustup update\n"
+#~ "rustup target add aarch64-unknown-none thumbv7em-none-eabihf\n"
+#~ "rustup component add llvm-tools-preview\n"
+#~ "cargo install cargo-binutils cargo-embed\n"
+#~ "```"
-#: src/exercises/concurrency/solutions-morning.md:7
-msgid ""
-"```rust\n"
-"// Copyright 2022 Google LLC\n"
-"//\n"
-"// Licensed under the Apache License, Version 2.0 (the \"License\");\n"
-"// you may not use this file except in compliance with the License.\n"
-"// You may obtain a copy of the License at\n"
-"//\n"
-"// http://www.apache.org/licenses/LICENSE-2.0\n"
-"//\n"
-"// Unless required by applicable law or agreed to in writing, software\n"
-"// distributed under the License is distributed on an \"AS IS\" BASIS,\n"
-"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
-"// See the License for the specific language governing permissions and\n"
-"// limitations under the License.\n"
-"\n"
-"// ANCHOR: Philosopher\n"
-"use std::sync::{mpsc, Arc, Mutex};\n"
-"use std::thread;\n"
-"use std::time::Duration;\n"
-"\n"
-"struct Fork;\n"
-"\n"
-"struct Philosopher {\n"
-" name: String,\n"
-" // ANCHOR_END: Philosopher\n"
-" left_fork: Arc>,\n"
-" right_fork: Arc>,\n"
-" thoughts: mpsc::SyncSender,\n"
-"}\n"
-"\n"
-"// ANCHOR: Philosopher-think\n"
-"impl Philosopher {\n"
-" fn think(&self) {\n"
-" self.thoughts\n"
-" .send(format!(\"Eureka! {} has a new idea!\", &self.name))\n"
-" .unwrap();\n"
-" }\n"
-" // ANCHOR_END: Philosopher-think\n"
-"\n"
-" // ANCHOR: Philosopher-eat\n"
-" fn eat(&self) {\n"
-" // ANCHOR_END: Philosopher-eat\n"
-" println!(\"{} is trying to eat\", &self.name);\n"
-" let left = self.left_fork.lock().unwrap();\n"
-" let right = self.right_fork.lock().unwrap();\n"
-"\n"
-" // ANCHOR: Philosopher-eat-end\n"
-" println!(\"{} is eating...\", &self.name);\n"
-" thread::sleep(Duration::from_millis(10));\n"
-" }\n"
-"}\n"
-"\n"
-"static PHILOSOPHERS: &[&str] =\n"
-" &[\"Socrates\", \"Plato\", \"Aristotle\", \"Thales\", \"Pythagoras\"];\n"
-"\n"
-"fn main() {\n"
-" // ANCHOR_END: Philosopher-eat-end\n"
-" let (tx, rx) = mpsc::sync_channel(10);\n"
-"\n"
-" let forks = (0..PHILOSOPHERS.len())\n"
-" .map(|_| Arc::new(Mutex::new(Fork)))\n"
-" .collect::>();\n"
-"\n"
-" for i in 0..forks.len() {\n"
-" let tx = tx.clone();\n"
-" let mut left_fork = Arc::clone(&forks[i]);\n"
-" let mut right_fork = Arc::clone(&forks[(i + 1) % forks.len()]);\n"
-"\n"
-" // To avoid a deadlock, we have to break the symmetry\n"
-" // somewhere. This will swap the forks without deinitializing\n"
-" // either of them.\n"
-" if i == forks.len() - 1 {\n"
-" std::mem::swap(&mut left_fork, &mut right_fork);\n"
-" }\n"
-"\n"
-" let philosopher = Philosopher {\n"
-" name: PHILOSOPHERS[i].to_string(),\n"
-" thoughts: tx,\n"
-" left_fork,\n"
-" right_fork,\n"
-" };\n"
-"\n"
-" thread::spawn(move || {\n"
-" for _ in 0..100 {\n"
-" philosopher.eat();\n"
-" philosopher.think();\n"
-" }\n"
-" });\n"
-" }\n"
-"\n"
-" drop(tx);\n"
-" for thought in rx {\n"
-" println!(\"{thought}\");\n"
-" }\n"
-"}\n"
-"```"
-msgstr ""
+#~ msgid ""
+#~ "```rust,editable,compile_fail\n"
+#~ "#![no_main]\n"
+#~ "#![no_std]\n"
+#~ "\n"
+#~ "use core::panic::PanicInfo;\n"
+#~ "\n"
+#~ "#[panic_handler]\n"
+#~ "fn panic(_panic: &PanicInfo) -> ! {\n"
+#~ " loop {}\n"
+#~ "}\n"
+#~ "```"
+#~ msgstr ""
+#~ "```rust,editable,compile_fail\n"
+#~ "#![no_main]\n"
+#~ "#![no_std]\n"
+#~ "\n"
+#~ "use core::panic::PanicInfo;\n"
+#~ "\n"
+#~ "#[panic_handler]\n"
+#~ "fn panic(_panic: &PanicInfo) -> ! {\n"
+#~ " loop {}\n"
+#~ "}\n"
+#~ "```"
-#: src/exercises/concurrency/solutions-morning.md:104
-msgid "Link Checker"
-msgstr "Comprobador de Enlaces"
+#~ msgid ""
+#~ "```rust,editable,compile_fail\n"
+#~ "#![no_main]\n"
+#~ "#![no_std]\n"
+#~ "\n"
+#~ "extern crate alloc;\n"
+#~ "extern crate panic_halt as _;\n"
+#~ "\n"
+#~ "use alloc::string::ToString;\n"
+#~ "use alloc::vec::Vec;\n"
+#~ "use buddy_system_allocator::LockedHeap;\n"
+#~ "\n"
+#~ "#[global_allocator]\n"
+#~ "static HEAP_ALLOCATOR: LockedHeap<32> = LockedHeap::<32>::new();\n"
+#~ "\n"
+#~ "static mut HEAP: [u8; 65536] = [0; 65536];\n"
+#~ "\n"
+#~ "pub fn entry() {\n"
+#~ " // Safe because `HEAP` is only used here and `entry` is only called "
+#~ "once.\n"
+#~ " unsafe {\n"
+#~ " // Give the allocator some memory to allocate.\n"
+#~ " HEAP_ALLOCATOR\n"
+#~ " .lock()\n"
+#~ " .init(HEAP.as_mut_ptr() as usize, HEAP.len());\n"
+#~ " }\n"
+#~ "\n"
+#~ " // Now we can do things that require heap allocation.\n"
+#~ " let mut v = Vec::new();\n"
+#~ " v.push(\"A string\".to_string());\n"
+#~ "}\n"
+#~ "```"
+#~ msgstr ""
+#~ "```rust,editable,compile_fail\n"
+#~ "#![no_main]\n"
+#~ "#![no_std]\n"
+#~ "\n"
+#~ "extern crate alloc;\n"
+#~ "extern crate panic_halt as _;\n"
+#~ "\n"
+#~ "use alloc::string::ToString;\n"
+#~ "use alloc::vec::Vec;\n"
+#~ "use buddy_system_allocator::LockedHeap;\n"
+#~ "\n"
+#~ "#[global_allocator]\n"
+#~ "static HEAP_ALLOCATOR: LockedHeap<32> = LockedHeap::<32>::new();\n"
+#~ "\n"
+#~ "static mut HEAP: [u8; 65536] = [0; 65536];\n"
+#~ "\n"
+#~ "pub fn entry() {\n"
+#~ " // Safe because `HEAP` is only used here and `entry` is only called "
+#~ "once.\n"
+#~ " unsafe {\n"
+#~ " // Give the allocator some memory to allocate.\n"
+#~ " HEAP_ALLOCATOR\n"
+#~ " .lock()\n"
+#~ " .init(HEAP.as_mut_ptr() as usize, HEAP.len());\n"
+#~ " }\n"
+#~ "\n"
+#~ " // Ahora podemos hacer cosas que requieran asignación de _heap_.\n"
+#~ " let mut v = Vec::new();\n"
+#~ " v.push(\"A string\".to_string());\n"
+#~ "}\n"
+#~ "```"
-#: src/exercises/concurrency/solutions-morning.md:106
-msgid "([back to exercise](link-checker.md))"
-msgstr "([volver al ejercicio](link-checker.md))"
+#~ msgid "SWD"
+#~ msgstr "SWD"
-#: src/exercises/concurrency/solutions-morning.md:108
-msgid ""
-"```rust,compile_fail\n"
-"// Copyright 2022 Google LLC\n"
-"//\n"
-"// Licensed under the Apache License, Version 2.0 (the \"License\");\n"
-"// you may not use this file except in compliance with the License.\n"
-"// You may obtain a copy of the License at\n"
-"//\n"
-"// http://www.apache.org/licenses/LICENSE-2.0\n"
-"//\n"
-"// Unless required by applicable law or agreed to in writing, software\n"
-"// distributed under the License is distributed on an \"AS IS\" BASIS,\n"
-"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
-"// See the License for the specific language governing permissions and\n"
-"// limitations under the License.\n"
-"\n"
-"use std::{sync::Arc, sync::Mutex, sync::mpsc, thread};\n"
-"\n"
-"// ANCHOR: setup\n"
-"use reqwest::{blocking::Client, Url};\n"
-"use scraper::{Html, Selector};\n"
-"use thiserror::Error;\n"
-"\n"
-"#[derive(Error, Debug)]\n"
-"enum Error {\n"
-" #[error(\"request error: {0}\")]\n"
-" ReqwestError(#[from] reqwest::Error),\n"
-" #[error(\"bad http response: {0}\")]\n"
-" BadResponse(String),\n"
-"}\n"
-"// ANCHOR_END: setup\n"
-"\n"
-"// ANCHOR: visit_page\n"
-"#[derive(Debug)]\n"
-"struct CrawlCommand {\n"
-" url: Url,\n"
-" extract_links: bool,\n"
-"}\n"
-"\n"
-"fn visit_page(client: &Client, command: &CrawlCommand) -> Result, "
-"Error> {\n"
-" println!(\"Checking {:#}\", command.url);\n"
-" let response = client.get(command.url.clone()).send()?;\n"
-" if !response.status().is_success() {\n"
-" return Err(Error::BadResponse(response.status().to_string()));\n"
-" }\n"
-"\n"
-" let mut link_urls = Vec::new();\n"
-" if !command.extract_links {\n"
-" return Ok(link_urls);\n"
-" }\n"
-"\n"
-" let base_url = response.url().to_owned();\n"
-" let body_text = response.text()?;\n"
-" let document = Html::parse_document(&body_text);\n"
-"\n"
-" let selector = Selector::parse(\"a\").unwrap();\n"
-" let href_values = document\n"
-" .select(&selector)\n"
-" .filter_map(|element| element.value().attr(\"href\"));\n"
-" for href in href_values {\n"
-" match base_url.join(href) {\n"
-" Ok(link_url) => {\n"
-" link_urls.push(link_url);\n"
-" }\n"
-" Err(err) => {\n"
-" println!(\"On {base_url:#}: ignored unparsable {href:?}: "
-"{err}\");\n"
-" }\n"
-" }\n"
-" }\n"
-" Ok(link_urls)\n"
-"}\n"
-"// ANCHOR_END: visit_page\n"
-"\n"
-"struct CrawlState {\n"
-" domain: String,\n"
-" visited_pages: std::collections::HashSet,\n"
-"}\n"
-"\n"
-"impl CrawlState {\n"
-" fn new(start_url: &Url) -> CrawlState {\n"
-" let mut visited_pages = std::collections::HashSet::new();\n"
-" visited_pages.insert(start_url.as_str().to_string());\n"
-" CrawlState {\n"
-" domain: start_url.domain().unwrap().to_string(),\n"
-" visited_pages,\n"
-" }\n"
-" }\n"
-"\n"
-" /// Determine whether links within the given page should be extracted.\n"
-" fn should_extract_links(&self, url: &Url) -> bool {\n"
-" let Some(url_domain) = url.domain() else {\n"
-" return false;\n"
-" };\n"
-" url_domain == self.domain\n"
-" }\n"
-"\n"
-" /// Mark the given page as visited, returning true if it had already\n"
-" /// been visited.\n"
-" fn mark_visited(&mut self, url: &Url) -> bool {\n"
-" self.visited_pages.insert(url.as_str().to_string())\n"
-" }\n"
-"}\n"
-"\n"
-"type CrawlResult = Result, (Url, Error)>;\n"
-"fn spawn_crawler_threads(\n"
-" command_receiver: mpsc::Receiver,\n"
-" result_sender: mpsc::Sender,\n"
-" thread_count: u32,\n"
-") {\n"
-" let command_receiver = Arc::new(Mutex::new(command_receiver));\n"
-"\n"
-" for _ in 0..thread_count {\n"
-" let result_sender = result_sender.clone();\n"
-" let command_receiver = command_receiver.clone();\n"
-" thread::spawn(move || {\n"
-" let client = Client::new();\n"
-" loop {\n"
-" let command_result = {\n"
-" let receiver_guard = command_receiver.lock().unwrap();\n"
-" receiver_guard.recv()\n"
-" };\n"
-" let Ok(crawl_command) = command_result else {\n"
-" // The sender got dropped. No more commands coming in.\n"
-" break;\n"
-" };\n"
-" let crawl_result = match visit_page(&client, &crawl_command) "
-"{\n"
-" Ok(link_urls) => Ok(link_urls),\n"
-" Err(error) => Err((crawl_command.url, error)),\n"
-" };\n"
-" result_sender.send(crawl_result).unwrap();\n"
-" }\n"
-" });\n"
-" }\n"
-"}\n"
-"\n"
-"fn control_crawl(\n"
-" start_url: Url,\n"
-" command_sender: mpsc::Sender,\n"
-" result_receiver: mpsc::Receiver,\n"
-") -> Vec {\n"
-" let mut crawl_state = CrawlState::new(&start_url);\n"
-" let start_command = CrawlCommand { url: start_url, extract_links: "
-"true };\n"
-" command_sender.send(start_command).unwrap();\n"
-" let mut pending_urls = 1;\n"
-"\n"
-" let mut bad_urls = Vec::new();\n"
-" while pending_urls > 0 {\n"
-" let crawl_result = result_receiver.recv().unwrap();\n"
-" pending_urls -= 1;\n"
-"\n"
-" match crawl_result {\n"
-" Ok(link_urls) => {\n"
-" for url in link_urls {\n"
-" if crawl_state.mark_visited(&url) {\n"
-" let extract_links = crawl_state."
-"should_extract_links(&url);\n"
-" let crawl_command = CrawlCommand { url, "
-"extract_links };\n"
-" command_sender.send(crawl_command).unwrap();\n"
-" pending_urls += 1;\n"
-" }\n"
-" }\n"
-" }\n"
-" Err((url, error)) => {\n"
-" bad_urls.push(url);\n"
-" println!(\"Got crawling error: {:#}\", error);\n"
-" continue;\n"
-" }\n"
-" }\n"
-" }\n"
-" bad_urls\n"
-"}\n"
-"\n"
-"fn check_links(start_url: Url) -> Vec {\n"
-" let (result_sender, result_receiver) = mpsc::channel::();\n"
-" let (command_sender, command_receiver) = mpsc::channel::"
-"();\n"
-" spawn_crawler_threads(command_receiver, result_sender, 16);\n"
-" control_crawl(start_url, command_sender, result_receiver)\n"
-"}\n"
-"\n"
-"fn main() {\n"
-" let start_url = reqwest::Url::parse(\"https://www.google.org\")."
-"unwrap();\n"
-" let bad_urls = check_links(start_url);\n"
-" println!(\"Bad URLs: {:#?}\", bad_urls);\n"
-"}\n"
-"```"
-msgstr ""
+#~ msgid "GDB stub and Microsoft "
+#~ msgstr "GDB stub y el servidor "
-#: src/exercises/concurrency/solutions-afternoon.md:1
-msgid "Concurrency Afternoon Exercise"
-msgstr "Concurrencia: Ejercicios de la Tarde"
+#~ msgid "DAP"
+#~ msgstr "DAP"
-#: src/exercises/concurrency/solutions-afternoon.md:5
-msgid "([back to exercise](dining-philosophers-async.md))"
-msgstr "([volver al ejercicio](dining-philosophers-async.md))"
+#~ msgid " server"
+#~ msgstr " de Microsoft"
-#: src/exercises/concurrency/solutions-afternoon.md:7
-msgid ""
-"```rust,compile_fail\n"
-"// Copyright 2023 Google LLC\n"
-"//\n"
-"// Licensed under the Apache License, Version 2.0 (the \"License\");\n"
-"// you may not use this file except in compliance with the License.\n"
-"// You may obtain a copy of the License at\n"
-"//\n"
-"// http://www.apache.org/licenses/LICENSE-2.0\n"
-"//\n"
-"// Unless required by applicable law or agreed to in writing, software\n"
-"// distributed under the License is distributed on an \"AS IS\" BASIS,\n"
-"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
-"// See the License for the specific language governing permissions and\n"
-"// limitations under the License.\n"
-"\n"
-"// ANCHOR: Philosopher\n"
-"use std::sync::Arc;\n"
-"use tokio::time;\n"
-"use tokio::sync::mpsc::{self, Sender};\n"
-"use tokio::sync::Mutex;\n"
-"\n"
-"struct Fork;\n"
-"\n"
-"struct Philosopher {\n"
-" name: String,\n"
-" // ANCHOR_END: Philosopher\n"
-" left_fork: Arc>,\n"
-" right_fork: Arc>,\n"
-" thoughts: Sender,\n"
-"}\n"
-"\n"
-"// ANCHOR: Philosopher-think\n"
-"impl Philosopher {\n"
-" async fn think(&self) {\n"
-" self.thoughts\n"
-" .send(format!(\"Eureka! {} has a new idea!\", &self.name))."
-"await\n"
-" .unwrap();\n"
-" }\n"
-" // ANCHOR_END: Philosopher-think\n"
-"\n"
-" // ANCHOR: Philosopher-eat\n"
-" async fn eat(&self) {\n"
-" // Pick up forks...\n"
-" // ANCHOR_END: Philosopher-eat\n"
-" let _first_lock = self.left_fork.lock().await;\n"
-" // Add a delay before picking the second fork to allow the "
-"execution\n"
-" // to transfer to another task\n"
-" time::sleep(time::Duration::from_millis(1)).await;\n"
-" let _second_lock = self.right_fork.lock().await;\n"
-"\n"
-" // ANCHOR: Philosopher-eat-body\n"
-" println!(\"{} is eating...\", &self.name);\n"
-" time::sleep(time::Duration::from_millis(5)).await;\n"
-" // ANCHOR_END: Philosopher-eat-body\n"
-"\n"
-" // The locks are dropped here\n"
-" // ANCHOR: Philosopher-eat-end\n"
-" }\n"
-"}\n"
-"\n"
-"static PHILOSOPHERS: &[&str] =\n"
-" &[\"Socrates\", \"Plato\", \"Aristotle\", \"Thales\", \"Pythagoras\"];\n"
-"\n"
-"#[tokio::main]\n"
-"async fn main() {\n"
-" // ANCHOR_END: Philosopher-eat-end\n"
-" // Create forks\n"
-" let mut forks = vec![];\n"
-" (0..PHILOSOPHERS.len()).for_each(|_| forks.push(Arc::new(Mutex::"
-"new(Fork))));\n"
-"\n"
-" // Create philosophers\n"
-" let (philosophers, mut rx) = {\n"
-" let mut philosophers = vec![];\n"
-" let (tx, rx) = mpsc::channel(10);\n"
-" for (i, name) in PHILOSOPHERS.iter().enumerate() {\n"
-" let left_fork = Arc::clone(&forks[i]);\n"
-" let right_fork = Arc::clone(&forks[(i + 1) % PHILOSOPHERS."
-"len()]);\n"
-" // To avoid a deadlock, we have to break the symmetry\n"
-" // somewhere. This will swap the forks without deinitializing\n"
-" // either of them.\n"
-" if i == 0 {\n"
-" std::mem::swap(&mut left_fork, &mut right_fork);\n"
-" }\n"
-" philosophers.push(Philosopher {\n"
-" name: name.to_string(),\n"
-" left_fork,\n"
-" right_fork,\n"
-" thoughts: tx.clone(),\n"
-" });\n"
-" }\n"
-" (philosophers, rx)\n"
-" // tx is dropped here, so we don't need to explicitly drop it later\n"
-" };\n"
-"\n"
-" // Make them think and eat\n"
-" for phil in philosophers {\n"
-" tokio::spawn(async move {\n"
-" for _ in 0..100 {\n"
-" phil.think().await;\n"
-" phil.eat().await;\n"
-" }\n"
-" });\n"
-"\n"
-" }\n"
-"\n"
-" // Output their thoughts\n"
-" while let Some(thought) = rx.recv().await {\n"
-" println!(\"Here is a thought: {thought}\");\n"
-" }\n"
-"}\n"
-"```"
-msgstr ""
+#~ msgid ""
+#~ "`cargo-embed` is a cargo subcommand to build and flash binaries, log "
+#~ msgstr ""
+#~ "`cargo-embed` es un subcomando de Cargo para compilar e instalar "
+#~ "binarios, registrar salidas "
-#: src/exercises/concurrency/solutions-afternoon.md:121
-msgid "([back to exercise](chat-app.md))"
-msgstr "([volver al ejercicio](chat-app.md))"
+#~ msgid "RTT"
+#~ msgstr "TTR"
-#: src/exercises/concurrency/solutions-afternoon.md:125
-msgid ""
-"```rust,compile_fail\n"
-"// Copyright 2023 Google LLC\n"
-"//\n"
-"// Licensed under the Apache License, Version 2.0 (the \"License\");\n"
-"// you may not use this file except in compliance with the License.\n"
-"// You may obtain a copy of the License at\n"
-"//\n"
-"// http://www.apache.org/licenses/LICENSE-2.0\n"
-"//\n"
-"// Unless required by applicable law or agreed to in writing, software\n"
-"// distributed under the License is distributed on an \"AS IS\" BASIS,\n"
-"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
-"// See the License for the specific language governing permissions and\n"
-"// limitations under the License.\n"
-"\n"
-"// ANCHOR: setup\n"
-"use futures_util::sink::SinkExt;\n"
-"use futures_util::stream::StreamExt;\n"
-"use std::error::Error;\n"
-"use std::net::SocketAddr;\n"
-"use tokio::net::{TcpListener, TcpStream};\n"
-"use tokio::sync::broadcast::{channel, Sender};\n"
-"use tokio_websockets::{Message, ServerBuilder, WebsocketStream};\n"
-"// ANCHOR_END: setup\n"
-"\n"
-"// ANCHOR: handle_connection\n"
-"async fn handle_connection(\n"
-" addr: SocketAddr,\n"
-" mut ws_stream: WebsocketStream,\n"
-" bcast_tx: Sender,\n"
-") -> Result<(), Box> {\n"
-" // ANCHOR_END: handle_connection\n"
-"\n"
-" ws_stream\n"
-" .send(Message::text(\"Welcome to chat! Type a message\".into()))\n"
-" .await?;\n"
-" let mut bcast_rx = bcast_tx.subscribe();\n"
-"\n"
-" // 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"
-" loop {\n"
-" tokio::select! {\n"
-" incoming = ws_stream.next() => {\n"
-" match incoming {\n"
-" Some(Ok(msg)) => {\n"
-" if let Some(text) = msg.as_text() {\n"
-" println!(\"From client {addr:?} {text:?}\");\n"
-" bcast_tx.send(text.into())?;\n"
-" }\n"
-" }\n"
-" Some(Err(err)) => return Err(err.into()),\n"
-" None => return Ok(()),\n"
-" }\n"
-" }\n"
-" msg = bcast_rx.recv() => {\n"
-" ws_stream.send(Message::text(msg?)).await?;\n"
-" }\n"
-" }\n"
-" }\n"
-" // ANCHOR: main\n"
-"}\n"
-"\n"
-"#[tokio::main]\n"
-"async fn main() -> Result<(), Box> {\n"
-" let (bcast_tx, _) = channel(16);\n"
-"\n"
-" let listener = TcpListener::bind(\"127.0.0.1:2000\").await?;\n"
-" println!(\"listening on port 2000\");\n"
-"\n"
-" loop {\n"
-" let (socket, addr) = listener.accept().await?;\n"
-" println!(\"New connection from {addr:?}\");\n"
-" let bcast_tx = bcast_tx.clone();\n"
-" tokio::spawn(async move {\n"
-" // Wrap the raw TCP stream into a websocket.\n"
-" let ws_stream = ServerBuilder::new().accept(socket).await?;\n"
-"\n"
-" handle_connection(addr, ws_stream, bcast_tx).await\n"
-" });\n"
-" }\n"
-"}\n"
-"// ANCHOR_END: main\n"
-"```"
-msgstr ""
+#~ msgid "HVC"
+#~ msgstr "HVC"
-#: src/exercises/concurrency/solutions-afternoon.md:212
-msgid ""
-"```rust,compile_fail\n"
-"// Copyright 2023 Google LLC\n"
-"//\n"
-"// Licensed under the Apache License, Version 2.0 (the \"License\");\n"
-"// you may not use this file except in compliance with the License.\n"
-"// You may obtain a copy of the License at\n"
-"//\n"
-"// http://www.apache.org/licenses/LICENSE-2.0\n"
-"//\n"
-"// Unless required by applicable law or agreed to in writing, software\n"
-"// distributed under the License is distributed on an \"AS IS\" BASIS,\n"
-"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
-"// See the License for the specific language governing permissions and\n"
-"// limitations under the License.\n"
-"\n"
-"// ANCHOR: setup\n"
-"use futures_util::stream::StreamExt;\n"
-"use futures_util::SinkExt;\n"
-"use http::Uri;\n"
-"use tokio::io::{AsyncBufReadExt, BufReader};\n"
-"use tokio_websockets::{ClientBuilder, Message};\n"
-"\n"
-"#[tokio::main]\n"
-"async fn main() -> Result<(), tokio_websockets::Error> {\n"
-" let (mut ws_stream, _) =\n"
-" ClientBuilder::from_uri(Uri::from_static(\"ws://127.0.0.1:2000\"))\n"
-" .connect()\n"
-" .await?;\n"
-"\n"
-" let stdin = tokio::io::stdin();\n"
-" let mut stdin = BufReader::new(stdin).lines();\n"
-"\n"
-" // ANCHOR_END: setup\n"
-" // Continuous loop for concurrently sending and receiving messages.\n"
-" loop {\n"
-" tokio::select! {\n"
-" incoming = ws_stream.next() => {\n"
-" match incoming {\n"
-" Some(Ok(msg)) => {\n"
-" if let Some(text) = msg.as_text() {\n"
-" println!(\"From server: {}\", text);\n"
-" }\n"
-" },\n"
-" Some(Err(err)) => return Err(err.into()),\n"
-" None => return Ok(()),\n"
-" }\n"
-" }\n"
-" res = stdin.next_line() => {\n"
-" match res {\n"
-" Ok(None) => return Ok(()),\n"
-" Ok(Some(line)) => ws_stream.send(Message::text(line."
-"to_string())).await?,\n"
-" Err(err) => return Err(err.into()),\n"
-" }\n"
-" }\n"
-"\n"
-" }\n"
-" }\n"
-"}\n"
-"```"
-msgstr ""
+#~ msgid " to tell the firmware to power off the system:"
+#~ msgstr " para decirle al firmware que apague el sistema:"
+
+#~ msgid ""
+#~ "```shell\n"
+#~ "cargo add thiserror\n"
+#~ "```"
+#~ msgstr ""
+#~ "```shell\n"
+#~ "cargo add thiserror\n"
+#~ "```"
+
+#~ msgid ""
+#~ "```rust,compile_fail\n"
+#~ "use reqwest::{blocking::Client, Url};\n"
+#~ "use scraper::{Html, Selector};\n"
+#~ "use thiserror::Error;\n"
+#~ "\n"
+#~ "#[derive(Error, Debug)]\n"
+#~ "enum Error {\n"
+#~ " #[error(\"request error: {0}\")]\n"
+#~ " ReqwestError(#[from] reqwest::Error),\n"
+#~ " #[error(\"bad http response: {0}\")]\n"
+#~ " BadResponse(String),\n"
+#~ "}\n"
+#~ "\n"
+#~ "#[derive(Debug)]\n"
+#~ "struct CrawlCommand {\n"
+#~ " url: Url,\n"
+#~ " extract_links: bool,\n"
+#~ "}\n"
+#~ "\n"
+#~ "fn visit_page(client: &Client, command: &CrawlCommand) -> "
+#~ "Result, Error> {\n"
+#~ " println!(\"Checking {:#}\", command.url);\n"
+#~ " let response = client.get(command.url.clone()).send()?;\n"
+#~ " if !response.status().is_success() {\n"
+#~ " return Err(Error::BadResponse(response.status().to_string()));\n"
+#~ " }\n"
+#~ "\n"
+#~ " let mut link_urls = Vec::new();\n"
+#~ " if !command.extract_links {\n"
+#~ " return Ok(link_urls);\n"
+#~ " }\n"
+#~ "\n"
+#~ " let base_url = response.url().to_owned();\n"
+#~ " let body_text = response.text()?;\n"
+#~ " let document = Html::parse_document(&body_text);\n"
+#~ "\n"
+#~ " let selector = Selector::parse(\"a\").unwrap();\n"
+#~ " let href_values = document\n"
+#~ " .select(&selector)\n"
+#~ " .filter_map(|element| element.value().attr(\"href\"));\n"
+#~ " for href in href_values {\n"
+#~ " match base_url.join(href) {\n"
+#~ " Ok(link_url) => {\n"
+#~ " link_urls.push(link_url);\n"
+#~ " }\n"
+#~ " Err(err) => {\n"
+#~ " println!(\"On {base_url:#}: ignored unparsable {href:?}: "
+#~ "{err}\");\n"
+#~ " }\n"
+#~ " }\n"
+#~ " }\n"
+#~ " Ok(link_urls)\n"
+#~ "}\n"
+#~ "\n"
+#~ "fn main() {\n"
+#~ " let client = Client::new();\n"
+#~ " let start_url = Url::parse(\"https://www.google.org\").unwrap();\n"
+#~ " let crawl_command = CrawlCommand{ url: start_url, extract_links: "
+#~ "true };\n"
+#~ " match visit_page(&client, &crawl_command) {\n"
+#~ " Ok(links) => println!(\"Links: {links:#?}\"),\n"
+#~ " Err(err) => println!(\"Could not extract links: {err:#}\"),\n"
+#~ " }\n"
+#~ "}\n"
+#~ "```"
+#~ msgstr ""
+#~ "```rust,compile_fail\n"
+#~ "use reqwest::{blocking::Client, Url};\n"
+#~ "use scraper::{Html, Selector};\n"
+#~ "use thiserror::Error;\n"
+#~ "\n"
+#~ "#[derive(Error, Debug)]\n"
+#~ "enum Error {\n"
+#~ " #[error(\"request error: {0}\")]\n"
+#~ " ReqwestError(#[from] reqwest::Error),\n"
+#~ " #[error(\"bad http response: {0}\")]\n"
+#~ " BadResponse(String),\n"
+#~ "}\n"
+#~ "\n"
+#~ "#[derive(Debug)]\n"
+#~ "struct CrawlCommand {\n"
+#~ " url: Url,\n"
+#~ " extract_links: bool,\n"
+#~ "}\n"
+#~ "\n"
+#~ "fn visit_page(client: &Client, command: &CrawlCommand) -> "
+#~ "Result, Error> {\n"
+#~ " println!(\"Checking {:#}\", command.url);\n"
+#~ " let response = client.get(command.url.clone()).send()?;\n"
+#~ " if !response.status().is_success() {\n"
+#~ " return Err(Error::BadResponse(response.status().to_string()));\n"
+#~ " }\n"
+#~ "\n"
+#~ " let mut link_urls = Vec::new();\n"
+#~ " if !command.extract_links {\n"
+#~ " return Ok(link_urls);\n"
+#~ " }\n"
+#~ "\n"
+#~ " let base_url = response.url().to_owned();\n"
+#~ " let body_text = response.text()?;\n"
+#~ " let document = Html::parse_document(&body_text);\n"
+#~ "\n"
+#~ " let selector = Selector::parse(\"a\").unwrap();\n"
+#~ " let href_values = document\n"
+#~ " .select(&selector)\n"
+#~ " .filter_map(|element| element.value().attr(\"href\"));\n"
+#~ " for href in href_values {\n"
+#~ " match base_url.join(href) {\n"
+#~ " Ok(link_url) => {\n"
+#~ " link_urls.push(link_url);\n"
+#~ " }\n"
+#~ " Err(err) => {\n"
+#~ " println!(\"On {base_url:#}: ignored unparsable {href:?}: "
+#~ "{err}\");\n"
+#~ " }\n"
+#~ " }\n"
+#~ " }\n"
+#~ " Ok(link_urls)\n"
+#~ "}\n"
+#~ "\n"
+#~ "fn main() {\n"
+#~ " let client = Client::new();\n"
+#~ " let start_url = Url::parse(\"https://www.google.org\").unwrap();\n"
+#~ " let crawl_command = CrawlCommand{ url: start_url, extract_links: "
+#~ "true };\n"
+#~ " match visit_page(&client, &crawl_command) {\n"
+#~ " Ok(links) => println!(\"Links: {links:#?}\"),\n"
+#~ " Err(err) => println!(\"Could not extract links: {err:#}\"),\n"
+#~ " }\n"
+#~ "}\n"
+#~ "```"
+
+#~ msgid ""
+#~ "```shell\n"
+#~ "cargo run\n"
+#~ "```"
+#~ msgstr ""
+#~ "```shell\n"
+#~ "cargo run\n"
+#~ "```"
+
+#~ msgid ""
+#~ "```rust,editable,compile_fail\n"
+#~ "use futures::executor::block_on;\n"
+#~ "\n"
+#~ "async fn count_to(count: i32) {\n"
+#~ " for i in 1..=count {\n"
+#~ " println!(\"Count is: {i}!\");\n"
+#~ " }\n"
+#~ "}\n"
+#~ "\n"
+#~ "async fn async_main(count: i32) {\n"
+#~ " count_to(count).await;\n"
+#~ "}\n"
+#~ "\n"
+#~ "fn main() {\n"
+#~ " block_on(async_main(10));\n"
+#~ "}\n"
+#~ "```"
+#~ msgstr ""
+#~ "```rust,editable,compile_fail\n"
+#~ "use futures::executor::block_on;\n"
+#~ "\n"
+#~ "async fn count_to(count: i32) {\n"
+#~ " for i in 1..=count {\n"
+#~ " println!(\"Count is: {i}!\");\n"
+#~ " }\n"
+#~ "}\n"
+#~ "\n"
+#~ "async fn async_main(count: i32) {\n"
+#~ " count_to(count).await;\n"
+#~ "}\n"
+#~ "\n"
+#~ "fn main() {\n"
+#~ " block_on(async_main(10));\n"
+#~ "}\n"
+#~ "```"
+
+#~ msgid ""
+#~ "**Note:** Please ignore the `// ANCHOR: label` and `// ANCHOR_END: label` "
+#~ "comments you see in the solutions. They are there to make it possible to "
+#~ "re-use parts of the solutions as the exercises."
+#~ msgstr ""
+#~ "**Nota:** Ignora los comentarios `// ANCHOR: label` y `// ANCHOR_END: "
+#~ "label` que aparecen en las soluciones. Están ahí para que sea posible "
+#~ "reutilizar algunas partes de las soluciones de los ejercicios."
#~ msgid "Extra Work in Modern C++"
#~ msgstr "Trabajo adicional en C++ moderno"
@@ -24270,9 +20231,6 @@ msgstr ""
#~ msgid "Double-frees."
#~ msgstr "Errores double free."
-#~ msgid "Memory leaks."
-#~ msgstr "Pérdidas de memoria."
-
#~ msgid "Garbage collection pauses."
#~ msgstr "Pausas en la recolección de memoria residual."
@@ -24459,17 +20417,6 @@ msgstr ""
#~ "println!();\n"
#~ "```"
-#~ msgid ""
-#~ "```rust,should_panic\n"
-#~ "// TODO: remove this when you're done with your implementation.\n"
-#~ "#![allow(unused_variables, dead_code)]\n"
-#~ "```"
-#~ msgstr ""
-#~ "```rust,should_panic\n"
-#~ "// TODO: borra esto cuando termines de implementarlo.\n"
-#~ "#![allow(unused_variables, dead_code)]\n"
-#~ "```"
-
#~ msgid ""
#~ "Note that since `println!` is a macro, `x` is not moved, even using the "
#~ "function like syntax of `println!(\"x: {}\", x)`"