diff --git a/po/pt-BR.po b/po/pt-BR.po index 5d611083cf7..83b4a941906 100644 --- a/po/pt-BR.po +++ b/po/pt-BR.po @@ -5,12 +5,11 @@ msgstr "" "PO-Revision-Date: 2023-08-25 09:32-0700\n" "Last-Translator: \n" "Language-Team: \n" -"Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: pt_BR\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Generator: Poedit 3.3.2\n" #: src/SUMMARY.md:4 src/index.md:1 msgid "Welcome to Comprehensive Rust 🦀" @@ -1414,22 +1413,6 @@ msgstr "" "prontas para uso. Você pode então copiar/colar os exemplos para `src/main." "rs` para experimentá-los:" -#: src/running-the-course/course-structure.md:54 -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:61 msgid "Format" msgstr "Formato" @@ -1618,16 +1601,6 @@ msgstr "" "Entretanto, isto lhe fornece uma versão desatualizada do Rust e pode levar a " "comportamentos inesperados. O comando seria:" -#: 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 msgid "" "We suggest using [VS Code](https://code.visualstudio.com/) to edit the code " @@ -1868,27 +1841,17 @@ msgstr "" msgid "The code blocks in this course are fully interactive:" msgstr "Os blocos de código neste curso são totalmente interativos:" -#: src/cargo/code-samples.md:13 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" println!(\"Edit me!\");\n" -"}\n" -"```" -msgstr "" -"```rust, editable\n" -"fn main() {\n" -" println!(\"Edite-me!\");\n" -"}\n" -"```" +#: src/cargo/code-samples.md:15 src/cargo/running-locally.md:45 +msgid "\"Edit me!\"" +msgstr "\"Edite-me!\"" #: src/cargo/code-samples.md:19 msgid "You can use " msgstr "Você pode usar " #: src/cargo/code-samples.md:19 -msgid " to execute the code when focus is in the text box." -msgstr " para executar o código quando o foco estiver na caixa de texto." +msgid "to execute the code when focus is in the text box." +msgstr "para executar o código quando o foco estiver na caixa de texto." #: src/cargo/code-samples.md:24 msgid "" @@ -1934,22 +1897,6 @@ msgstr "" "fornecer o `rustc` e o `cargo` funcionando. Quando este curso foi escrito, " "as últimas versões estáveis do Rust são:" -#: 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 " @@ -1979,18 +1926,6 @@ msgstr "" "Use `cargo new exercise` para criar um novo diretório `exercise/` para o seu " "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:" @@ -1998,26 +1933,6 @@ msgstr "" "Navegue até `exercise/` e use `cargo run` para compilar e executar seu " "binário:" -#: 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" -"Hello, world!\n" -"```" - #: src/cargo/running-locally.md:40 msgid "" "Replace the boiler-plate code in `src/main.rs` with your own code. For " @@ -2026,42 +1941,10 @@ msgstr "" "Substitua o código gerado em `src/main.rs` pelo seu próprio código. Por " "exemplo, usando o exemplo da página anterior, faça `src/main.rs` parecer como" -#: 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 "Use `cargo run` para compilar e executar seu binário atualizado:" -#: 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/exercise`\n" -"Edit me!\n" -"```" - #: src/cargo/running-locally.md:59 msgid "" "Use `cargo check` to quickly check your project for errors, use `cargo " @@ -2305,19 +2188,9 @@ msgstr "" "Vamos pular para o programa em Rust mais simples possível, o clássico \"Olá " "Mundo\":" -#: src/hello-world.md:6 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" println!(\"Hello 🌍!\");\n" -"}\n" -"```" -msgstr "" -"```rust,editable\n" -"fn main() {\n" -" println!(\"Olá, 🌍!\");\n" -"}\n" -"```" +#: src/hello-world.md:8 +msgid "\"Hello 🌍!\"" +msgstr "\"Olá, 🌍!\"" #: src/hello-world.md:12 msgid "What you see:" @@ -2405,39 +2278,33 @@ msgstr "" msgid "Here is a small example program in Rust:" msgstr "Aqui está um pequeno programa de exemplo em 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" -"```" -msgstr "" -"```rust,editable\n" -"fn main() { // Ponto de entrada do programa\n" -" let mut x: i32 = 6; // Atribuição de uma variável mutável\n" -" print!(\"{x}\"); // Macro para escrever na tela, como printf\n" -" while x != 1 { // Sem parênteses ao redor de expressões\n" -" if x % 2 == 0 { // Matemática como em outras linguagens\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 "// Ponto de entrada do programa\n" + +#: src/hello-world/small-example.md:7 +msgid "// Mutable variable binding\n" +msgstr "// Atribuição de uma variável mutável\n" + +#: src/hello-world/small-example.md:8 src/traits/impl-trait.md:15 +msgid "\"{x}\"" +msgstr "\"{x}\"" + +#: src/hello-world/small-example.md:8 +msgid "// Macro for printing, like printf\n" +msgstr "// Macro para escrever na tela, como printf\n" + +#: src/hello-world/small-example.md:9 +msgid "// No parenthesis around expression\n" +msgstr "// Sem parênteses ao redor de expressões\n" + +#: src/hello-world/small-example.md:10 +msgid "// Math like in other languages\n" +msgstr "// Matemática como em outras linguagens\n" + +#: src/hello-world/small-example.md:15 +msgid "\" -> {x}\"" +msgstr "\" -> {x}\"" #: src/hello-world/small-example.md:23 msgid "" @@ -2968,41 +2835,27 @@ msgstr "" "escape desabilitados: `r\"\\n\" == \"\\\\n\"`. Você pode embutir aspas " "duplas utilizando uma quantidade igual de `#` em Ambos os lados das aspas:" -#: src/basic-syntax/scalar-types.md:27 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" println!(r#\"link\"#);\n" -" println!(\"link\");\n" -"}\n" -"```" -msgstr "" -"```rust,editable\n" -"fn main() {\n" -" println!(r#\"link\"#);\n" -" println!(\"link\");\n" -"}\n" -"```" +#: src/basic-syntax/scalar-types.md:29 +msgid "r#\"link\"#" +msgstr "r#\"link\"#" + +#: src/basic-syntax/scalar-types.md:30 +msgid "\"link\"" +msgstr "\"link\"" #: src/basic-syntax/scalar-types.md:34 msgid "Byte strings allow you to create a `&[u8]` value directly:" msgstr "Strings de byte permitem que você crie um valor `&[u8]` diretamente:" -#: 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 "" -"```rust,editable\n" -"fn main() {\n" -" println!(\"{:?}\", b\"abc\");\n" -" println!(\"{:?}\", &[97, 98, 99]);\n" -"}\n" -"```" +#: src/basic-syntax/scalar-types.md:38 src/basic-syntax/scalar-types.md:39 +#: src/control-flow/if-let-expressions.md:30 src/async/control-flow/join.md:30 +#: src/exercises/day-1/solutions-morning.md:99 +msgid "\"{:?}\"" +msgstr "\"{:?}\"" + +#: src/basic-syntax/scalar-types.md:38 +msgid "b\"abc\"" +msgstr "b\"abc\"" #: src/basic-syntax/scalar-types.md:43 msgid "" @@ -3042,45 +2895,21 @@ msgstr "`()`, `('x',)`, `('x', 1.2)`, ..." msgid "Array assignment and access:" msgstr "Atribuição e acesso a matrizes:" -#: 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 "" -"```rust,editable\n" -"fn main() {\n" -" let mut a: [i8; 10] = [42; 10];\n" -" a[5] = 0;\n" -" println!(\"a: {:?}\", a);\n" -"}\n" -"```" +#: src/basic-syntax/compound-types.md:14 +msgid "\"a: {:?}\"" +msgstr "\"a: {:?}\"" #: src/basic-syntax/compound-types.md:18 msgid "Tuple assignment and access:" msgstr "Atribuição e acesso 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 "" -"```rust,editable\n" -"fn main() {\n" -" let t: (i8, bool) = (7, true);\n" -" println!(\"1º índice: {}\", t.0);\n" -" println!(\"2º índice: {}\", t.1);\n" -"}\n" -"```" +#: src/basic-syntax/compound-types.md:23 +msgid "\"1st index: {}\"" +msgstr "\"1º índice: {}\"" + +#: src/basic-syntax/compound-types.md:24 +msgid "\"2nd index: {}\"" +msgstr "\"2º índice: {}\"" #: src/basic-syntax/compound-types.md:32 msgid "Arrays:" @@ -3167,17 +2996,12 @@ msgstr "" msgid "Like C++, Rust has references:" msgstr "Como C++, o Rust tem referências:" -#: 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:10 src/basic-syntax/variables.md:9 +#: src/ownership/copy-clone.md:9 src/control-flow/blocks.md:22 +#: src/control-flow/while-let-expressions.md:12 +#: src/control-flow/for-expressions.md:12 src/control-flow/break-continue.md:15 +msgid "\"x: {x}\"" +msgstr "\"x: {x}\"" #: src/basic-syntax/references.md:14 msgid "Some notes:" @@ -3223,18 +3047,8 @@ msgstr "" msgid "Rust will statically forbid dangling references:" msgstr "Rust estaticamente proibirá referências pendentes:" -#: 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" -"```" +#: src/basic-syntax/references-dangling.md:12 +msgid "\"ref_x: {ref_x}\"" msgstr "" #: src/basic-syntax/references-dangling.md:16 @@ -3257,29 +3071,13 @@ msgstr "Falaremos mais sobre empréstimos quando chegarmos à _ownership_." msgid "A slice gives you a view into a larger collection:" msgstr "Uma _slice_ (fatia) oferece uma visão de uma coleção maior:" -#: 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 "" -"```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" -"```" +#: src/basic-syntax/slices.md:8 +msgid "\"a: {a:?}\"" +msgstr "\"a: {a:?}\"" + +#: src/basic-syntax/slices.md:12 +msgid "\"s: {s:?}\"" +msgstr "\"s: {s:?}\"" #: src/basic-syntax/slices.md:16 msgid "Slices borrow data from the sliced type." @@ -3368,37 +3166,28 @@ msgstr "`String` vs `str`" msgid "We can now understand the two string types in Rust:" msgstr "Agora podemos entender os dois tipos de strings em 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" -"```" -msgstr "" -"```rust,editable\n" -"fn main() {\n" -" let s1: &str = \"Mundo\";\n" -" println!(\"s1: {s1}\");\n" -"\n" -" let mut s2: String = String::from(\"Olá \");\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 "\"Mundo\"" + +#: src/basic-syntax/string-slices.md:8 +msgid "\"s1: {s1}\"" +msgstr "\"s1: {s1}\"" + +#: src/basic-syntax/string-slices.md:10 src/memory-management/scope-based.md:16 +#: src/memory-management/garbage-collection.md:15 +msgid "\"Hello \"" +msgstr "\"Olá \"" + +#: src/basic-syntax/string-slices.md:11 src/basic-syntax/string-slices.md:13 +#: src/ownership/move-semantics.md:9 +msgid "\"s2: {s2}\"" +msgstr "\"s2: {s2}\"" + +#: src/basic-syntax/string-slices.md:16 +msgid "\"s3: {s3}\"" +msgstr "\"s3: {s3}\"" #: src/basic-syntax/string-slices.md:20 msgid "Rust terminology:" @@ -3479,63 +3268,39 @@ msgstr "" "Uma versão em Rust da famosa pergunta de entrevistas [FizzBuzz](https://en." "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 "" -"```rust,editable\n" -"fn main() {\n" -" imprimir_fizzbuzz_para(20);\n" -"}\n" -"\n" -"fn eh_divisivel(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 eh_divisivel(n, 3) { \"fizz\" } else { \"\" };\n" -" let buzz = if eh_divisivel(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 imprimir_fizzbuzz_para(n: u32) {\n" -" for i in 1..=n {\n" -" println!(\"{}\", fizzbuzz(i));\n" -" }\n" -"}\n" -"```" +#: src/basic-syntax/functions.md:18 +msgid "\"fizz\"" +msgstr "\"fizz\"" + +#: src/basic-syntax/functions.md:18 src/basic-syntax/functions.md:19 +#: src/exercises/day-2/luhn.md:40 src/testing/unit-tests.md:15 +#: src/exercises/day-2/solutions-afternoon.md:65 +#: src/exercises/day-3/solutions-morning.md:112 +#: src/exercises/day-3/solutions-morning.md:114 +#: src/exercises/day-3/solutions-morning.md:118 +#: src/exercises/day-3/solutions-morning.md:136 +#: src/exercises/day-3/solutions-morning.md:140 +msgid "\"\"" +msgstr "\"\"" + +#: src/basic-syntax/functions.md:19 +msgid "\"buzz\"" +msgstr "\"buzz\"" + +#: src/basic-syntax/functions.md:21 +msgid "\"{n}\"" +msgstr "\"{n}\"" + +#: src/basic-syntax/functions.md:23 +msgid "\"{fizz}{buzz}\"" +msgstr "\"{fizz}{buzz}\"" + +#: src/basic-syntax/functions.md:28 src/traits/trait-objects.md:79 +#: src/traits/trait-objects.md:80 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:158 +msgid "\"{}\"" +msgstr "\"{}\"" #: src/basic-syntax/functions.md:35 msgid "" @@ -3584,33 +3349,24 @@ msgstr "" "Todos os itens da linguagem podem ser documentados com a sintaxe 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" -"```" msgstr "" -"```rust,editable\n" "/// Determine se o primeiro argumento é divisível pelo segundo argumento.\n" "///\n" "/// Se o segundo argumento for zero, o resultado é falso.\n" -"fn divisivel_por(lhs: u32, rhs: u32) -> bool {\n" -" if rhs == 0 {\n" -" return false; // Caso excepcional, retorne antes\n" -" }\n" -" lhs % rhs == 0 // A última expressão do bloco é o valor de retorno\n" -"}\n" -"```" + +#: src/basic-syntax/rustdoc.md:11 +msgid "// Corner case, early return\n" +msgstr "// Caso excepcional, retorne antes\n" + +#: src/basic-syntax/rustdoc.md:13 +msgid "// The last expression in a block is the return value\n" +msgstr "// A última expressão do bloco é o valor de retorno\n" #: src/basic-syntax/rustdoc.md:17 msgid "" @@ -3667,55 +3423,13 @@ msgstr "" "Métodos são funções associadas a um tipo específico. O primeiro argumento " "(`self`) de um método é uma instância do tipo ao qual está associado:" -#: 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" -"```" -msgstr "" -"```rust,editable\n" -"struct Retangulo {\n" -" largura: u32,\n" -" altura: u32,\n" -"}\n" -"\n" -"impl Retangulo {\n" -" fn area(&self) -> u32 {\n" -" self.largura * self.altura\n" -" }\n" -"\n" -" fn aum_largura(&mut self, delta: u32) {\n" -" self.largura += delta;\n" -" }\n" -"}\n" -"\n" -"fn main() {\n" -" let mut ret = Retangulo { largura: 10, altura: 5 };\n" -" println!(\"area antiga: {}\", ret.area());\n" -" ret.aum_largura(5);\n" -" println!(\"nova area: {}\", ret.area());\n" -"}\n" -"```" +#: src/basic-syntax/methods.md:24 +msgid "\"old area: {}\"" +msgstr "\"area antiga: {}\"" + +#: src/basic-syntax/methods.md:26 +msgid "\"new area: {}\"" +msgstr "\"nova area: {}\"" #: src/basic-syntax/methods.md:30 msgid "" @@ -3731,21 +3445,6 @@ msgstr "" "Adicione um método estático chamado `Retangulo::new` e o chame a partir de " "`main`:" -#: src/basic-syntax/methods.md:36 -#, fuzzy -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(largura: u32, altura: u32) -> Retangulo {\n" -" Retangulo { largura, altura }\n" -"}\n" -"```" - #: src/basic-syntax/methods.md:42 #, fuzzy msgid "" @@ -3805,29 +3504,21 @@ msgstr "Às vezes macros são utilizadas como alternativa." msgid "However, function parameters can be generic:" msgstr "No entanto, os parâmetros da função podem ser tipos 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" -"```" -msgstr "" -"```rust,editable\n" -"fn escolha_um(a: T, b: T) -> T {\n" -" if std::process::id() % 2 == 0 { a } else { b }\n" -"}\n" -"\n" -"fn main() {\n" -" println!(\"lance da moeda: {}\", escolha_um(\"cara\", \"coroa\"));\n" -" println!(\"prêmio em dinheiro: {}\", escolha_um(500, 1000));\n" -"}\n" -"```" +#: src/basic-syntax/functions-interlude.md:20 +msgid "\"coin toss: {}\"" +msgstr "\"lance da moeda: {}\"" + +#: src/basic-syntax/functions-interlude.md:20 +msgid "\"heads\"" +msgstr "\"cara\"" + +#: src/basic-syntax/functions-interlude.md:20 +msgid "\"tails\"" +msgstr "\"coroa\"" + +#: src/basic-syntax/functions-interlude.md:21 +msgid "\"cash prize: {}\"" +msgstr "\"prêmio em dinheiro: {}\"" #: src/basic-syntax/functions-interlude.md:27 msgid "" @@ -3901,33 +3592,9 @@ msgstr "" "([ao contrário de C++](https://en.cppreference.com/w/cpp/language/" "implicit_conversion)). Você pode ver isso em um programa como este:" -#: 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 "" -"```rust,editable,compile_fail\n" -"fn multiplicar(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} = {}\", multiplicar(x, y));\n" -"}\n" -"```" +#: src/exercises/day-1/implicit-conversions.md:15 +msgid "\"{x} * {y} = {}\"" +msgstr "\"{x} * {y} = {}\"" #: src/exercises/day-1/implicit-conversions.md:19 msgid "" @@ -4001,16 +3668,6 @@ msgstr "Matrizes (_Arrays_) e _Loops_ (Laços) `for`" msgid "We saw that an array can be declared like this:" msgstr "Vimos que uma matriz pode ser declarada assim:" -#: src/exercises/day-1/for-loops.md:5 -msgid "" -"```rust\n" -"let array = [10, 20, 30];\n" -"```" -msgstr "" -"```rust\n" -"let matriz = [10, 20, 30];\n" -"```" - #: src/exercises/day-1/for-loops.md:9 msgid "" "You can print such an array by asking for its debug representation with `{:?}" @@ -4019,21 +3676,9 @@ msgstr "" "Você pode imprimir tal matriz solicitando sua representação de depuração com " "`{:?}`:" -#: 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 "" -"```rust,editable\n" -"fn main() {\n" -" let matriz = [10, 20, 30];\n" -" println!(\"matriz: {matriz:?}\");\n" -"}\n" -"```" +#: src/exercises/day-1/for-loops.md:14 +msgid "\"array: {array:?}\"" +msgstr "\"matriz: {matriz:?}\"" #: src/exercises/day-1/for-loops.md:18 msgid "" @@ -4043,41 +3688,21 @@ msgstr "" "Rust permite iterar em coisas como matrizes e _ranges_ (faixas ou " "intervalos) usando a palavra-chave `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" -"```" -msgstr "" -"```rust,editable\n" -"fn main() {\n" -" let matriz = [10, 20, 30];\n" -" print!(\"Iterando sobre a matriz:\");\n" -" for n in &matriz {\n" -" print!(\" {n}\");\n" -" }\n" -" println!();\n" -"\n" -" print!(\"Iterando sobre um range:\");\n" -" for i in 0..3 {\n" -" print!(\" {}\", matriz[i]);\n" -" }\n" -" println!();\n" -"}\n" -"```" +#: src/exercises/day-1/for-loops.md:24 +msgid "\"Iterating over array:\"" +msgstr "\"Iterando sobre a matriz:\"" + +#: src/exercises/day-1/for-loops.md:26 +msgid "\" {n}\"" +msgstr "\" {n}\"" + +#: src/exercises/day-1/for-loops.md:30 +msgid "\"Iterating over range:\"" +msgstr "\"Iterando sobre um range:\"" + +#: src/exercises/day-1/for-loops.md:32 +msgid "\" {}\"" +msgstr "\" {}\"" #: src/exercises/day-1/for-loops.md:38 msgid "" @@ -4110,70 +3735,35 @@ msgstr "" "Copie o código abaixo para e implemente as " "funções:" -#: src/exercises/day-1/for-loops.md:52 -msgid "" -"```rust,should_panic\n" -"// TODO: remove this when you're done with your implementation.\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" -"```" -msgstr "" -"```rust,should_panic\n" -"// TODO: remova isto quando você terminar sua implementação .\n" -"#![allow(unused_variables, dead_code)]\n" -"\n" -"fn transpose(matriz: [[i32; 3]; 3]) -> [[i32; 3]; 3] {\n" -" unimplemented!()\n" -"}\n" -"\n" -"fn pretty_print(matriz: &[[i32; 3]; 3]) {\n" -" unimplemented!()\n" -"}\n" -"\n" -"fn main() {\n" -" let matriz = [\n" -" [101, 102, 103], // <-- o comentário faz com que o rustfmt adicione " -"uma nova linha\n" -" [201, 202, 203],\n" -" [301, 302, 303],\n" -" ];\n" -"\n" -" println!(\"matriz:\");\n" -" pretty_print(&matriz);\n" -"\n" -" let transposed = transpose(matriz);\n" -" println!(\"transposta:\");\n" -" pretty_print(&transposed);\n" -"}\n" -"```" - -#: src/exercises/day-1/for-loops.md:80 -msgid "Bonus Question" -msgstr "Pergunta Bônus" - -#: src/exercises/day-1/for-loops.md:82 +#: src/exercises/day-1/for-loops.md:53 +#: src/exercises/day-2/health-statistics.md:14 +#: src/exercises/day-2/points-polygons.md:8 src/exercises/day-2/luhn.md:26 +#: src/exercises/day-2/strings-iterators.md:13 +#: src/exercises/day-3/simple-gui.md:19 +#: src/exercises/day-3/safe-ffi-wrapper.md:49 +msgid "// TODO: remove this when you're done with your implementation.\n" +msgstr "// TODO: remova isto quando você terminar sua implementação .\n" + +#: src/exercises/day-1/for-loops.md:66 +#: src/exercises/day-1/solutions-morning.md:65 +msgid "// <-- the comment makes rustfmt add a newline\n" +msgstr "// <-- o comentário faz com que o rustfmt adicione uma nova linha\n" + +#: src/exercises/day-1/for-loops.md:71 +#: src/exercises/day-1/solutions-morning.md:70 +msgid "\"matrix:\"" +msgstr "\"matriz:\"" + +#: src/exercises/day-1/for-loops.md:75 +#: src/exercises/day-1/solutions-morning.md:74 +msgid "\"transposed:\"" +msgstr "\"transposta:\"" + +#: src/exercises/day-1/for-loops.md:80 +msgid "Bonus Question" +msgstr "Pergunta Bônus" + +#: src/exercises/day-1/for-loops.md:82 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 " @@ -4227,7 +3817,7 @@ msgid "" "`[i32; 3]` is also a copy type." msgstr "" "Uma cópia implícita da matriz teria ocorrido. Como `i32` é um tipo de cópia " -"(*copy type*), então `[i32; 3]` também é um tipo de cópia." +"(_copy type_), então `[i32; 3]` também é um tipo de cópia." #: src/basic-syntax/variables.md:3 msgid "" @@ -4237,16 +3827,10 @@ msgstr "" "Rust fornece segurança de tipo por meio de tipagem estática. Variáveis são " "imutáveis por padrão:" -#: src/basic-syntax/variables.md:6 +#: src/basic-syntax/variables.md:10 msgid "" -"```rust,editable\n" -"fn main() {\n" -" let x: i32 = 10;\n" -" println!(\"x: {x}\");\n" -" // x = 20;\n" +"// x = 20;\n" " // println!(\"x: {x}\");\n" -"}\n" -"```" msgstr "" #: src/basic-syntax/variables.md:17 @@ -4261,45 +3845,17 @@ msgstr "" msgid "Rust will look at how the variable is _used_ to determine the type:" msgstr "Rust verá como a variável é _usada_ para determinar o 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 "" -"```rust,editable\n" -"fn recebe_u32(x: u32) {\n" -" println!(\"u32: {x}\");\n" -"}\n" -"\n" -"fn recebe_i8(y: i8) {\n" -" println!(\"i8: {y}\");\n" -"}\n" -"\n" -"fn main() {\n" -" let x = 10;\n" -" let y = 20;\n" -"\n" -" recebe_u32(x);\n" -" recebe_i8(y);\n" -" // recebe_u32(y);\n" -"}\n" -"```" +#: src/basic-syntax/type-inference.md:7 +msgid "\"u32: {x}\"" +msgstr "\"u32: {x}\"" + +#: src/basic-syntax/type-inference.md:11 +msgid "\"i8: {y}\"" +msgstr "\"i8: {y}\"" + +#: src/basic-syntax/type-inference.md:20 +msgid "// takes_u32(y);\n" +msgstr "// recebe_u32(y);\n" #: src/basic-syntax/type-inference.md:26 msgid "" @@ -4333,31 +3889,15 @@ msgstr "" "contêiner genérico sem que o código especifique explicitamente o tipo " "contido, usando `_` como _placeholder_:" -#: 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 "" -"```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" -"```" +#: src/basic-syntax/type-inference.md:39 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 "\"v: {v:?}\"" + +#: src/basic-syntax/type-inference.md:42 +msgid "\"vv: {vv:?}\"" +msgstr "\"vv: {vv:?}\"" #: src/basic-syntax/type-inference.md:46 msgid "" @@ -4399,45 +3939,17 @@ msgstr "" "Constantes são avaliadas em tempo de compilação e seus valores são " "incorporados onde quer que sejam usados:" -#: 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 "" -"```rust,editable\n" -"const TAMANHO_RESUMO: usize = 3;\n" -"const ZERO: Option = Some(42);\n" -"\n" -"fn computar_resumo(texto: &str) -> [u8; TAMANHO_RESUMO] {\n" -" let mut resumo = [ZERO.unwrap_or(0); TAMANHO_RESUMO];\n" -" for (idx, &b) in texto.as_bytes().iter().enumerate() {\n" -" resumo[idx % TAMANHO_RESUMO] = resumo[idx % TAMANHO_RESUMO]." -"wrapping_add(b);\n" -" }\n" -" resumo\n" -"}\n" -"\n" -"fn main() {\n" -" let resumo = computar_resumo(\"Olá\");\n" -" println!(\"Resumo: {resumo:?}\");\n" -"}\n" -"```" +#: src/basic-syntax/static-and-const.md:24 src/memory-management/stack.md:8 +#: src/memory-management/stack.md:36 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 "\"Olá\"" + +#: src/basic-syntax/static-and-const.md:25 +msgid "\"Digest: {digest:?}\"" +msgstr "\"Resumo: {resumo:?}\"" #: src/basic-syntax/static-and-const.md:29 msgid "" @@ -4469,23 +3981,13 @@ msgstr "" "Variáveis estáticas permanecerão válidas durante toda a execução do programa " "e, portanto, não serão movidas:" -#: 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" -"```" -msgstr "" -"```rust,editable\n" -"static BANNER: &str = \"Bem-vindo ao RustOS 3.14\";\n" -"\n" -"fn main() {\n" -" println!(\"{BANNER}\");\n" -"}\n" -"```" +#: src/basic-syntax/static-and-const.md:38 +msgid "\"Welcome to RustOS 3.14\"" +msgstr "\"Bem-vindo ao RustOS 3.14\"" + +#: src/basic-syntax/static-and-const.md:41 +msgid "\"{BANNER}\"" +msgstr "\"{BANNER}\"" #: src/basic-syntax/static-and-const.md:45 msgid "" @@ -4624,41 +4126,26 @@ msgstr "" "Você pode sobrepor (_shadow_) variáveis, tanto aquelas de escopos externos " "quanto variáveis do mesmo escopo:" -#: 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" -"```" -msgstr "" -"```rust,editable\n" -"fn main() {\n" -" let a = 10;\n" -" println!(\"antes: {a}\");\n" -"\n" -" {\n" -" let a = \"olá\";\n" -" println!(\"escopo interno: {a}\");\n" -"\n" -" let a = true;\n" -" println!(\"sobreposto no escopo interno: {a}\");\n" -" }\n" -"\n" -" println!(\"depois: {a}\");\n" -"}\n" -"```" +#: src/basic-syntax/scopes-shadowing.md:9 +msgid "\"before: {a}\"" +msgstr "\"antes: {a}\"" + +#: src/basic-syntax/scopes-shadowing.md:12 src/traits/from-into.md:7 +#: src/traits/from-into.md:19 +msgid "\"hello\"" +msgstr "\"olá\"" + +#: src/basic-syntax/scopes-shadowing.md:13 +msgid "\"inner scope: {a}\"" +msgstr "\"escopo interno: {a}\"" + +#: src/basic-syntax/scopes-shadowing.md:16 +msgid "\"shadowed in inner scope: {a}\"" +msgstr "\"sobreposto no escopo interno: {a}\"" + +#: src/basic-syntax/scopes-shadowing.md:19 +msgid "\"after: {a}\"" +msgstr "\"depois: {a}\"" #: src/basic-syntax/scopes-shadowing.md:25 msgid "" @@ -4693,25 +4180,9 @@ msgstr "" "reutilizar locais de memória ao sobrepor uma variável imutável em um escopo, " "mesmo que o tipo não seja alterado." -#: 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 "" -"```rust,editable\n" -"fn main() {\n" -" let a = 1;\n" -" let b = &a;\n" -" let a = a + 1;\n" -" println!(\"{a} {b}\");\n" -"}\n" -"```" +#: src/basic-syntax/scopes-shadowing.md:35 src/testing/test-modules.md:8 +msgid "\"{a} {b}\"" +msgstr "\"{a} {b}\"" #: src/memory-management.md:3 msgid "Traditionally, languages have fallen into two broad categories:" @@ -4805,50 +4276,6 @@ msgstr "" "A criação de uma `String` coloca metadados de tamanho fixo na pilha e dados " "dinamicamente dimensionados - a string propriamente dita - no _heap_:" -#: src/memory-management/stack.md:6 -msgid "" -"```rust,editable\n" -"fn main() {\n" -" let s1 = String::from(\"Hello\");\n" -"}\n" -"```" -msgstr "" -"```rust,editable\n" -"fn main() {\n" -" let s1 = String::from(\"Hello\");\n" -"}\n" -"```" - -#: 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" -"```" -msgstr "" -"```bob\n" -" Pilha Heap\n" -".- - - - - - - - - - - - - - -. .- - - - - - - - - - - - - - - -.\n" -": : : :\n" -": : : :\n" -": +------------+-------+ : : +----+----+----+----+----+ :\n" -": | ptr | o---+----+-----+-->| H | e | l | l | o | :\n" -": | tamanho | 5 | : : +----+----+----+----+----+ :\n" -": | capacidade | 5 | : : :\n" -": +------------+-------+ : : :\n" -": : `- - - - - - - - - - - - - - - -'\n" -"`- - - - - - - - - - - - - - -'\n" -"```" - #: src/memory-management/stack.md:28 msgid "" "Mention that a `String` is backed by a `Vec`, so it has a capacity and " @@ -4879,42 +4306,30 @@ msgstr "" "Podemos inspecionar o layout da memória com código inseguro (`unsafe`). No " "entanto, você deve apontar que isso é legitimamente inseguro!" -#: src/memory-management/stack.md:34 +#: src/memory-management/stack.md:37 src/control-flow/if-let-expressions.md:34 +#: src/testing/unit-tests.md:7 src/exercises/day-2/solutions-afternoon.md:27 +msgid "' '" +msgstr "' '" + +#: src/memory-management/stack.md:38 +msgid "\"world\"" +msgstr "\"mundo\"" + +#: src/memory-management/stack.md:39 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 "" -"```rust,editable\n" -"fn main() {\n" -" let mut s1 = String::from(\"Olá\");\n" -" s1.push(' ');\n" -" s1.push_str(\"mundo\");\n" -" // NÃO FAÇA ISSO EM CASA! Somente com propósito educacional.\n" +"// NÃO FAÇA ISSO EM CASA! Somente com propósito educacional.\n" " // String não fornece nenhuma garantia sobre o seu layout, então isso " "pode causar\n" " // um comportamento indefinido.\n" -" unsafe {\n" -" let (ptr, capacity, len): (usize, usize, usize) = std::mem::" -"transmute(s1);\n" -" println!(\"Ponteiro = {ptr:#x}, tamanho = {len}, capacidade = " -"{capacity}\");\n" -" }\n" -"}\n" -"```" + +#: src/memory-management/stack.md:44 +msgid "\"ptr = {ptr:#x}, len = {len}, capacity = {capacity}\"" +msgstr "\"Ponteiro = {ptr:#x}, tamanho = {len}, capacidade = {capacity}\"" #: src/memory-management/manual.md:3 msgid "You allocate and deallocate heap memory yourself." @@ -4936,27 +4351,15 @@ msgstr "Exemplo em C" msgid "You must call `free` on every pointer you allocate with `malloc`:" msgstr "Você deve chamar `free` em cada ponteiro que alocar com `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 "" -"```c\n" -"void foo(size_t n) {\n" -" int* int_matriz = (int*)malloc(n * sizeof(int));\n" -" //\n" +"//\n" " // ... várias linhas de código\n" " //\n" -" free(int_matriz);\n" -"}\n" -"```" #: src/memory-management/manual.md:21 msgid "" @@ -5000,20 +4403,6 @@ msgstr "" msgid "C++ Example" msgstr "Exemplo em 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 diga_ola(std::unique_ptr pessoa) {\n" -" std::cout << \"Olá \" << pessoa->nome << 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 " @@ -5037,17 +4426,9 @@ msgstr "" "Construtores especiais de movimento (_move_) são usados ao passar o " "_\"ownership\"_ para uma função:" -#: 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 "" -"```c++\n" -"std::unique_ptr pessoa = encontrar_pessoa(\"Carla\");\n" -"diga_ola(std::move(pessoa));\n" -"```" +#: src/memory-management/scope-based.md:28 +msgid "\"Carla\"" +msgstr "\"Carla\"" #: src/memory-management/garbage-collection.md:1 msgid "Automatic Memory Management" @@ -5081,20 +4462,6 @@ msgstr "Exemplo em Java" msgid "The `person` object is not deallocated after `sayHello` returns:" msgstr "O objeto `pessoa` não é desalocado depois que `digaOla` retorna:" -#: 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 digaOla(Pessoa pessoa) {\n" -" System.out.println(\"Olá \" + pessoa.obterNome());\n" -"}\n" -"```" - #: src/memory-management/rust.md:1 msgid "Memory Management in Rust" msgstr "Gerenciamento de Memória no Rust" @@ -5263,29 +4630,13 @@ msgstr "" "Todas as associações de variáveis têm um _escopo_ onde são válidas e é um " "erro usar uma variável fora de seu escopo:" -#: 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 "" -"```rust,editable,compile_fail\n" -"fn main() {\n" -" {\n" -" let p = Ponto(3, 4);\n" -" println!(\"x: {}\", p.0);\n" -" }\n" -" println!(\"y: {}\", p.1);\n" -"}\n" -"```" +#: src/ownership.md:12 +msgid "\"x: {}\"" +msgstr "\"x: {}\"" + +#: src/ownership.md:14 +msgid "\"y: {}\"" +msgstr "\"y: {}\"" #: src/ownership.md:18 msgid "" @@ -5306,25 +4657,13 @@ msgstr "Dizemos que a variável _possui_ (_owns_) o valor." msgid "An assignment will transfer _ownership_ between variables:" msgstr "Uma atribuição transferirá o _ownership_ entre variáveis:" -#: 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" -"```" -msgstr "" -"```rust,editable\n" -"fn main() {\n" -" let s1: String = String::from(\"Olá!\");\n" -" let s2: String = s1;\n" -" println!(\"s2: {s2}\");\n" -" // println!(\"s1: {s1}\");\n" -"}\n" -"```" +#: src/ownership/move-semantics.md:7 +msgid "\"Hello!\"" +msgstr "\"Olá!\"" + +#: src/ownership/move-semantics.md:10 +msgid "// println!(\"s1: {s1}\");\n" +msgstr "// println!(\"s1: {s1}\");\n" #: src/ownership/move-semantics.md:14 msgid "The assignment of `s1` to `s2` transfers ownership." @@ -5373,14 +4712,8 @@ msgstr "" msgid "In Rust, clones are explicit (by using `clone`)." msgstr "No Rust, clones são explícitos (utilizando-se `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" -"```" +#: src/ownership/moved-strings-rust.md:5 +msgid "\"Rust\"" msgstr "" #: src/ownership/moved-strings-rust.md:10 @@ -5395,38 +4728,6 @@ msgstr "Quando `s1` sai do escopo, nada acontece (foi movido dele)." msgid "Before move to `s2`:" msgstr "Antes de mover para `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 "" -"```bob\n" -" Pilha Heap\n" -".- - - - - - - - - - - - - -. .- - - - - - - - - - - - - -.\n" -": : : :\n" -": s1 : : :\n" -": +------------+------+ : : +----+----+----+----+ :\n" -": | ponteiro | o---+---+-----+-->| R | u | s | t | :\n" -": | tamanho | 4 | : : +----+----+----+----+ :\n" -": | capacidade | 4 | : : :\n" -": +------------+------+ : : :\n" -": : `- - - - - - - - - - - - - -'\n" -": :\n" -"`- - - - - - - - - - - - - -'\n" -"```" - #: src/ownership/moved-strings-rust.md:30 msgid "After move to `s2`:" msgstr "Depois de mover para `s2`:" @@ -5483,17 +4784,13 @@ msgstr "Trabalho Extra em C++ Moderno" msgid "Modern C++ solves this differently:" msgstr "O C++ moderno resolve isso de maneira 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" -"```" -msgstr "" -"```c++\n" -"std::string s1 = \"Cpp\";\n" -"std::string s2 = s1; // Duplica os dados em s1.\n" -"```" +#: src/ownership/double-free-modern-cpp.md:6 +msgid "\"Cpp\"" +msgstr "\"Cpp\"" + +#: src/ownership/double-free-modern-cpp.md:7 +msgid "// Duplicate the data in s1.\n" +msgstr "// Duplica os dados em s1.\n" #: src/ownership/double-free-modern-cpp.md:10 msgid "" @@ -5510,84 +4807,10 @@ msgstr "Quando `s1` e `s2` saem de escopo, cada um libera sua própria memória. msgid "Before copy-assignment:" msgstr "Antes da atribuição por cópia:" -#: 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" -" Pilha Heap\n" -".- - - - - - - - - - - - - -. .- - - - - - - - - - - -.\n" -": : : :\n" -": s1 : : :\n" -": +-----------+-------+ : : +----+----+----+ :\n" -": | ptr | o---+---+--+--+-->| C | p | p | :\n" -": | tam | 3 | : : +----+----+----+ :\n" -": | capac | 3 | : : :\n" -": +-----------+-------+ : : :\n" -": : `- - - - - - - - - - - -'\n" -"`- - - - - - - - - - - - - -'\n" -"```" - #: src/ownership/double-free-modern-cpp.md:30 msgid "After copy-assignment:" msgstr "Após atribuição por cópia:" -#: 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" -" Pilha Heap\n" -".- - - - - - - - - - - - - -. .- - - - - - - - - - - -.\n" -": : : :\n" -": s1 : : :\n" -": +-----------+-------+ : : +----+----+----+ :\n" -": | ptr | o---+---+--+--+-->| C | p | p | :\n" -": | tam | 3 | : : +----+----+----+ :\n" -": | capac | 3 | : : :\n" -": +-----------+-------+ : : :\n" -": : : :\n" -": s2 : : :\n" -": +-----------+-------+ : : +----+----+----+ :\n" -": | ptr | o---+---+-----+-->| C | p | p | :\n" -": | tam | 3 | : : +----+----+----+ :\n" -": | capac | 3 | : : :\n" -": +-----------+-------+ : : :\n" -": : `- - - - - - - - - - - -'\n" -"`- - - - - - - - - - - - - -'\n" -"```" - #: src/ownership/moves-function-calls.md:3 msgid "" "When you pass a value to a function, the value is assigned to the function " @@ -5596,31 +4819,18 @@ msgstr "" "Quando você passa um valor para uma função, o valor é atribuído ao parâmetro " "da função. Isso transfere a _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" -"```" -msgstr "" -"```rust,editable\n" -"fn diga_ola(nome: String) {\n" -" println!(\"Olá {nome}\")\n" -"}\n" -"\n" -"fn main() {\n" -" let nome = String::from(\"Alice\");\n" -" diga_ola(nome);\n" -" // diga_ola(nome);\n" -"}\n" -"```" +#: src/ownership/moves-function-calls.md:8 src/traits/impl-trait.md:10 +msgid "\"Hello {name}\"" +msgstr "\"Olá {nome}\"" + +#: src/ownership/moves-function-calls.md:12 +#: src/android/interoperability/java.md:56 +msgid "\"Alice\"" +msgstr "\"Alice\"" + +#: src/ownership/moves-function-calls.md:14 +msgid "// say_hello(name);\n" +msgstr "// diga_ola(nome);\n" #: src/ownership/moves-function-calls.md:20 msgid "" @@ -5670,25 +4880,9 @@ msgstr "" "Embora a semântica de movimento seja o padrão, certos tipos são copiados por " "padrão:" -#: 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 "" -"```rust,editable\n" -"fn main() {\n" -" let x = 42;\n" -" let y = x;\n" -" println!(\"x: {x}\");\n" -" println!(\"y: {y}\");\n" -"}\n" -"```" +#: src/ownership/copy-clone.md:10 src/control-flow/blocks.md:11 +msgid "\"y: {y}\"" +msgstr "\"y: {y}\"" #: src/ownership/copy-clone.md:14 msgid "These types implement the `Copy` trait." @@ -5699,31 +4893,13 @@ msgid "You can opt-in your own types to use copy semantics:" msgstr "" "Você pode habilitar seus próprios tipos para usar a semântica de cópia:" -#: 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 "" -"```rust,editable\n" -"#[derive(Copy, Clone, Debug)]\n" -"struct Ponto(i32, i32);\n" -"\n" -"fn main() {\n" -" let p1 = Ponto(3, 4);\n" -" let p2 = p1;\n" -" println!(\"p1: {p1:?}\");\n" -" println!(\"p2: {p2:?}\");\n" -"}\n" -"```" +#: src/ownership/copy-clone.md:25 +msgid "\"p1: {p1:?}\"" +msgstr "\"p1: {p1:?}\"" + +#: src/ownership/copy-clone.md:26 +msgid "\"p2: {p2:?}\"" +msgstr "\"p2: {p2:?}\"" #: src/ownership/copy-clone.md:30 msgid "After the assignment, both `p1` and `p2` own their own data." @@ -5806,39 +4982,9 @@ msgstr "" "Em vez de transferir a ownership ao chamar uma função, você pode permitir " "que uma função _empreste_ o 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 "" -"```rust,editable\n" -"#[derive(Debug)]\n" -"struct Ponto(i32, i32);\n" -"\n" -"fn somar(p1: &Ponto, p2: &Ponto) -> Ponto {\n" -" Ponto(p1.0 + p2.0, p1.1 + p2.1)\n" -"}\n" -"\n" -"fn main() {\n" -" let p1 = Ponto(3, 4);\n" -" let p2 = Ponto(10, 20);\n" -" let p3 = somar(&p1, &p2);\n" -" println!(\"{p1:?} + {p2:?} = {p3:?}\");\n" -"}\n" -"```" +#: src/ownership/borrowing.md:18 src/ownership/borrowing.md:45 +msgid "\"{p1:?} + {p2:?} = {p3:?}\"" +msgstr "\"{p1:?} + {p2:?} = {p3:?}\"" #: src/ownership/borrowing.md:22 msgid "The `add` function _borrows_ two points and returns a new point." @@ -5870,43 +5016,15 @@ msgstr "" "nível de otimização \"DEBUG\", os endereços devem mudar, enquanto eles " "permanecem os mesmos quando a configuração é alterada para \"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 "" -"```rust,editable\n" -"#[derive(Debug)]\n" -"struct Ponto(i32, i32);\n" -"\n" -"fn somar(p1: &Ponto, p2: &Ponto) -> Ponto {\n" -" Ponto(p1.0 + p2.0, p1.1 + p2.1)\n" -"}\n" -"\n" -" pub fn main() {\n" -" let p1 = Ponto(3, 4);\n" -" let p2 = Ponto(10, 20);\n" -" let p3 = somar(&p1, &p2);\n" -" println!(\"&p3.0: {:p}\", &p3.0);\n" -" println!(\"{p1:?} + {p2:?} = {p3:?}\");\n" -" }\n" -"```" +#: src/ownership/borrowing.md:36 +#, fuzzy +msgid "\"&p.0: {:p}\"" +msgstr "\"&p3.0: {:p}\"" + +#: src/ownership/borrowing.md:44 +#, fuzzy +msgid "\"&p3.0: {:p}\"" +msgstr "\"{p1:?} + {p2:?} = {p3:?}\"" #: src/ownership/borrowing.md:48 msgid "The Rust compiler can do return value optimization (RVO)." @@ -5938,37 +5056,13 @@ msgstr "Você pode ter um ou mais valores `&T` a qualquer momento, _ou_" msgid "You can have exactly one `&mut T` value." msgstr "Você pode ter exatamente um 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 "" -"```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" -"```" +#: src/ownership/shared-unique-borrows.md:18 src/std/rc.md:13 +msgid "\"a: {a}\"" +msgstr "\"a: {a}\"" + +#: src/ownership/shared-unique-borrows.md:19 src/std/rc.md:14 +msgid "\"b: {b}\"" +msgstr "\"b: {b}\"" #: src/ownership/shared-unique-borrows.md:25 msgid "" @@ -6053,39 +5147,10 @@ msgstr "" "Além de emprestar seus argumentos, uma função pode retornar um valor " "emprestado:" -#: 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 "" -"```rust,editable\n" -"#[derive(Debug)]\n" -"struct Ponto(i32, i32);\n" -"\n" -"fn mais_a_esquerda<'a>(p1: &'a Ponto, p2: &'a Ponto) -> &'a Ponto {\n" -" if p1.0 < p2.0 { p1 } else { p2 }\n" -"}\n" -"\n" -"fn main() {\n" -" let p1: Ponto = Ponto(10, 10);\n" -" let p2: Ponto = Ponto(20, 20);\n" -" let p3: &Ponto = mais_a_esquerda(&p1, &p2);\n" -" println!(\"Ponto mais à esquerda: {:?}\", p3);\n" -"}\n" -"```" +#: src/ownership/lifetimes-function-calls.md:17 +#: src/ownership/lifetimes-function-calls.md:47 +msgid "\"left-most point: {:?}\"" +msgstr "\"Ponto mais à esquerda: {:?}\"" #: src/ownership/lifetimes-function-calls.md:21 msgid "`'a` is a generic parameter, it is inferred by the compiler." @@ -6110,46 +5175,6 @@ msgstr "" "Mova a declaração de `p2` e `p3` para um novo escopo (`{ ... }`), resultando " "no seguinte 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 "" -"```rust,ignore\n" -"#[derive(Debug)]\n" -"struct Ponto(i32, i32);\n" -"\n" -"fn mais_a_esquerda<'a>(p1: &'a Ponto, p2: &'a Ponto) -> &'a Ponto {\n" -" if p1.0 < p2.0 { p1 } else { p2 }\n" -"}\n" -"\n" -"fn main() {\n" -" let p1: Ponto = Ponto(10, 10);\n" -" let p3: &Ponto;\n" -" {\n" -" let p2: Ponto = Ponto(20, 20);\n" -" p3 = mais_a_esquerda(&p1, &p2);\n" -" }\n" -" println!(\"ponto mais à esquerda: {:?}\", p3);\n" -"}\n" -"```" - #: src/ownership/lifetimes-function-calls.md:50 msgid "Note how this does not compile since `p3` outlives `p2`." msgstr "Note como isto não compila uma vez que `p3` vive mais que `p2`." @@ -6200,45 +5225,25 @@ msgstr "" "Se um tipo de dados armazena dados emprestados, ele deve ser anotado com um " "tempo 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" -"```" -msgstr "" -"```rust,editable\n" -"#[derive(Debug)]\n" -"struct Destaque<'doc>(&'doc str);\n" -"\n" -"fn apagar(texto: String) {\n" -" println!(\"Até logo {texto}!\");\n" -"}\n" -"\n" -"fn main() {\n" -" let texto = String::from(\"A raposa marrom ágil pula sobre o cachorro " -"preguiçoso.\");\n" -" let raposa = Destaque(&texto[2..21]);\n" -" let cachorro = Destaque(&texto[35..53]);\n" -" // apagar(texto);\n" -" println!(\"{raposa:?}\");\n" -" println!(\"{cachorro:?}\");\n" -"}\n" -"```" +#: src/ownership/lifetimes-data-structures.md:10 +msgid "\"Bye {text}!\"" +msgstr "\"Até logo {texto}!\"" + +#: src/ownership/lifetimes-data-structures.md:14 +msgid "\"The quick brown fox jumps over the lazy dog.\"" +msgstr "\"A raposa marrom ágil pula sobre o cachorro preguiçoso.\"" + +#: src/ownership/lifetimes-data-structures.md:17 +msgid "// erase(text);\n" +msgstr "// apagar(texto);\n" + +#: src/ownership/lifetimes-data-structures.md:18 +msgid "\"{fox:?}\"" +msgstr "\"{raposa:?}\"" + +#: src/ownership/lifetimes-data-structures.md:19 +msgid "\"{dog:?}\"" +msgstr "\"{cachorro:?}\"" #: src/ownership/lifetimes-data-structures.md:25 msgid "" @@ -6321,31 +5326,13 @@ msgstr "" "Nós iremos aprender muito mais sobre _structs_ e o tipo `Vec` amanhã. Por " "hora, você só precisa conhecer parte de sua API:" -#: src/exercises/day-1/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" -"```" -msgstr "" -"```rust, editable\n" -"fn main() {\n" -" let mut vetor = vec![10, 20];\n" -" vetor.push(30);\n" -" let ponto_central = vetor.len() / 2;\n" -" println!(\"valor do meio: {}\", vetor[ponto_central]);\n" -" for item in vetor.iter() {\n" -" println!(\"item: {item}\");\n" -" }\n" -"}\n" -"```" +#: src/exercises/day-1/book-library.md:11 +msgid "\"middle value: {}\"" +msgstr "\"valor do meio: {}\"" + +#: src/exercises/day-1/book-library.md:13 +msgid "\"item: {item}\"" +msgstr "\"item: {item}\"" #: src/exercises/day-1/book-library.md:18 msgid "" @@ -6356,69 +5343,101 @@ msgstr "" "código abaixo para e atualize os tipos para " "compilar:" -#: src/exercises/day-1/book-library.md:21 +#: src/exercises/day-1/book-library.md:32 +#: src/exercises/day-1/solutions-afternoon.md:33 +msgid "// This is a constructor, used below.\n" +msgstr "// Este é um construtor, utilizado abaixo.\n" + +#: src/exercises/day-1/book-library.md:40 +#: src/exercises/day-1/solutions-afternoon.md:41 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" "//\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" +msgstr "" +"// Implemente os métodos abaixo. Atualize o parâmetro `self` para\n" +"// indicar o nível requerido de ownership sobre o objeto:\n" +"//\n" +"// - `&self` para acesso compartilhado de apenas leitura,\n" +"// - `&mut self` para acesso mutável exclusivo,\n" +"// - `self` para acesso exclusivo por valor.\n" + +#: src/exercises/day-1/book-library.md:49 +msgid "\"Initialize and return a `Library` value\"" +msgstr "\"Inicialize e retorne um valor `Biblioteca`\"" + +#: src/exercises/day-1/book-library.md:52 +msgid "" +"//fn len(self) -> usize {\n" " // todo!(\"Return the length of `self.books`\")\n" " //}\n" -"\n" -" //fn is_empty(self) -> bool {\n" +msgstr "" +"//fn tamanho(self) -> usize {\n" +" // todo!(\"Retorne o tamanho de `self.livros`\")\n" +" //}\n" + +#: src/exercises/day-1/book-library.md:56 +msgid "" +"//fn is_empty(self) -> bool {\n" " // todo!(\"Return `true` if `self.books` is empty\")\n" " //}\n" -"\n" -" //fn add_book(self, book: Book) {\n" +msgstr "" +"//fn esta_vazia(self) -> bool {\n" +" // todo!(\"Retorne `true` se `self.livros` for vazio\")\n" +" //}\n" + +#: src/exercises/day-1/book-library.md:60 +msgid "" +"//fn add_book(self, book: Book) {\n" " // todo!(\"Add a new book to `self.books`\")\n" " //}\n" -"\n" -" //fn print_books(self) {\n" +msgstr "" +"//fn adicionar_livro(self, book: Livro) {\n" +" // todo!(\"Adicione um novo livro em `self.livros`\")\n" +" //}\n" + +#: src/exercises/day-1/book-library.md:64 +msgid "" +"//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" +msgstr "" +"//fn imprimir_livros(self) {\n" +" // todo!(\"Itere sobre `self.livros` e sobre o título e ano de cada " +"livro\")\n" +" //}\n" + +#: src/exercises/day-1/book-library.md:68 +msgid "" +"//fn oldest_book(self) -> Option<&Book> {\n" " // todo!(\"Return a reference to the oldest book (if any)\")\n" " //}\n" -"}\n" -"\n" +msgstr "" +"//fn livro_mais_antigo(self) -> Option<&Livro> {\n" +" // todo!(\"Retorne uma referência para o livro mais antigo (se " +"houver)\")\n" +" //}\n" + +#: src/exercises/day-1/book-library.md:72 +msgid "" "// 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." +msgstr "" +"// Isto demonstra o comportamento esperado. Descomente o código abaixo e\n" +"// implemente os métodos que faltam. Você precisará atualizar as\n" +"// assinaturas dos métodos, incluindo o parâmetro \"self\"! Você talvez\n" +"// precise atualizar as atribuições de variável dentro de `main()`.\n" + +#: src/exercises/day-1/book-library.md:80 +#: src/exercises/day-1/solutions-afternoon.md:124 +msgid "" +"//println!(\"The library is empty: library.is_empty() -> {}\", library." "is_empty());\n" " //\n" " //library.add_book(Book::new(\"Lord of the Rings\", 1954));\n" @@ -6438,71 +5457,8 @@ msgid "" " //\n" " //println!(\"The library has {} books\", library.len());\n" " //library.print_books();\n" -"}\n" -"```" msgstr "" -"```rust,should_panic\n" -"struct Biblioteca {\n" -" livros: Vec,\n" -"}\n" -"\n" -"struct Livro {\n" -" titulo: String,\n" -" ano: u16,\n" -"}\n" -"\n" -"impl Livro {\n" -" // Este é um construtor, utilizado abaixo.\n" -" fn new(titulo: &str, ano: u16) -> Livro {\n" -" Livro {\n" -" titulo: String::from(titulo),\n" -" ano,\n" -" }\n" -" }\n" -"}\n" -"\n" -"// Implemente os métodos abaixo. Atualize o parâmetro `self` para\n" -"// indicar o nível requerido de ownership sobre o objeto:\n" -"//\n" -"// - `&self` para acesso compartilhado de apenas leitura,\n" -"// - `&mut self` para acesso mutável exclusivo,\n" -"// - `self` para acesso exclusivo por valor.\n" -"impl Biblioteca {\n" -" fn new() -> Biblioteca {\n" -" todo!(\"Inicialize e retorne um valor `Biblioteca`\")\n" -" }\n" -"\n" -" //fn tamanho(self) -> usize {\n" -" // todo!(\"Retorne o tamanho de `self.livros`\")\n" -" //}\n" -"\n" -" //fn esta_vazia(self) -> bool {\n" -" // todo!(\"Retorne `true` se `self.livros` for vazio\")\n" -" //}\n" -"\n" -" //fn adicionar_livro(self, book: Livro) {\n" -" // todo!(\"Adicione um novo livro em `self.livros`\")\n" -" //}\n" -"\n" -" //fn imprimir_livros(self) {\n" -" // todo!(\"Itere sobre `self.livros` e sobre o título e ano de cada " -"livro\")\n" -" //}\n" -"\n" -" //fn livro_mais_antigo(self) -> Option<&Livro> {\n" -" // todo!(\"Retorne uma referência para o livro mais antigo (se " -"houver)\")\n" -" //}\n" -"}\n" -"\n" -"// Isto demonstra o comportamento esperado. Descomente o código abaixo e\n" -"// implemente os métodos que faltam. Você precisará atualizar as\n" -"// assinaturas dos métodos, incluindo o parâmetro \"self\"! Você talvez\n" -"// precise atualizar as atribuições de variável dentro de `main()`.\n" -"fn main() {\n" -" let biblioteca = Biblioteca::new();\n" -"\n" -" //println!(\"A biblioteca está vazia: biblioteca.esta_vazia() -> {}\", " +"//println!(\"A biblioteca está vazia: biblioteca.esta_vazia() -> {}\", " "biblioteca.esta_vazia());\n" " //\n" " //biblioteca.adicionar_livro(Livro::new(\"Lord of the Rings\", 1954));\n" @@ -6523,8 +5479,6 @@ msgstr "" " //\n" " //println!(\"The biblioteca tem {} livros\", biblioteca.tamanho());\n" " //biblioteca.imprimir_livros();\n" -"}\n" -"```" #: src/exercises/day-1/book-library.md:102 msgid "[Solution](solutions-afternoon.md#designing-a-library)" @@ -6556,77 +5510,34 @@ msgstr "" "para um tipo. O _trait_ `Iterator` simplesmente diz que você pode chamar " "`next` até obter `None` como retorno:" -#: src/exercises/day-1/iterators-and-ownership.md:13 -msgid "" -"```rust\n" -"pub trait Iterator {\n" -" type Item;\n" -" fn next(&mut self) -> Option;\n" -"}\n" -"```" -msgstr "" -"```rust\n" -"pub trait Iterator {\n" -" type Item;\n" -" fn next(&mut self) -> Option;\n" -"}\n" -"```" - #: src/exercises/day-1/iterators-and-ownership.md:20 msgid "You use this trait like this:" msgstr "Você usa esse _trait_ da seguinte forma:" -#: src/exercises/day-1/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" -"```" -msgstr "" -"```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!(\"Sem mais itens: {:?}\", iter.next());\n" -"}\n" -"```" +#: src/exercises/day-1/iterators-and-ownership.md:27 +msgid "\"v[0]: {:?}\"" +msgstr "\"v[0]: {:?}\"" + +#: src/exercises/day-1/iterators-and-ownership.md:28 +msgid "\"v[1]: {:?}\"" +msgstr "\"v[1]: {:?}\"" + +#: src/exercises/day-1/iterators-and-ownership.md:29 +msgid "\"v[2]: {:?}\"" +msgstr "\"v[2]: {:?}\"" + +#: src/exercises/day-1/iterators-and-ownership.md:30 +msgid "\"No more items: {:?}\"" +msgstr "\"Sem mais itens: {:?}\"" #: src/exercises/day-1/iterators-and-ownership.md:34 msgid "What is the type returned by the iterator? Test your answer here:" msgstr "Qual é o tipo retornado pelo iterador? Teste sua resposta aqui:" -#: src/exercises/day-1/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" -"```" -msgstr "" -"```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-1/iterators-and-ownership.md:42 +#: src/exercises/day-1/iterators-and-ownership.md:79 +msgid "\"v0: {v0:?}\"" +msgstr "\"v0: {v0:?}\"" #: src/exercises/day-1/iterators-and-ownership.md:46 msgid "Why is this type used?" @@ -6645,26 +5556,6 @@ msgstr "" "O _trait_ `Iterator` informa como _iterar_ depois de criar um iterador. O " "_trait_ relacionado `IntoIterator` lhe informa como criar o iterador:" -#: src/exercises/day-1/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 "" -"```rust\n" -"pub trait IntoIterator {\n" -" type Item;\n" -" type IntoIter: Iterator;\n" -"\n" -" fn into_iter(self) -> Self::IntoIter;\n" -"}\n" -"```" - #: src/exercises/day-1/iterators-and-ownership.md:62 msgid "" "The syntax here means that every implementation of `IntoIterator` must " @@ -6693,29 +5584,20 @@ msgstr "" msgid "Like before, what is the type returned by the iterator?" msgstr "Como antes, qual é o tipo retornado pelo iterador?" -#: src/exercises/day-1/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" -"```" -msgstr "" -"```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-1/iterators-and-ownership.md:75 +#: src/exercises/day-1/iterators-and-ownership.md:91 +#: src/exercises/day-2/luhn.md:35 src/traits/trait-bounds.md:22 +#: src/traits/impl-trait.md:14 src/exercises/day-3/simple-gui.md:150 +#: src/exercises/day-3/simple-gui.md:151 src/exercises/day-3/simple-gui.md:152 +#: src/testing/test-modules.md:21 src/exercises/day-2/solutions-afternoon.md:60 +msgid "\"foo\"" +msgstr "\"foo\"" + +#: src/exercises/day-1/iterators-and-ownership.md:75 +#: src/exercises/day-1/iterators-and-ownership.md:91 +#: src/testing/test-modules.md:21 +msgid "\"bar\"" +msgstr "\"bar\"" #: src/exercises/day-1/iterators-and-ownership.md:83 msgid "`for` Loops" @@ -6731,37 +5613,10 @@ msgstr "" "`for`. Eles chamam `into_iter()` em uma expressão e itera sobre o iterador " "resultante:" -#: src/exercises/day-1/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" -"```" -msgstr "" -"```rust,editable\n" -"fn main() {\n" -" let v: Vec = vec![String::from(\"foo\"), String::" -"from(\"bar\")];\n" -"\n" -" for palavra in &v {\n" -" println!(\"palavra: {palavra}\");\n" -" }\n" -"\n" -" for palavra in v {\n" -" println!(\"palavra: {palavra}\");\n" -" }\n" -"}\n" -"```" +#: src/exercises/day-1/iterators-and-ownership.md:94 +#: src/exercises/day-1/iterators-and-ownership.md:98 +msgid "\"word: {word}\"" +msgstr "\"palavra: {palavra}\"" #: src/exercises/day-1/iterators-and-ownership.md:103 msgid "What is the type of `word` in each loop?" @@ -6822,55 +5677,18 @@ msgstr "" msgid "Like C and C++, Rust has support for custom structs:" msgstr "Como C e C++, Rust tem suporte para `structs` 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" -"```" -msgstr "" -"```rust,editable\n" -"struct Pessoa {\n" -" nome: String,\n" -" idade: u8,\n" -"}\n" -"\n" -"fn main() {\n" -" let mut pedro = Pessoa {\n" -" nome: String::from(\"Pedro\"),\n" -" idade: 27,\n" -" };\n" -" println!(\"{} tem {} anos.\", pedro.nome, pedro.idade);\n" -" \n" -" pedro.idade= 28;\n" -" println!(\"{} tem {} anos.\", pedro.nome, pedro.idade);\n" -" \n" -" let jackie = Pessoa {\n" -" nome: String::from(\"Jackie\"),\n" -" ..pedro\n" -" };\n" -" println!(\"{} tem {} anos.\", jackie.nome, jackie.idade);\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 "\"Pedro\"" + +#: src/structs.md:16 src/structs.md:19 src/structs.md:25 +msgid "\"{} is {} years old\"" +msgstr "\"{} tem {} anos.\"" + +#: src/structs.md:22 +msgid "\"Jackie\"" +msgstr "\"Jackie\"" #: src/structs.md:31 src/enums.md:34 src/enums/sizes.md:28 src/methods.md:30 #: src/methods/example.md:46 src/pattern-matching.md:25 @@ -6941,25 +5759,9 @@ msgstr "" "Se os nomes dos campos não forem importantes, você pode usar uma estrutura " "de tupla:" -#: 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" -"```" -msgstr "" -"```rust,editable\n" -"struct Ponto(i32, i32);\n" -"\n" -"fn main() {\n" -" let p = Ponto(17, 23);\n" -" println!(\"({}, {})\", p.0, p.1);\n" -"}\n" -"```" +#: src/structs/tuple-structs.md:10 +msgid "\"({}, {})\"" +msgstr "\"({}, {})\"" #: src/structs/tuple-structs.md:14 msgid "This is often used for single-field wrappers (called newtypes):" @@ -6967,45 +5769,15 @@ msgstr "" "Isso é comumente utilizado para _wrappers_ (invólucros) com campo único " "(chamados _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" -"```" -msgstr "" -"```rust,editable,compile_fail\n" -"struct LibrasDeForca(f64);\n" -"struct Newtons(f64);\n" -"\n" -"fn calcular_forca_nas_turbinas() -> LibrasDeForca {\n" -" todo!(\"Pergunte para um cientista de foguetes da NASA\")\n" -"}\n" -"\n" -"fn definir_forca_nas_turbinas(force: Newtons) {\n" -" // …\n" -"}\n" -"\n" -"fn main() {\n" -" let forca = calcular_forca_nas_turbinas();\n" -" definir_forca_nas_turbinas(forca);\n" -"}\n" -"\n" -"```" +#: src/structs/tuple-structs.md:21 +msgid "\"Ask a rocket scientist at NASA\"" +msgstr "\"Pergunte para um cientista de foguetes da NASA\"" + +#: src/structs/tuple-structs.md:25 +#: src/bare-metal/microcontrollers/type-state.md:14 +#: src/async/pitfalls/cancellation.md:99 +msgid "// ...\n" +msgstr "// …\n" #: src/structs/tuple-structs.md:37 msgid "" @@ -7064,45 +5836,9 @@ msgstr "" "Se você já tiver variáveis com os nomes corretos, poderá criar a estrutura " "(_struct_) usando uma abreviação:" -#: 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" -"```" -msgstr "" -"```rust,editable\n" -"#[derive(Debug)]\n" -"struct Pessoa {\n" -" nome: String,\n" -" idade: u8,\n" -"}\n" -"\n" -"impl Pessoa {\n" -" fn new(nome: String, idade: u8) -> Pessoa {\n" -" Pessoa { nome, idade }\n" -" }\n" -"}\n" -"\n" -"fn main() {\n" -" let pedro = Pessoa::new(String::from(\"Pedro\"), 27);\n" -" println!(\"{pedro:?}\");\n" -"}\n" -"```" +#: src/structs/field-shorthand.md:21 +msgid "\"{peter:?}\"" +msgstr "\"{pedro:?}\"" #: src/structs/field-shorthand.md:27 msgid "" @@ -7112,34 +5848,6 @@ msgstr "" "A função `new` poderia ser escrita utilizando `Self` como tipo, já que ele é " "intercambiável com o nome da _struct_" -#: 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 "" -"```rust,editable\n" -"#[derive(Debug)]\n" -"struct Pessoa {\n" -" nome: String,\n" -" idade: u8,\n" -"}\n" -"impl Pessoa {\n" -" fn new(nome: String, idade: u8) -> Self {\n" -" Self { nome, idade }\n" -" }\n" -"}\n" -"```" - #: src/structs/field-shorthand.md:41 msgid "" "Implement the `Default` trait for the struct. Define some fields and use the " @@ -7148,57 +5856,13 @@ msgstr "" "Implemente a _trait_ `Default` (Padrão) para a _struct_. Defina alguns " "campos e utilize valores padrão para os demais." -#: 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" -"```" -msgstr "" -"```rust,editable\n" -"#[derive(Debug)]\n" -"struct Pessoa {\n" -" nome: String,\n" -" idade: u8,\n" -"}\n" -"impl Default for Pessoa {\n" -" fn default() -> Pessoa {\n" -" Pessoa {\n" -" nome: \"Robô\".to_string(),\n" -" idade: 0,\n" -" }\n" -" }\n" -"}\n" -"fn create_default() {\n" -" let tmp = Pessoa {\n" -" ..Pessoa::default()\n" -" };\n" -" let tmp = Pessoa {\n" -" nome: \"Sam\".to_string(),\n" -" ..Pessoa::default()\n" -" };\n" -"}\n" -"```" +#: src/structs/field-shorthand.md:52 +msgid "\"Bot\"" +msgstr "\"Robô\"" + +#: src/structs/field-shorthand.md:62 +msgid "\"Sam\"" +msgstr "\"Sam\"" #: src/structs/field-shorthand.md:68 msgid "Methods are defined in the `impl` block." @@ -7227,60 +5891,18 @@ msgstr "" "A palavra-chave `enum` permite a criação de um tipo que possui algumas " "variantes diferentes:" -#: 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 "// Implementação baseada em https://xkcd.com/221/\n" + +#: src/enums.md:9 +msgid "// Chosen by fair dice roll. Guaranteed to be random.\n" msgstr "" -"```rust,editable\n" -"fn gerar_numero_aleatorio() -> i32 {\n" -" // Implementação baseada em https://xkcd.com/221/\n" -" 4 // Escolhido por uma rolagem de dados justa. Garantido ser " -"aleatório.\n" -"}\n" -"\n" -"#[derive(Debug)]\n" -"enum MoedaJogada {\n" -" Cara,\n" -" Coroa,\n" -"}\n" -"\n" -"fn jogar_moeda() -> MoedaJogada {\n" -" let numero_aleatorio = gerar_numero_aleatorio();\n" -" if numero_aleatorio % 2 == 0 {\n" -" return MoedaJogada::Cara;\n" -" } else {\n" -" return MoedaJogada::Coroa;\n" -" }\n" -"}\n" -"\n" -"fn main() {\n" -" println!(\"Você tirou: {:?}\", jogar_moeda());\n" -"}\n" -"```" +"// Escolhido por uma rolagem de dados justa. Garantido ser aleatório.\n" + +#: src/enums.md:28 +msgid "\"You got: {:?}\"" +msgstr "\"Você tirou: {:?}\"" #: src/enums.md:36 msgid "Enumerations allow you to collect a set of values under one type" @@ -7330,62 +5952,33 @@ msgstr "" "pode então usar a instrução `match` (corresponder) para extrair os dados 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" -"```" -msgstr "" -"```rust,editable\n" -"enum EventoWeb {\n" -" CarregarPagina, // Variante sem conteúdo\n" -" TeclaPressionada(char), // Variante tupla\n" -" Clique { x: i64, y: i64 }, // Variante completa\n" -"}\n" -"\n" -"#[rustfmt::skip]\n" -"fn inspecionar(evento: EventoWeb) {\n" -" match evento {\n" -" EventoWeb::CarregarPagina => println!(\"página carregada\"),\n" -" EventoWeb::TeclaPressionada(c) => println!(\"pressionou " -"'{c}'\"),\n" -" EventoWeb::Clique { x, y } => println!(\"clicou em x={x}, y={y}\"),\n" -" }\n" -"}\n" -"\n" -"fn main() {\n" -" let carregar = EventoWeb::CarregarPagina;\n" -" let pressionar = EventoWeb::TeclaPressionada('x');\n" -" let clicar = EventoWeb::Clique { x: 20, y: 80 };\n" -"\n" -" inspecionar(carregar);\n" -" inspecionar(pressionar);\n" -" inspecionar(clicar);\n" -"}\n" -"```" +#: src/enums/variant-payloads.md:8 +msgid "// Variant without payload\n" +msgstr "// Variante sem conteúdo\n" + +#: src/enums/variant-payloads.md:9 +msgid "// Tuple struct variant\n" +msgstr "// Variante tupla\n" + +#: src/enums/variant-payloads.md:10 +msgid "// Full struct variant\n" +msgstr "// Variante completa\n" + +#: src/enums/variant-payloads.md:16 +msgid "\"page loaded\"" +msgstr "\"página carregada\"" + +#: src/enums/variant-payloads.md:17 +msgid "\"pressed '{c}'\"" +msgstr "\"pressionou '{c}'\"" + +#: src/enums/variant-payloads.md:18 +msgid "\"clicked at x={x}, y={y}\"" +msgstr "\"clicou em x={x}, y={y}\"" + +#: src/enums/variant-payloads.md:24 src/pattern-matching.md:10 +msgid "'x'" +msgstr "'x'" #: src/enums/variant-payloads.md:35 msgid "" @@ -7468,45 +6061,9 @@ msgstr "" "Enums, em Rust, são agrupados de maneira compacta, levando em consideração " "restrições devido ao alinhamento:" -#: 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 "" -"```rust,editable\n" -"use std::any::type_name;\n" -"use std::mem::{align_of, size_of};\n" -"\n" -"fn dbg_size() {\n" -" println!(\"{}: tamanho {} bytes, alinhamento: {} 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" -"```" +#: src/enums/sizes.md:10 +msgid "\"{}: size {} bytes, align: {} bytes\"" +msgstr "\"{}: tamanho {} bytes, alinhamento: {} bytes\"" #: src/enums/sizes.md:24 msgid "" @@ -7531,37 +6088,25 @@ msgstr "" "É possível controlar a discriminante se necessário (e.g., para " "compatibilidade com 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 "" -"```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" -"```" +#: src/enums/sizes.md:37 +msgid "// 0\n" +msgstr "// 0\n" + +#: src/enums/sizes.md:39 +msgid "// 10001\n" +msgstr "// 10001\n" + +#: src/enums/sizes.md:43 +msgid "\"A: {}\"" +msgstr "\"A: {}\"" + +#: src/enums/sizes.md:44 +msgid "\"B: {}\"" +msgstr "\"B: {}\"" + +#: src/enums/sizes.md:45 +msgid "\"C: {}\"" +msgstr "\"C: {}\"" #: src/enums/sizes.md:49 msgid "" @@ -7630,79 +6175,33 @@ msgstr "" "garantia a respeito dessa representação, portanto isso é completamente " "inseguro." -#: src/enums/sizes.md:70 +#: src/enums/sizes.md:75 src/enums/sizes.md:114 +msgid "\"- {}: {:#x}\"" +msgstr "\"- {}: {:#x}\"" + +#: src/enums/sizes.md:80 src/enums/sizes.md:131 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" +"// 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 "" -"```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" -" // TOTALMENTE INSEGURO. Rust não oferece nenhuma garantia sobre a\n" +"// TOTALMENTE INSEGURO. Rust não oferece nenhuma garantia sobre a\n" " // representação dos tipos em bits.\n" -" unsafe {\n" -" println!(\"Representação em bits de booleano\");\n" -" dbg_bits!(false, u8);\n" -" dbg_bits!(true, u8);\n" -"\n" -" println!(\"Representação em bits de Option\");\n" -" dbg_bits!(None::, u8);\n" -" dbg_bits!(Some(false), u8);\n" -" dbg_bits!(Some(true), u8);\n" -"\n" -" println!(\"Representação em bits de 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!(\"Representação em bits de Option<&i32>\");\n" -" dbg_bits!(None::<&i32>, usize);\n" -" dbg_bits!(Some(&0i32), usize);\n" -" }\n" -"}\n" -"```" + +#: src/enums/sizes.md:83 +msgid "\"Bitwise representation of bool\"" +msgstr "\"Representação em bits de booleano\"" + +#: src/enums/sizes.md:87 +msgid "\"Bitwise representation of Option\"" +msgstr "\"Representação em bits de Option\"" + +#: src/enums/sizes.md:92 +msgid "\"Bitwise representation of Option>\"" +msgstr "\"Representação em bits de Option>\"" + +#: src/enums/sizes.md:98 +msgid "\"Bitwise representation of Option<&i32>\"" +msgstr "\"Representação em bits de Option<&i32>\"" #: src/enums/sizes.md:105 msgid "" @@ -7712,109 +6211,30 @@ msgstr "" "Exemplo mais complexo caso queira demonstrar o que acontece ao encadear mais " "de 256 `Option`s de uma vez." -#: src/enums/sizes.md:107 +#: src/enums/sizes.md:108 +msgid "\"1000\"" +msgstr "\"1000\"" + +#: src/enums/sizes.md:117 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 "" -"```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 que envolve um valor em 2^n Some() no qual n é o número de \"@\".\n" "// É preciso aumentar o limite de recursão para aplicar essa macro.\n" -"macro_rules! muitos_options {\n" -" ($value:expr) => { Some($value) };\n" -" ($value:expr, @) => {\n" -" Some(Some($value))\n" -" };\n" -" ($value:expr, @ $($more:tt)+) => {\n" -" muitos_options!(muitos_options!($value, $($more)+), $($more)+)\n" -" };\n" -"}\n" -"\n" -"fn main() {\n" -" // TOTALMENTE INSEGURO. Rust não oferece nenhuma garantia sobre a\n" -" // representação dos tipos em bits.\n" -" unsafe {\n" -" assert_eq!(muitos_options!(false), Some(false));\n" -" assert_eq!(muitos_options!(false, @), Some(Some(false)));\n" -" assert_eq!(muitos_options!(false, @@), " -"Some(Some(Some(Some(false)))));\n" -"\n" -" println!(\"Representação em bits de uma sequência de 128 Option's." -"\");\n" -" dbg_bits!(muitos_options!(false, @@@@@@@), u8);\n" -" dbg_bits!(muitos_options!(true, @@@@@@@), u8);\n" -"\n" -" println!(\"Representação em bits de uma sequência de 256 Option's." -"\");\n" -" dbg_bits!(muitos_options!(false, @@@@@@@@), u16);\n" -" dbg_bits!(muitos_options!(true, @@@@@@@@), u16);\n" -"\n" -" println!(\"Representação em bits de uma sequência de 257 Option's." -"\");\n" -" dbg_bits!(muitos_options!(Some(false), @@@@@@@@), u16);\n" -" dbg_bits!(muitos_options!(Some(true), @@@@@@@@), u16);\n" -" dbg_bits!(muitos_options!(None::, @@@@@@@@), u16);\n" -" }\n" -"}\n" -"```" + +#: src/enums/sizes.md:138 +msgid "\"Bitwise representation of a chain of 128 Option's.\"" +msgstr "\"Representação em bits de uma sequência de 128 Option's.\"" + +#: src/enums/sizes.md:142 +msgid "\"Bitwise representation of a chain of 256 Option's.\"" +msgstr "\"Representação em bits de uma sequência de 256 Option's.\"" + +#: src/enums/sizes.md:146 +msgid "\"Bitwise representation of a chain of 257 Option's.\"" +msgstr "\"Representação em bits de uma sequência de 257 Option's.\"" #: src/methods.md:3 msgid "" @@ -7824,51 +6244,9 @@ msgstr "" "Rust permite que você associe funções aos seus novos tipos. Você faz isso " "com um bloco `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" -"```" -msgstr "" -"```rust,editable\n" -"#[derive(Debug)]\n" -"struct Pessoa {\n" -" nome: String,\n" -" idade: u8,\n" -"}\n" -"\n" -"impl Pessoa {\n" -" fn dizer_ola(&self) {\n" -" println!(\"Olá, meu nome é {}\", self.nome);\n" -" }\n" -"}\n" -"\n" -"fn main() {\n" -" let pedro = Pessoa {\n" -" nome: String::from(\"Pedro\"),\n" -" idade: 27,\n" -" };\n" -" pedro.dizer_ola();\n" -"}\n" -"```" +#: src/methods.md:15 +msgid "\"Hello, my name is {}\"" +msgstr "\"Olá, meu nome é {}\"" #: src/methods.md:31 msgid "It can be helpful to introduce methods by comparing them to functions." @@ -8006,95 +6384,41 @@ msgstr "" "possível referenciar uma _struct_ de vários locais e chamar um método " "mutável (`&mut self`) nela." -#: 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" -"```" -msgstr "" -"```rust,editable\n" -"#[derive(Debug)]\n" -"struct Corrida {\n" -" nome: String,\n" -" voltas: Vec,\n" -"}\n" -"\n" -"impl Corrida {\n" -" fn new(nome: &str) -> Corrida { // Sem receptor, método estático\n" -" Corrida { nome: String::from(nome), voltas: Vec::new() }\n" -" }\n" -"\n" -" fn adicionar_volta(&mut self, volta: i32) { // Empréstimo único com " -"acesso de leitura e escrita em self\n" -" self.voltas.push(volta);\n" -" }\n" -"\n" -" fn imprimir_voltas(&self) { // Empréstimo compartilhado com acesso " -"apenas de leitura em self\n" -" println!(\"Registrou {} voltas para {}:\", self.voltas.len(), self." -"nome);\n" -" for (idx, volta) in self.voltas.iter().enumerate() {\n" -" println!(\"Volta {idx}: {volta} seg\");\n" -" }\n" -" }\n" -"\n" -" fn encerrar(self) { // Propriedade exclusiva de self\n" -" let total = self.voltas.iter().sum::();\n" -" println!(\"Corrida {} foi encerrada, tempo de voltas total: {}\", " -"self.nome, total);\n" -" }\n" -"}\n" -"\n" -"fn main() {\n" -" let mut corrida = Corrida::new(\"Monaco Grand Prix\");\n" -" corrida.adicionar_volta(70);\n" -" corrida.adicionar_volta(68);\n" -" corrida.imprimir_voltas();\n" -" corrida.adicionar_volta(71);\n" -" corrida.imprimir_voltas();\n" -" corrida.encerrar();\n" -" // corrida.adicionar_volta(42);\n" -"}\n" -"```" +#: src/methods/example.md:11 +msgid "// No receiver, a static method\n" +msgstr "// Sem receptor, método estático\n" + +#: src/methods/example.md:15 +msgid "// Exclusive borrowed read-write access to self\n" +msgstr "// Empréstimo único com acesso de leitura e escrita em self\n" + +#: src/methods/example.md:19 +msgid "// Shared and read-only borrowed access to self\n" +msgstr "// Empréstimo compartilhado com acesso apenas de leitura em self\n" + +#: src/methods/example.md:20 +msgid "\"Recorded {} laps for {}:\"" +msgstr "\"Registrou {} voltas para {}:\"" + +#: src/methods/example.md:22 +msgid "\"Lap {idx}: {lap} sec\"" +msgstr "\"Volta {idx}: {volta} seg\"" + +#: src/methods/example.md:26 +msgid "// Exclusive ownership of self\n" +msgstr "// Propriedade exclusiva de self\n" + +#: src/methods/example.md:28 +msgid "\"Race {} is finished, total lap time: {}\"" +msgstr "\"Corrida {} foi encerrada, tempo de voltas total: {}\"" + +#: src/methods/example.md:33 +msgid "\"Monaco Grand Prix\"" +msgstr "\"Monaco Grand Prix\"" + +#: src/methods/example.md:40 +msgid "// race.add_lap(42);\n" +msgstr "// corrida.adicionar_volta(42);\n" #: src/methods/example.md:47 msgid "All four methods here use a different method receiver." @@ -8149,33 +6473,49 @@ msgid "The patterns can be simple values, similarly to `switch` in C and C++:" msgstr "" "Os padrões podem ser valores simples, similarmente a `switch` em C e 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" -"```" -msgstr "" -"```rust,editable\n" -"fn main() {\n" -" let entrada = 'x';\n" -"\n" -" match entrada {\n" -" 'q' => println!(\"Encerrando\"),\n" -" 'a' | 's' | 'w' | 'd' => println!(\"Movendo por ai\"),\n" -" '0'..='9' => println!(\"Entrada de número\"),\n" -" _ => println!(\"Alguma outra coisa\"),\n" -" }\n" -"}\n" -"```" +#: src/pattern-matching.md:13 +msgid "'q'" +msgstr "'q'" + +#: src/pattern-matching.md:13 +msgid "\"Quitting\"" +msgstr "\"Encerrando\"" + +#: src/pattern-matching.md:14 +msgid "'a'" +msgstr "'a'" + +#: src/pattern-matching.md:14 +msgid "'s'" +msgstr "'s'" + +#: src/pattern-matching.md:14 +msgid "'w'" +msgstr "'w'" + +#: src/pattern-matching.md:14 +msgid "'d'" +msgstr "'d'" + +#: src/pattern-matching.md:14 +msgid "\"Moving around\"" +msgstr "\"Movendo por ai\"" + +#: src/pattern-matching.md:15 +msgid "'0'" +msgstr "'0'" + +#: src/pattern-matching.md:15 +msgid "'9'" +msgstr "'9'" + +#: src/pattern-matching.md:15 +msgid "\"Number input\"" +msgstr "\"Entrada de número\"" + +#: src/pattern-matching.md:16 +msgid "\"Something else\"" +msgstr "\"Alguma outra coisa\"" #: src/pattern-matching.md:21 msgid "The `_` pattern is a wildcard pattern which matches any value." @@ -8235,56 +6575,17 @@ msgstr "" "valores. É assim que você inspeciona a estrutura de seus tipos. Vamos " "começar com um tipo `enum` simples:" -#: 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" -"```" -msgstr "" -"```rust,editable\n" -"enum Resultado {\n" -" Ok(i32),\n" -" Erro(String),\n" -"}\n" -"\n" -"fn divide_em_dois(n: i32) -> Resultado {\n" -" if n % 2 == 0 {\n" -" Resultado::Ok(n / 2)\n" -" } else {\n" -" Resultado::Erro(format!(\"não é possível dividir {n} em duas partes " -"iguais\"))\n" -" }\n" -"}\n" -"\n" -"fn main() {\n" -" let n = 100;\n" -" match divide_em_dois(n) {\n" -" Resultado::Ok(metade) => println!(\"{n} divido em dois é " -"{metade}\"),\n" -" Resultado::Erro(msg) => println!(\"desculpe, aconteceu um erro: " -"{msg}\"),\n" -" }\n" -"}\n" -"```" +#: src/pattern-matching/destructuring-enums.md:16 +msgid "\"cannot divide {n} into two equal parts\"" +msgstr "\"não é possível dividir {n} em duas partes iguais\"" + +#: src/pattern-matching/destructuring-enums.md:23 +msgid "\"{n} divided in two is {half}\"" +msgstr "\"{n} divido em dois é {metade}\"" + +#: src/pattern-matching/destructuring-enums.md:24 +msgid "\"sorry, an error happened: {msg}\"" +msgstr "\"desculpe, aconteceu um erro: {msg}\"" #: src/pattern-matching/destructuring-enums.md:29 msgid "" @@ -8319,43 +6620,17 @@ msgstr "" msgid "You can also destructure `structs`:" msgstr "Você também pode desestruturar `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" -"```" -msgstr "" -"```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}, outros campos foram " -"ignorados\"),\n" -" }\n" -"}\n" -"```" +#: src/pattern-matching/destructuring-structs.md:15 +msgid "\"x.0 = 1, b = {b}, y = {y}\"" +msgstr "\"x.0 = 1, b = {b}, y = {y}\"" + +#: src/pattern-matching/destructuring-structs.md:16 +msgid "\"y = 2, x = {i:?}\"" +msgstr "\"y = 2, x = {i:?}\"" + +#: src/pattern-matching/destructuring-structs.md:17 +msgid "\"y = {y}, other fields were ignored\"" +msgstr "\"y = {y}, outros campos foram ignorados\"" #: src/pattern-matching/destructuring-structs.md:23 msgid "Change the literal values in `foo` to match with the other patterns." @@ -8384,33 +6659,24 @@ msgid "" msgstr "" "Você pode desestruturar vetores, tuplas e _slices_ combinando seus 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" -"```" -msgstr "" -"```rust, editable\n" -"#[rustfmt::skip]\n" -"fn main() {\n" -" let triplo = [0, -2, 3];\n" -" println!(\"Fale-me sobre {triplo:?}\");\n" -" match triplo {\n" -" [0, y, z] => println!(\"Primeiro é 0, y = {y} e z = {z}\"),\n" -" [1, ..] => println!(\"Primeiro é 1 e o resto foi ignorado\"),\n" -" _ => println!(\"Todos os elementos foram ignorados\"),\n" -" }\n" -"}\n" -"```" +#: src/pattern-matching/destructuring-arrays.md:9 +msgid "\"Tell me about {triple:?}\"" +msgstr "\"Fale-me sobre {triplo:?}\"" + +#: src/pattern-matching/destructuring-arrays.md:11 +#: src/pattern-matching/destructuring-arrays.md:34 +msgid "\"First is 0, y = {y}, and z = {z}\"" +msgstr "\"Primeiro é 0, y = {y} e z = {z}\"" + +#: src/pattern-matching/destructuring-arrays.md:12 +#: src/pattern-matching/destructuring-arrays.md:35 +msgid "\"First is 1 and the rest were ignored\"" +msgstr "\"Primeiro é 1 e o resto foi ignorado\"" + +#: src/pattern-matching/destructuring-arrays.md:13 +#: src/pattern-matching/destructuring-arrays.md:36 +msgid "\"All elements were ignored\"" +msgstr "\"Todos os elementos foram ignorados\"" #: src/pattern-matching/destructuring-arrays.md:21 msgid "" @@ -8420,41 +6686,9 @@ msgstr "" "Desestruturar _slices_ de tamanho desconhecido é possível utilizando padrões " "de tamanho fixo." -#: 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" -"```" -msgstr "" -"```rust,editable\n" -"fn main() {\n" -" inspecionar(&[0, -2, 3]);\n" -" inspecionar(&[0, -2, 3, 4]);\n" -"}\n" -"\n" -"#[rustfmt::skip]\n" -"fn inspecionar(slice: &[i32]) {\n" -" println!(\"Fale-me sobre {slice:?}\");\n" -" match slice {\n" -" &[0, y, z] => println!(\"Primeiro é 0, y = {y}, and z = {z}\"),\n" -" &[1, ..] => println!(\"Primeiro é 1 e o resto foi ignorado\"),\n" -" _ => println!(\"Todos os elementos foram ignorados\"),\n" -" }\n" -"}\n" -"```" +#: src/pattern-matching/destructuring-arrays.md:32 +msgid "\"Tell me about {slice:?}\"" +msgstr "\"Fale-me sobre {slice:?}\"" #: src/pattern-matching/destructuring-arrays.md:41 msgid "Create a new pattern using `_` to represent an element. " @@ -8486,35 +6720,25 @@ msgstr "" "para um padrão. É uma expressão Booleana arbitrária que será executada se o " "padrão corresponder:" -#: 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" -"```" -msgstr "" -"```rust, editable\n" -"#[rustfmt::skip]\n" -"fn main() {\n" -" let par = (2, -2);\n" -" println!(\"Fale-me sobre {par:?}\");\n" -" match par {\n" -" (x, y) if x == y => println!(\"Estes são gêmeos\"),\n" -" (x, y) if x + y == 0 => println!(\"Antimatter, kaboom!\"),\n" -" (x, _) if x % 2 == 1 => println!(\"O primeiro é ímpar\"),\n" -" _ => println!(\"Sem correlação...\"),\n" -" }\n" -"}\n" -"```" +#: src/pattern-matching/match-guards.md:10 +msgid "\"Tell me about {pair:?}\"" +msgstr "\"Fale-me sobre {par:?}\"" + +#: src/pattern-matching/match-guards.md:12 +msgid "\"These are twins\"" +msgstr "\"Estes são gêmeos\"" + +#: src/pattern-matching/match-guards.md:13 +msgid "\"Antimatter, kaboom!\"" +msgstr "\"Antimatter, kaboom!\"" + +#: src/pattern-matching/match-guards.md:14 +msgid "\"The first one is odd\"" +msgstr "\"O primeiro é ímpar\"" + +#: src/pattern-matching/match-guards.md:15 +msgid "\"No correlation...\"" +msgstr "\"Sem correlação...\"" #: src/pattern-matching/match-guards.md:23 msgid "" @@ -8594,181 +6818,20 @@ msgstr "" "Copie o código abaixo em e implemente os " "métodos que estão faltando:" -#: src/exercises/day-2/health-statistics.md:13 -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" -"```" -msgstr "" -"```rust,should_panic\n" -"// TODO: remova a linha abaixo quando terminar sua implementação.\n" -"#![allow(unused_variables, dead_code)]\n" -"\n" -"pub struct Usuario {\n" -" nome: String,\n" -" idade: u32,\n" -" peso: f32,\n" -" num_visitas: usize,\n" -" ult_pressao_sang: Option<(u32, u32)>,\n" -"}\n" -"\n" -"pub struct Medicoes {\n" -" altura: f32,\n" -" pressao_sangue: (u32, u32),\n" -"}\n" -"\n" -"pub struct RelatorioSaude<'a> {\n" -" nome_paciente: &'a str,\n" -" num_visitas: u32,\n" -" dif_altura: f32,\n" -" dif_pressao_sangue: Option<(i32, i32)>,\n" -"}\n" -"\n" -"impl Usuario {\n" -" pub fn new(nome: String, idade: u32, peso: f32) -> Self {\n" -" unimplemented!()\n" -" }\n" -"\n" -" pub fn nome(&self) -> &str {\n" -" unimplemented!()\n" -" }\n" -"\n" -" pub fn idade(&self) -> u32 {\n" -" unimplemented!()\n" -" }\n" -"\n" -" pub fn altura(&self) -> f32 {\n" -" unimplemented!()\n" -" }\n" -"\n" -" pub fn visitas_medico(&self) -> u32 {\n" -" unimplemented!()\n" -" }\n" -"\n" -" pub fn definir_idade(&mut self, nova_idade: u32) {\n" -" unimplemented!()\n" -" }\n" -"\n" -" pub fn definir_altura(&mut self, novo_altura: f32) {\n" -" unimplemented!()\n" -" }\n" -"}\n" -"\n" -"fn main() {\n" -" let beto = Usuario::new(String::from(\"Beto\"), 32, 155.2);\n" -" println!(\"Eu sou {} e minha idade é {}\", beto.nome(), beto.idade());\n" -"}\n" -"\n" -"#[test]\n" -"fn test_altura() {\n" -" let beto = Usuario::new(String::from(\"Beto\"), 32, 155.2);\n" -" assert_eq!(beto.altura(), 155.2);\n" -"}\n" -"\n" -"#[test]\n" -"fn test_definir_idade() {\n" -" let mut beto = Usuario::new(String::from(\"Beto\"), 32, 155.2);\n" -" assert_eq!(beto.idade(), 32);\n" -" beto.definir_idade(33);\n" -" assert_eq!(beto.idade(), 33);\n" -"}\n" -"```" +#: 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 +#, fuzzy +msgid "\"Bob\"" +msgstr "\"Beto\"" + +#: src/exercises/day-2/health-statistics.md:73 +#, fuzzy +msgid "\"I'm {} and my age is {}\"" +msgstr "\"Eu sou {} e minha idade é {}\"" #: src/exercises/day-2/points-polygons.md:1 msgid "Polygon Struct" @@ -8784,223 +6847,17 @@ msgstr "" "código abaixo em e preencha os métodos que " "faltam para fazer os testes passarem:" -#: src/exercises/day-2/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" -"```" -msgstr "" -"```rust\n" -"// TODO: remova a linha abaixo quando terminar sua implementação.\n" -"#![allow(unused_variables, dead_code)]\n" -"\n" -"pub struct Ponto {\n" -" // adicione atributos\n" -"}\n" -"\n" -"impl Ponto {\n" -" // adicione métodos\n" -"}\n" -"\n" -"pub struct Poligono {\n" -" // adicione atributos\n" -"}\n" -"\n" -"impl Poligono {\n" -" // adicione métodos\n" -"}\n" -"\n" -"pub struct Circulo {\n" -" // adicione atributos\n" -"}\n" -"\n" -"impl Circulo {\n" -" // adicione métodos\n" -"}\n" -"\n" -"pub enum Forma {\n" -" Poligono(Poligono),\n" -" Circulo(Circulo),\n" -"}\n" -"\n" -"#[cfg(test)]\n" -"mod tests {\n" -" use super::*;\n" -"\n" -" fn arredonda_dois_digitos(x: f64) -> f64 {\n" -" (x * 100.0).round() / 100.0\n" -" }\n" -"\n" -" #[test]\n" -" fn testa_magnitude_ponto() {\n" -" let p1 = Ponto::new(12, 13);\n" -" assert_eq!(arredonda_dois_digitos(p1.magnitude()), 17.69);\n" -" }\n" -"\n" -" #[test]\n" -" fn testa_distancia_ponto() {\n" -" let p1 = Ponto::new(10, 10);\n" -" let p2 = Ponto::new(14, 13);\n" -" assert_eq!(arredonda_dois_digitos(p1.distancia(p2)), 5.00);\n" -" }\n" -"\n" -" #[test]\n" -" fn testa_somar_ponto() {\n" -" let p1 = Ponto::new(16, 16);\n" -" let p2 = p1 + Ponto::new(-4, 3);\n" -" assert_eq!(p2, Ponto::new(12, 19));\n" -" }\n" -"\n" -" #[test]\n" -" fn testa_ponto_mais_a_esquerda_poligono() {\n" -" let p1 = Ponto::new(12, 13);\n" -" let p2 = Ponto::new(16, 16);\n" -"\n" -" let mut poli = Poligono::new();\n" -" poli.adiciona_ponto(p1);\n" -" poli.adiciona_ponto(p2);\n" -" assert_eq!(poli.ponto_mais_a_esquerda(), Some(p1));\n" -" }\n" -"\n" -" #[test]\n" -" fn testa_iterador_poligono() {\n" -" let p1 = Ponto::new(12, 13);\n" -" let p2 = Ponto::new(16, 16);\n" -"\n" -" let mut poli = Poligono::new();\n" -" poli.adiciona_ponto(p1);\n" -" poli.adiciona_ponto(p2);\n" -"\n" -" let pontos = poli.iter().cloned().collect::>();\n" -" assert_eq!(pontos, vec![Point::new(12, 13), Point::new(16, 16)]);\n" -" }\n" -"\n" -" #[test]\n" -" fn testa_perimetros_forma() {\n" -" let mut poli = Poligono::new();\n" -" poli.adiciona_ponto(Ponto::new(12, 13));\n" -" poli.adiciona_ponto(Ponto::new(17, 11));\n" -" poli.adiciona_ponto(Ponto::new(16, 16));\n" -" let formas = vec![\n" -" Forma::from(poli),\n" -" Forma::from(Circulo::new(Ponto::new(10, 20), 5)),\n" -" ];\n" -" let perimetros = formas\n" -" .iter()\n" -" .map(Forma::perimetro)\n" -" .map(arredonda_dois_digitos)\n" -" .collect::>();\n" -" assert_eq!(perimetros, vec![15.48, 31.42]);\n" -" }\n" -"}\n" -"\n" -"#[allow(dead_code)]\n" -"fn main() {}\n" -"```" +#: src/exercises/day-2/points-polygons.md:12 +#: src/exercises/day-2/points-polygons.md:20 +#: src/exercises/day-2/points-polygons.md:28 +msgid "// add fields\n" +msgstr "// adicione atributos\n" + +#: src/exercises/day-2/points-polygons.md:16 +#: src/exercises/day-2/points-polygons.md:24 +#: src/exercises/day-2/points-polygons.md:32 +msgid "// add methods\n" +msgstr "// adicione métodos\n" #: src/exercises/day-2/points-polygons.md:117 msgid "" @@ -9052,45 +6909,13 @@ msgstr "" "Um bloco em Rust contêm uma sequência de expressões. Cada bloco tem um valor " "e um tipo, os quais são os da última expressão do bloco:" -#: 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 "" -"```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" -"```" +#: src/control-flow/blocks.md:16 +msgid "\"w: {w}\"" +msgstr "\"w: {w}\"" + +#: src/control-flow/blocks.md:19 +msgid "\"z: {z}\"" +msgstr "\"z: {z}\"" #: src/control-flow/blocks.md:26 msgid "" @@ -9108,27 +6933,9 @@ msgstr "" "A mesma regra é usada para funções: o valor do corpo da função é o valor de " "retorno:" -#: 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 "" -"```rust,editable\n" -"fn dobrar(x: i32) -> i32 {\n" -" x + x\n" -"}\n" -"\n" -"fn main() {\n" -" println!(\"dobrado: {}\", dobrar(7));\n" -"}\n" -"```" +#: src/control-flow/blocks.md:37 +msgid "\"doubled: {}\"" +msgstr "\"dobrado: {}\"" #: src/control-flow/blocks.md:44 msgid "" @@ -9160,30 +6967,6 @@ msgstr "" "if-expr.html#if-expressions) exatamente como declarações `if` em outras " "linguagens:" -#: 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 "" -"```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" -"```" - #: src/control-flow/if-expressions.md:18 msgid "" "In addition, you can use `if` as an expression. The last expression of each " @@ -9192,30 +6975,6 @@ msgstr "" "Além disso, você pode usá-lo como uma expressão. A última expressão de cada " "bloco se torna o valor da expressão `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 "" -"```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" -"```" - #: src/control-flow/if-expressions.md:35 msgid "" "Because `if` is an expression and must have a particular type, both of its " @@ -9240,33 +6999,17 @@ msgstr "" "expr.html#if-let-expressions) lhe permite que você execute um código " "diferente, dependendo se um valor corresponde a um padrão:" -#: 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" -"```" -msgstr "" -"```rust, editable\n" -"fn main() {\n" -" let arg = std::env::args().next();\n" -" if let Some(valor) = arg {\n" -" println!(\"Nome do programa: {valor}\");\n" -" } else {\n" -" println!(\"Falta o nome?\");\n" -" }\n" -"}\n" -"```" - -#: src/control-flow/if-let-expressions.md:18 -#: src/control-flow/while-let-expressions.md:21 -#: src/control-flow/match-expressions.md:23 +#: src/control-flow/if-let-expressions.md:11 +msgid "\"Program name: {value}\"" +msgstr "\"Nome do programa: {valor}\"" + +#: src/control-flow/if-let-expressions.md:13 +msgid "\"Missing name?\"" +msgstr "\"Falta o nome?\"" + +#: src/control-flow/if-let-expressions.md:18 +#: src/control-flow/while-let-expressions.md:21 +#: src/control-flow/match-expressions.md:23 msgid "" "See [pattern matching](../pattern-matching.md) for more details on patterns " "in Rust." @@ -9305,36 +7048,9 @@ msgstr "" "desestruturação, ou se falhar, ter um bloco de ramificação sem retorno " "(`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 "" -"```rust,editable\n" -"fn main() {\n" -" println!(\"{:?}\", segunda_palavra_para_maiusculas(\"foo bar\"));\n" -"}\n" -" \n" -"fn segunda_palavra_para_maiusculas(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" -"```" +#: src/control-flow/if-let-expressions.md:30 src/testing/test-modules.md:21 +msgid "\"foo bar\"" +msgstr "\"foo bar\"" #: src/control-flow/while-expressions.md:1 msgid "`while` loops" @@ -9349,35 +7065,10 @@ msgstr "" "loop-expr.html#predicate-loops) funciona de maneira muito similar a outras " "linguagens:" -#: 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 "" -"```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!(\"X final: {x}\");\n" -"}\n" -"```" +#: src/control-flow/while-expressions.md:16 +#: src/control-flow/loop-expressions.md:21 +msgid "\"Final x: {x}\"" +msgstr "\"X final: {x}\"" #: src/control-flow/while-let-expressions.md:1 msgid "`while let` loops" @@ -9393,30 +7084,6 @@ msgstr "" "reference/expressions/loop-expr.html#predicate-pattern-loops) que testa " "repetidamente se um valor corresponde a um padrão:" -#: 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 "" -"```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" -"```" - #: src/control-flow/while-let-expressions.md:17 msgid "" "Here the iterator returned by `v.into_iter()` will return a `Option` on " @@ -9462,35 +7129,9 @@ msgstr "" "expressions.md). Ele chamará automaticamente `into_iter()` na expressão e, " "em seguida, iterará sobre ela:" -#: 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 "" -"```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" -"```" +#: src/control-flow/for-expressions.md:16 +msgid "\"i: {i}\"" +msgstr "\"i: {i}\"" #: src/control-flow/for-expressions.md:21 msgid "You can use `break` and `continue` here as usual." @@ -9539,42 +7180,6 @@ msgstr "" msgid "Here you must either `break` or `return` to stop the loop:" msgstr "Aqui você deve usar `break` ou `return` para parar o loop:" -#: 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 "" -"```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!(\"X final: {x}\");\n" -"}\n" -"```" - #: src/control-flow/loop-expressions.md:27 msgid "Break the `loop` with a value (e.g. `break 8`) and print it out." msgstr "Interrompa o `loop` com um valor (por exemplo, `break 8`) e imprima-o." @@ -9603,33 +7208,45 @@ msgstr "" "match-expr.html) é usada para corresponder um valor a um ou mais padrões. " "Nesse sentido, funciona como uma série de expressões `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" -"```" -msgstr "" -"```rust, editable\n" -"fn main() {\n" -" match std::env::args().next().as_deref() {\n" -" Some(\"gato\") => println!(\"Vai fazer coisas de gato\"),\n" -" Some(\"ls\") => println!(\"Vou ls alguns arquivos\"),\n" -" Some(\"mv\") => println!(\"Vamos mover alguns arquivos\"),\n" -" Some(\"rm\") => println!(\"Uh, perigoso!\"),\n" -" None => println!(\"Hmm, nenhum nome de programa?\"),\n" -" _ => println!(\"Nome de programa desconhecido!\"),\n" -" }\n" -"}\n" -"```" +#: src/control-flow/match-expressions.md:10 +msgid "\"cat\"" +msgstr "\"gato\"" + +#: src/control-flow/match-expressions.md:10 +msgid "\"Will do cat things\"" +msgstr "\"Vai fazer coisas de gato\"" + +#: src/control-flow/match-expressions.md:11 +msgid "\"ls\"" +msgstr "\"ls\"" + +#: src/control-flow/match-expressions.md:11 +msgid "\"Will ls some files\"" +msgstr "\"Vou ls alguns arquivos\"" + +#: src/control-flow/match-expressions.md:12 +msgid "\"mv\"" +msgstr "\"mv\"" + +#: src/control-flow/match-expressions.md:12 +msgid "\"Let's move some files\"" +msgstr "\"Vamos mover alguns arquivos\"" + +#: src/control-flow/match-expressions.md:13 +msgid "\"rm\"" +msgstr "\"rm\"" + +#: src/control-flow/match-expressions.md:13 +msgid "\"Uh, dangerous!\"" +msgstr "\"Uh, perigoso!\"" + +#: src/control-flow/match-expressions.md:14 +msgid "\"Hmm, no program name?\"" +msgstr "\"Hmm, nenhum nome de programa?\"" + +#: src/control-flow/match-expressions.md:15 +msgid "\"Unknown program name!\"" +msgstr "\"Nome de programa desconhecido!\"" #: src/control-flow/match-expressions.md:20 msgid "" @@ -9702,43 +7319,9 @@ msgstr "" "Ambos `continue` e `break` podem opcionalmente receber um _label_ (rótulo) " "como argumento que é usado para sair de loops aninhados:" -#: 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 "" -"```rust, editable\n" -"fn main() {\n" -" let v = vec![10, 20, 30];\n" -" let mut iter = v.into_iter();\n" -" 'laco_externo: 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 'laco_externo;\n" -" }\n" -" }\n" -" }\n" -"}\n" -"```" +#: src/control-flow/break-continue.md:18 +msgid "\"x: {x}, i: {i}\"" +msgstr "\"x: {x}, i: {i}\"" #: src/control-flow/break-continue.md:28 msgid "" @@ -9836,29 +7419,13 @@ msgstr "`Option` e `Result`" msgid "The types represent optional data:" msgstr "Os tipos representam dados opcionais:" -#: 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" -"```" -msgstr "" -"```rust,editable\n" -"fn main() {\n" -" let numeros = vec![10, 20, 30];\n" -" let primeiro: Option<&i8> = numeros.first();\n" -" println!(\"primeiro: {primeiro:?}\");\n" -"\n" -" let ind: Result = numeros.binary_search(&10);\n" -" println!(\"ind: {ind:?}\");\n" -"}\n" -"```" +#: src/std/option-result.md:9 +msgid "\"first: {first:?}\"" +msgstr "\"primeiro: {primeiro:?}\"" + +#: src/std/option-result.md:12 +msgid "\"idx: {idx:?}\"" +msgstr "\"ind: {ind:?}\"" #: src/std/option-result.md:18 msgid "`Option` and `Result` are widely used not just in the standard library." @@ -9903,41 +7470,25 @@ msgstr "" "[`String`](https://doc.rust-lang.org/std/string/struct.String.html) é o " "buffer padrão de cadeia de caracteres UTF-8 expansível e alocado no 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" -"```" -msgstr "" -"```rust,editable\n" -"fn main() {\n" -" let mut s1 = String::new();\n" -" s1.push_str(\"Olá\");\n" -" println!(\"s1: tam = {}, capacidade = {}\", 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: tam = {}, capacidade = {}\", s2.len(), s2.capacity());\n" -"\n" -" let s3 = String::from(\"🇧🇷\");\n" -" println!(\"s3: tam = {}, número de caracteres = {}\", s3.len(),\n" -" s3.chars().count());\n" -"}\n" -"```" +#: src/std/string.md:9 +msgid "\"s1: len = {}, capacity = {}\"" +msgstr "\"s1: tam = {}, capacidade = {}\"" + +#: src/std/string.md:13 +msgid "'!'" +msgstr "'!'" + +#: src/std/string.md:14 +msgid "\"s2: len = {}, capacity = {}\"" +msgstr "\"s2: tam = {}, capacidade = {}\"" + +#: src/std/string.md:16 +msgid "\"🇨🇭\"" +msgstr "\"🇧🇷\"" + +#: src/std/string.md:17 +msgid "\"s3: len = {}, number of chars = {}\"" +msgstr "\"s3: tam = {}, número de caracteres = {}\"" #: src/std/string.md:22 msgid "" @@ -10047,57 +7598,29 @@ msgstr "" "[`Vec`](https://doc.rust-lang.org/std/vec/struct.Vec.html) é o buffer padrão " "redimensionável alocado no 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" -"```" -msgstr "" -"```rust,editable\n" -"fn main() {\n" -" let mut v1 = Vec::new();\n" -" v1.push(42);\n" -" println!(\"v1: tamanho = {}, capacidade = {}\", 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: tamanho = {}, capacidade = {}\", v2.len(), v2." -"capacity());\n" -"\n" -" // Macro canônica para inicializar um vetor com elementos.\n" -" let mut v3 = vec![0, 0, 1, 2, 3, 4];\n" -"\n" -" // Mantém apenas os elementos pares.\n" -" v3.retain(|x| x % 2 == 0);\n" -" println!(\"{v3:?}\");\n" -"\n" -" // Remove duplicatas consecutivas.\n" -" v3.dedup();\n" -" println!(\"{v3:?}\");\n" -"}\n" -"```" +#: src/std/vec.md:9 +msgid "\"v1: len = {}, capacity = {}\"" +msgstr "\"v1: tamanho = {}, capacidade = {}\"" + +#: src/std/vec.md:14 +msgid "\"v2: len = {}, capacity = {}\"" +msgstr "\"v2: tamanho = {}, capacidade = {}\"" + +#: src/std/vec.md:16 +msgid "// Canonical macro to initialize a vector with elements.\n" +msgstr "// Macro canônica para inicializar um vetor com elementos.\n" + +#: src/std/vec.md:19 +msgid "// Retain only the even elements.\n" +msgstr "// Mantém apenas os elementos pares.\n" + +#: src/std/vec.md:21 src/std/vec.md:25 +msgid "\"{v3:?}\"" +msgstr "\"{v3:?}\"" + +#: src/std/vec.md:23 +msgid "// Remove consecutive duplicates.\n" +msgstr "// Remove duplicatas consecutivas.\n" #: src/std/vec.md:29 msgid "" @@ -10166,78 +7689,46 @@ msgid "Standard hash map with protection against HashDoS attacks:" msgstr "" "_Hash map_ (Mapa de _hash_) padrão com proteção contra 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 "\"Adventures of Huckleberry Finn\"" + +#: src/std/hashmap.md:11 +msgid "\"Grimms' Fairy Tales\"" +msgstr "\"Grimms' Fairy Tales\"" + +#: src/std/hashmap.md:12 src/std/hashmap.md:19 src/std/hashmap.md:27 +msgid "\"Pride and Prejudice\"" +msgstr "\"Pride and Prejudice\"" + +#: src/std/hashmap.md:14 +msgid "\"Les Misérables\"" +msgstr "\"Les Misérables\"" + +#: src/std/hashmap.md:15 +msgid "\"We know about {} books, but not Les Misérables.\"" +msgstr "\"Nós sabemos sobre livros {}, mas não Les Misérables.\"" + +#: src/std/hashmap.md:19 src/std/hashmap.md:27 +msgid "\"Alice's Adventure in Wonderland\"" +msgstr "\"Alice's Adventure in Wonderland\"" + +#: src/std/hashmap.md:21 +msgid "\"{book}: {count} pages\"" +msgstr "\"{livro}: {paginas} páginas\"" + +#: src/std/hashmap.md:22 +msgid "\"{book} is unknown.\"" +msgstr "\"{livro} é desconhecido.\"" + +#: src/std/hashmap.md:26 +msgid "// Use the .entry() method to insert a value if nothing is found.\n" msgstr "" -"```rust,editable\n" -"use std::collections::HashMap;\n" -"\n" -"fn main() {\n" -" let mut contadores_paginas = HashMap::new();\n" -" contadores_paginas.insert(\"Adventures of Huckleberry Finn\"." -"to_string(), 207);\n" -" contadores_paginas.insert(\"Grimms' Fairy Tales\".to_string(), 751);\n" -" contadores_paginas.insert(\"Pride and Prejudice\".to_string(), 303);\n" -"\n" -" if !contadores_paginas.contains_key(\"Les Misérables\") {\n" -" println!(\"Nós sabemos sobre livros {}, mas não Les Misérables.\",\n" -" contadores_paginas.len());\n" -" }\n" -"\n" -" for livro in [\"Pride and Prejudice\", \"Alice's Adventure in " -"Wonderland\"] {\n" -" match contadores_paginas.get(livro) {\n" -" Some(paginas) => println!(\"{livro}: {paginas} páginas\"),\n" -" None => println!(\"{livro} é desconhecido.\")\n" -" }\n" -" }\n" -"\n" -" // Use o método .entry() para inserir um valor caso nada seja " -"encontrado.\n" -" for livro in [\"Pride and Prejudice\", \"Alice's Adventure in " -"Wonderland\"] {\n" -" let contador_paginas: &mut i32 = contadores_paginas.entry(livro." -"to_string()).or_insert(0);\n" -" *contador_paginas += 1;\n" -" }\n" -"\n" -" println!(\"{contadores_paginas:#?}\");\n" -"}\n" -"```" +"// Use o método .entry() para inserir um valor caso nada seja encontrado.\n" + +#: src/std/hashmap.md:32 +msgid "\"{page_counts:#?}\"" +msgstr "\"{contadores_paginas:#?}\"" #: src/std/hashmap.md:38 msgid "" @@ -10256,25 +7747,13 @@ msgstr "" "linha irá inserir o valor alternativo no hash map se o livro não for " "encontrado." -#: 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" -"```" -msgstr "" -"```rust,ignore\n" -" let pc1 = contadores_paginas\n" -" .get(\"Harry Potter and the Sorcerer's Stone \")\n" -" .unwrap_or(&336);\n" -" let pc2 = contadores_paginas\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 "\"Harry Potter and the Sorcerer's Stone \"" + +#: src/std/hashmap.md:46 src/std/hashmap.md:55 +msgid "\"The Hunger Games\"" +msgstr "\"The Hunger Games\"" #: src/std/hashmap.md:49 msgid "Unlike `vec!`, there is unfortunately no standard `hashmap!` macro." @@ -10293,21 +7772,9 @@ msgstr "" "From%3C%5B(K,+V);+N%5D%3E-for-HashMap%3CK,+V,+RandomState%3E), o que nos " "permite inicializar facilmente um hash map a partir de uma matriz 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" -"```" -msgstr "" -"```rust,ignore\n" -" let contadores_paginas = 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 "\"Harry Potter and the Sorcerer's Stone\"" #: src/std/hashmap.md:59 msgid "" @@ -10356,49 +7823,9 @@ msgstr "" "[`Box`](https://doc.rust-lang.org/std/boxed/struct.Box.html) é um ponteiro " "_owned_ para dados no 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 "" -"```rust, editable\n" -"fn main() {\n" -" let cinco = Box::new(5);\n" -" println!(\"cinco: {}\", *cinco);\n" -"}\n" -"```" - -#: src/std/box.md:13 -msgid "" -"```bob\n" -" Stack Heap\n" -".- - - - - - -. .- - - - - - -.\n" -": : : :\n" -": five : : :\n" -": +-----+ : : +-----+ :\n" -": | o---|---+-----+-->| 5 | :\n" -": +-----+ : : +-----+ :\n" -": : : :\n" -": : : :\n" -"`- - - - - - -' `- - - - - - -'\n" -"```" -msgstr "" -"```bob\n" -" Pilha Heap\n" -".- - - - - - -. .- - - - - - -.\n" -": : : :\n" -": cinco : : :\n" -": +-----+ : : +-----+ :\n" -": | o---|---+-----+-->| 5 | :\n" -": +-----+ : : +-----+ :\n" -": : : :\n" -": : : :\n" -"`- - - - - - -' `- - - - - - -'\n" -"```" +#: src/std/box.md:8 +msgid "\"five: {}\"" +msgstr "\"cinco: {}\"" #: src/std/box.md:26 msgid "" @@ -10459,35 +7886,9 @@ msgstr "" "Tipos de dados recursivos ou tipos de dados com tamanhos dinâmicos precisam " "usar uma `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" -"```" -msgstr "" -"```rust,editable\n" -"#[derive(Debug)]\n" -"enum List {\n" -" Cons(T, Box>),\n" -" Nil,\n" -"}\n" -"\n" -"fn main() {\n" -" let lista: List = List::Cons(1, Box::new(List::Cons(2, Box::" -"new(List::Nil))));\n" -" println!(\"{lista:?}\");\n" -"}\n" -"```" +#: src/std/box-recursive.md:14 src/std/box-niche.md:12 +msgid "\"{list:?}\"" +msgstr "\"{lista:?}\"" #: src/std/box-recursive.md:18 msgid "" @@ -10620,32 +8021,6 @@ msgstr "" "compartilhado com contagem de referência. Use-o quando precisar consultar os " "mesmos dados a partir de vários locais:" -#: 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" -"```" -msgstr "" -"```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:18 msgid "" "See [`Arc`](../concurrency/shared_state/arc.md) and [`Mutex`](https://doc." @@ -10706,7 +8081,7 @@ msgid "" "on the next slide)." msgstr "" "`Rc::downgrade` lhe fornece um objeto _contador de referências_ " -"\"fraco\" (weak)_ para criar ciclos que podem ser apropriadamente " +"\"fraco\" (weak)\\_ para criar ciclos que podem ser apropriadamente " "descartados (provavelmente combinados com `RefCell`, no próximo slide)." #: src/std/cell.md:1 @@ -10735,75 +8110,13 @@ msgstr "" "rastreia referências compartilhadas e exclusivas em tempo de execução e " "retorna um pânico (_panic_) se forem mal utilizadas." -#: 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" -"```" -msgstr "" -"```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 "\"graph: {root:#?}\"" + +#: src/std/cell.md:41 +msgid "\"graph sum: {}\"" +msgstr "\"graph sum: {}\"" #: src/std/cell.md:47 msgid "" @@ -10856,45 +8169,13 @@ msgid "Similarly, `mod` lets us namespace types and functions:" msgstr "" "Da mesma forma, `mod` nos permite usar _namespaces_ de tipos e funções:" -#: 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" -"```" -msgstr "" -"```rust,editable\n" -"mod foo {\n" -" pub fn faz_algo() {\n" -" println!(\"No módulo foo\");\n" -" }\n" -"}\n" -"\n" -"mod bar {\n" -" pub fn faz_algo() {\n" -" println!(\"No módulo bar\");\n" -" }\n" -"}\n" -"\n" -"fn main() {\n" -" foo::faz_algo();\n" -" bar::faz_algo();\n" -"}\n" -"```" +#: src/modules.md:10 +msgid "\"In the foo module\"" +msgstr "\"No módulo foo\"" + +#: src/modules.md:16 +msgid "\"In the bar module\"" +msgstr "\"No módulo bar\"" #: src/modules.md:28 msgid "" @@ -10937,67 +8218,27 @@ msgstr "" "Em outras palavras, se um item é visível no módulo `foo`, ele é visível em " "todos os descendentes 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" -"```" -msgstr "" -"```rust,editable\n" -"mod externo {\n" -" fn privado() {\n" -" println!(\"externo::privado\");\n" -" }\n" -"\n" -" pub fn publico() {\n" -" println!(\"externo::publico\");\n" -" }\n" -"\n" -" mod interno {\n" -" fn privado() {\n" -" println!(\"externo::interno::privado\");\n" -" }\n" -"\n" -" pub fn publico() {\n" -" println!(\"externo::interno::publico\");\n" -" super::privado();\n" -" }\n" -" }\n" -"}\n" -"\n" -"fn main() {\n" -" externo::publico();\n" -"}\n" -"```" - -#: src/modules/visibility.md:39 -msgid "Use the `pub` keyword to make modules public." -msgstr "Use a palavra reservada `pub` para tornar módulos públicos." - -#: src/modules/visibility.md:41 +#: src/modules/visibility.md:13 +msgid "\"outer::private\"" +msgstr "\"externo::privado\"" + +#: src/modules/visibility.md:17 +msgid "\"outer::public\"" +msgstr "\"externo::publico\"" + +#: src/modules/visibility.md:22 +msgid "\"outer::inner::private\"" +msgstr "\"externo::interno::privado\"" + +#: src/modules/visibility.md:26 +msgid "\"outer::inner::public\"" +msgstr "\"externo::interno::publico\"" + +#: src/modules/visibility.md:39 +msgid "Use the `pub` keyword to make modules public." +msgstr "Use a palavra reservada `pub` para tornar módulos públicos." + +#: src/modules/visibility.md:41 msgid "" "Additionally, there are advanced `pub(...)` specifiers to restrict the scope " "of public visibility." @@ -11065,34 +8306,12 @@ msgstr "" "Um módulo pode trazer símbolos de outro módulo para o escopo com `use`. " "Normalmente, você verá algo assim na 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 "" -"```rust,editable\n" -"use std::collections::HashSet;\n" -"use std::mem::transmute;\n" -"```" - #: src/modules/filesystem.md:3 msgid "" "Omitting the module content will tell Rust to look for it in another file:" msgstr "" "Omitir o conteúdo do módulo dirá ao Rust para procurá-lo em outro arquivo:" -#: src/modules/filesystem.md:5 -msgid "" -"```rust,editable,compile_fail\n" -"mod garden;\n" -"```" -msgstr "" -"```rust,editable,compile_fail\n" -"mod jardim;\n" -"```" - #: src/modules/filesystem.md:9 msgid "" "This tells rust that the `garden` module content is found at `src/garden." @@ -11125,39 +8344,27 @@ msgstr "" "\"comentários internos de documento\" (_inner doc comments_). Estes " "documentam o item que os contém - neste caso, um 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 "" -"```rust,editable,compile_fail\n" "//! Este módulo implementa o jardim, incluindo uma implementação de " "germinação\n" "//! de alto desempenho.\n" -"\n" -"// Re-exporta tipos deste módulo.\n" -"pub use sementes::SementePacote;\n" -"pub use jardim::Jardim;\n" -"\n" -"/// Semeia os pacotes de semente fornecidos.\n" -"pub fn semear(sementes: Vec) { todo!() }\n" -"\n" -"/// Colhe os vegetais no jardim que está pronto.\n" -"pub fn colher(jardim: &mut Jardim) { todo!() }\n" -"```" + +#: src/modules/filesystem.md:23 +msgid "// Re-export types from this module.\n" +msgstr "// Re-exporta tipos deste módulo.\n" + +#: src/modules/filesystem.md:27 +msgid "/// Sow the given seed packets.\n" +msgstr "/// Semeia os pacotes de semente fornecidos.\n" + +#: src/modules/filesystem.md:30 +msgid "/// Harvest the produce in the garden that is ready.\n" +msgstr "/// Colhe os vegetais no jardim que está pronto.\n" #: src/modules/filesystem.md:37 msgid "" @@ -11183,24 +8390,6 @@ msgstr "" "O aninhamento mais profundo pode usar pastas, mesmo que o módulo principal " "seja um arquivo:" -#: 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 "" -"```ignore\n" -"src/\n" -"├── main.rs\n" -"├── top_module.rs\n" -"└── top_module/\n" -" └── sub_module.rs\n" -"```" - #: src/modules/filesystem.md:52 msgid "" "The place rust will look for modules can be changed with a compiler " @@ -11209,17 +8398,9 @@ msgstr "" "O local no qual o Rust irá procurar por módulos pode ser alterado por meio " "de uma diretiva de compilador:" -#: src/modules/filesystem.md:54 -msgid "" -"```rust,ignore\n" -"#[path = \"some/path.rs\"]\n" -"mod some_module;\n" -"```" -msgstr "" -"```rust,ignore\n" -"#[caminho = \"algum/caminho.rs\"]\n" -"mod algum_modulo { }\n" -"```" +#: src/modules/filesystem.md:55 +msgid "\"some/path.rs\"" +msgstr "\"algum/caminho.rs\"" #: src/modules/filesystem.md:59 msgid "" @@ -11291,105 +8472,49 @@ msgid "" "integers. Then, revisit the solution and try to implement it with iterators." msgstr "" -#: src/exercises/day-2/luhn.md:25 -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" -"}\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" -"```" -msgstr "" -"```rust\n" -"// TODO: remova isto quando você estiver terminado com sua implementação.\n" -"#![allow(unused_variables, dead_code)]\n" -"\n" -"pub fn luhn(cc_numero: &str) -> bool {\n" -" unimplemented!()\n" -"}\n" -"\n" -"#[test]\n" -"fn teste_cc_numero_nao_digito() {\n" -" assert!(!luhn(\"foo\"));\n" -"}\n" -"\n" -"#[test]\n" -"fn teste_cc_numero_vazio() {\n" -" assert!(!luhn(\"\"));\n" -" assert!(!luhn(\" \"));\n" -" assert!(!luhn(\" \"));\n" -" assert!(!luhn(\" \"));\n" -"}\n" -"\n" -"#[test]\n" -"fn teste_cc_numero_digito_simples() {\n" -" assert!(!luhn(\"0\"));\n" -"}\n" -"\n" -"#[test]\n" -"fn teste_cc_numero_dois_digitos() {\n" -" assert!(luhn(\" 0 0 \"));\n" -"}\n" -"\n" -"#[test]\n" -"fn teste_cc_numero_valido() {\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 teste_cc_numero_invalido() {\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" -"```" +#: src/exercises/day-2/luhn.md:41 src/exercises/day-2/solutions-afternoon.md:66 +msgid "\" \"" +msgstr "\" \"" + +#: src/exercises/day-2/luhn.md:42 src/exercises/day-2/solutions-afternoon.md:67 +msgid "\" \"" +msgstr "\" \"" + +#: src/exercises/day-2/luhn.md:43 src/exercises/day-2/solutions-afternoon.md:68 +msgid "\" \"" +msgstr "\" \"" + +#: src/exercises/day-2/luhn.md:48 src/exercises/day-2/solutions-afternoon.md:73 +msgid "\"0\"" +msgstr "\"0\"" + +#: src/exercises/day-2/luhn.md:53 src/exercises/day-2/solutions-afternoon.md:78 +msgid "\" 0 0 \"" +msgstr "\" 0 0 \"" + +#: src/exercises/day-2/luhn.md:58 src/exercises/day-2/solutions-afternoon.md:83 +msgid "\"4263 9826 4026 9299\"" +msgstr "\"4263 9826 4026 9299\"" + +#: src/exercises/day-2/luhn.md:59 src/exercises/day-2/solutions-afternoon.md:84 +msgid "\"4539 3195 0343 6467\"" +msgstr "\"4539 3195 0343 6467\"" + +#: src/exercises/day-2/luhn.md:60 src/exercises/day-2/solutions-afternoon.md:85 +msgid "\"7992 7398 713\"" +msgstr "\"7992 7398 713\"" + +#: src/exercises/day-2/luhn.md:65 src/exercises/day-2/solutions-afternoon.md:90 +msgid "\"4223 9826 4026 9299\"" +msgstr "\"4223 9826 4026 9299\"" + +#: src/exercises/day-2/luhn.md:66 src/exercises/day-2/solutions-afternoon.md:91 +msgid "\"4539 3195 0343 6476\"" +msgstr "\"4539 3195 0343 6476\"" + +#: src/exercises/day-2/luhn.md:67 src/exercises/day-2/solutions-afternoon.md:92 +msgid "\"8273 1232 7352 0569\"" +msgstr "\"8273 1232 7352 0569\"" #: src/exercises/day-2/strings-iterators.md:3 msgid "" @@ -11412,100 +8537,80 @@ msgstr "" "Copie o seguinte código para e faça os testes " "passarem. Tente evitar alocar um `Vec` para seus resultados intermediários:" -#: 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" -"```" -msgstr "" -"```rust\n" -"// TODO: remova isto quando você estiver terminado com sua implementação.\n" -"#![allow(unused_variables, dead_code)]\n" -"\n" -"pub fn corresponde_prefixo(prefixo: &str, caminho_requisitado: &str) -> bool " -"{\n" -" unimplemented!()\n" -"}\n" -"\n" -"#[test]\n" -"fn teste_corresponde_sem_curinga() {\n" -" assert!(corresponde_prefixo(\"/v1/editores\", \"/v1/editores\"));\n" -" assert!(corresponde_prefixo(\"/v1/editores\", \"/v1/editores/" -"abc-123\"));\n" -" assert!(corresponde_prefixo(\"/v1/editores\", \"/v1/editores/abc/" -"livros\"));\n" -"\n" -" assert!(!corresponde_prefixo(\"/v1/editores\", \"/v1\"));\n" -" assert!(!corresponde_prefixo(\"/v1/editores\", \"/v1/" -"editoresLivros\"));\n" -" assert!(!corresponde_prefixo(\"/v1/editores\", \"/v1/pai/editores\"));\n" -"}\n" -"\n" -"#[test]\n" -"fn teste_corresponde_com_curinga() {\n" -" assert!(corresponde_prefixo(\n" -" \"/v1/editores/*/livros\",\n" -" \"/v1/editores/foo/livros\"\n" -" ));\n" -" assert!(corresponde_prefixo(\n" -" \"/v1/editores/*/livros\",\n" -" \"/v1/editores/bar/livros\"\n" -" ));\n" -" assert!(corresponde_prefixo(\n" -" \"/v1/editores/*/livros\",\n" -" \"/v1/editores/foo/livros/livro1\"\n" -" ));\n" -"\n" -" assert!(!corresponde_prefixo(\"/v1/editores/*/livros\", \"/v1/" -"editores\"));\n" -" assert!(!corresponde_prefixo(\n" -" \"/v1/editores/*/livros\",\n" -" \"/v1/editores/foo/livrosPorAutor\"\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:143 +#: src/exercises/day-2/solutions-afternoon.md:144 +#: src/exercises/day-2/solutions-afternoon.md:145 +#: src/exercises/day-2/solutions-afternoon.md:147 +#: src/exercises/day-2/solutions-afternoon.md:148 +#: src/exercises/day-2/solutions-afternoon.md:149 +#: src/exercises/day-2/solutions-afternoon.md:167 +msgid "\"/v1/publishers\"" +msgstr "\"/v1/editores\"" + +#: src/exercises/day-2/strings-iterators.md:23 +#: src/exercises/day-2/solutions-afternoon.md:144 +msgid "\"/v1/publishers/abc-123\"" +msgstr "\"/v1/editores/abc-123\"" + +#: src/exercises/day-2/strings-iterators.md:24 +#: src/exercises/day-2/solutions-afternoon.md:145 +msgid "\"/v1/publishers/abc/books\"" +msgstr "\"/v1/editores/abc/livros\"" + +#: src/exercises/day-2/strings-iterators.md:26 +#: src/exercises/day-2/solutions-afternoon.md:147 +msgid "\"/v1\"" +msgstr "\"/v1\"" + +#: src/exercises/day-2/strings-iterators.md:27 +#: src/exercises/day-2/solutions-afternoon.md:148 +msgid "\"/v1/publishersBooks\"" +msgstr "\"/v1/editoresLivros\"" + +#: src/exercises/day-2/strings-iterators.md:28 +#: src/exercises/day-2/solutions-afternoon.md:149 +msgid "\"/v1/parent/publishers\"" +msgstr "\"/v1/pai/editores\"" + +#: 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:155 +#: src/exercises/day-2/solutions-afternoon.md:159 +#: src/exercises/day-2/solutions-afternoon.md:163 +#: src/exercises/day-2/solutions-afternoon.md:167 +#: src/exercises/day-2/solutions-afternoon.md:169 +msgid "\"/v1/publishers/*/books\"" +msgstr "\"/v1/editores/*/livros\"" + +#: src/exercises/day-2/strings-iterators.md:35 +#: src/exercises/day-2/solutions-afternoon.md:156 +msgid "\"/v1/publishers/foo/books\"" +msgstr "\"/v1/editores/foo/livros\"" + +#: src/exercises/day-2/strings-iterators.md:39 +#: src/exercises/day-2/solutions-afternoon.md:160 +msgid "\"/v1/publishers/bar/books\"" +msgstr "\"/v1/editores/bar/livros\"" + +#: src/exercises/day-2/strings-iterators.md:43 +#: src/exercises/day-2/solutions-afternoon.md:164 +msgid "\"/v1/publishers/foo/books/book1\"" +msgstr "\"/v1/editores/foo/livros/livro1\"" + +#: src/exercises/day-2/strings-iterators.md:49 +#: src/exercises/day-2/solutions-afternoon.md:170 +msgid "\"/v1/publishers/foo/booksByAuthor\"" +msgstr "\"/v1/editores/foo/livrosPorAutor\"" #: src/welcome-day-3.md:1 msgid "Welcome to Day 3" @@ -11554,35 +8659,9 @@ msgstr "" msgid "You can use generics to abstract over the concrete field type:" msgstr "Você pode usar tipos genéricos para abstrair o tipo concreto do campo:" -#: 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" -"```" -msgstr "" -"```rust,editable\n" -"#[derive(Debug)]\n" -"struct Ponto {\n" -" x: T,\n" -" y: T,\n" -"}\n" -"\n" -"fn main() {\n" -" let inteiro = Ponto { x: 5, y: 10 };\n" -" let real = Ponto { x: 1.0, y: 4.0 };\n" -" println!(\"{inteiro:?} e {real:?}\");\n" -"}\n" -"```" +#: src/generics/data-types.md:15 +msgid "\"{integer:?} and {float:?}\"" +msgstr "\"{inteiro:?} e {real:?}\"" #: src/generics/data-types.md:21 msgid "Try declaring a new variable `let p = Point { x: 5, y: 10.0 };`." @@ -11598,25 +8677,16 @@ msgstr "" msgid "You can declare a generic type on your `impl` block:" msgstr "Você pode declarar um tipo genérico em seu bloco `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 @@ -11657,62 +8727,10 @@ msgstr "" "O código _genérico_ é transformado em código _não genérico_ de acordo com os " "tipos usados:" -#: 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 "" -"```rust, editable\n" -"fn main() {\n" -" let inteiro = Some(5);\n" -" let real = Some(5.0);\n" -"}\n" -"```" - #: src/generics/monomorphization.md:12 msgid "behaves as if you wrote" msgstr "se comporta como se você tivesse 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 "" -"```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 inteiro = Option_i32::Some(5);\n" -" let real = Option_f64::Some(5.0);\n" -"}\n" -"```" - #: src/generics/monomorphization.md:31 msgid "" "This is a zero-cost abstraction: you get exactly the same result as if you " @@ -11729,80 +8747,21 @@ msgstr "" "Rust permite abstrair características dos tipos usando `trait`. Eles são " "semelhantes a 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" -"```" -msgstr "" -"```rust,editable\n" -"trait Pet {\n" -" fn nome(&self) -> String;\n" -"}\n" -"\n" -"struct Cachorro {\n" -" nome: String,\n" -"}\n" -"\n" -"struct Gato;\n" -"\n" -"impl Pet for Cachorro {\n" -" fn nome(&self) -> String {\n" -" self.nome.clone()\n" -" }\n" -"}\n" -"\n" -"impl Pet for Gato {\n" -" fn nome(&self) -> String {\n" -" String::from(\"Gato\") // Sem nomes, gatos não respondem mesmo.\n" -" }\n" -"}\n" -"\n" -"fn saudar(pet: &P) {\n" -" println!(\"Quem é? É o {}!\", pet.nome());\n" -"}\n" -"\n" -"fn main() {\n" -" let bidu = Cachorro { nome: \"Bidu\".into() };\n" -" saudar(&bidu);\n" -"\n" -" let felix = Gato;\n" -" saudar(&felix);\n" -"}\n" -"```" +#: src/traits.md:24 src/traits/trait-objects.md:24 +msgid "\"The cat\"" +msgstr "\"Gato\"" + +#: src/traits.md:24 src/traits/trait-objects.md:24 +msgid "// No name, cats won't respond to it anyway.\n" +msgstr "// Sem nomes, gatos não respondem mesmo.\n" + +#: src/traits.md:29 +msgid "\"Who's a cutie? {} is!\"" +msgstr "\"Quem é? É o {}!\"" + +#: src/traits.md:33 src/traits/trait-objects.md:31 +msgid "\"Fido\"" +msgstr "\"Bidu\"" #: src/traits/trait-objects.md:3 msgid "" @@ -11812,77 +8771,9 @@ msgstr "" "Objetos `trait` permitem valores de diferentes tipos, por exemplo, em uma " "coleção:" -#: 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" -"```" -msgstr "" -"```rust,editable\n" -"trait Pet {\n" -" fn nome(&self) -> String;\n" -"}\n" -"\n" -"struct Cachorro {\n" -" nome: String,\n" -"}\n" -"\n" -"struct Gato;\n" -"\n" -"impl Pet for Cachorro {\n" -" fn nome(&self) -> String {\n" -" self.nome.clone()\n" -" }\n" -"}\n" -"\n" -"impl Pet for Gato {\n" -" fn nome(&self) -> String {\n" -" String::from(\"O gato\") // Sem nomes, de qualquer forma gatos não " -"reconhecem.\n" -" }\n" -"}\n" -"\n" -"fn main() {\n" -" let pets: Vec> = vec![\n" -" Box::new(Gato),\n" -" Box::new(Cachorro { nome: String::from(\"Bidu\") }),\n" -" ];\n" -" for pet in pets {\n" -" println!(\"Olá {}!\", pet.nome());\n" -" }\n" -"}\n" -"```" +#: src/traits/trait-objects.md:34 +msgid "\"Hello {}!\"" +msgstr "\"Olá {}!\"" #: src/traits/trait-objects.md:40 msgid "Memory layout after allocating `pets`:" @@ -12020,25 +8911,10 @@ msgstr "" msgid "Compare these outputs in the above example:" msgstr "Compare estas saídas no exemplo 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" -"```" -msgstr "" -"```rust,ignore\n" -" println!(\"{} {}\", std::mem::size_of::(), std::mem::size_of::" -"());\n" -" println!(\"{} {}\", std::mem::size_of::<&Cachorro>(), std::mem::size_of::" -"<&Gato>());\n" -" println!(\"{}\", std::mem::size_of::<&dyn Pet>());\n" -" println!(\"{}\", std::mem::size_of::>());\n" -"```" +#: src/traits/trait-objects.md:77 src/traits/trait-objects.md:78 +#: src/traits/closures.md:54 +msgid "\"{} {}\"" +msgstr "\"{} {}\"" #: src/traits/deriving-traits.md:3 msgid "" @@ -12052,39 +8928,19 @@ msgstr "" msgid "You can let the compiler derive a number of traits as follows:" msgstr "Você pode deixar o compilador derivar uma série de _traits_ tais como:" -#: 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" -"```" -msgstr "" -"```rust,editable\n" -"#[derive(Debug, Clone, PartialEq, Eq, Default)]\n" -"struct Jogador {\n" -" nome: String,\n" -" forca: u8,\n" -" pontos_ataque: u8,\n" -"}\n" -"\n" -"fn main() {\n" -" let p1 = Jogador::default();\n" -" let p2 = p1.clone();\n" -" println!(\"{:?} é\\nigual a {:?}?\\nA resposta é {}!\", &p1, &p2,\n" -" if p1 == p2 { \"sim\" } else { \"não\" });\n" -"}\n" -"```" +#: src/traits/deriving-traits.md:18 +msgid "\"Is {:?}\\nequal to {:?}?\\nThe answer is {}!\"" +msgstr "\"{:?} é\\nigual a {:?}?\\nA resposta é {}!\"" + +#: src/traits/deriving-traits.md:19 +#: src/exercises/day-2/solutions-afternoon.md:53 +msgid "\"yes\"" +msgstr "\"sim\"" + +#: src/traits/deriving-traits.md:19 +#: src/exercises/day-2/solutions-afternoon.md:53 +msgid "\"no\"" +msgstr "\"não\"" #: src/traits/default-methods.md:3 msgid "Traits can implement behavior in terms of other trait methods:" @@ -12092,59 +8948,15 @@ msgstr "" "Traits podem implementar o comportamento em termos de outros métodos de " "`trait`:" -#: 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" -"```" -msgstr "" -"```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 Centimetro(i16);\n" -"\n" -"impl Equals for Centimetro {\n" -" fn equals(&self, other: &Centimetro) -> bool {\n" -" self.0 == other.0\n" -" }\n" -"}\n" -"\n" -"fn main() {\n" -" let a = Centimetro(10);\n" -" let b = Centimetro(20);\n" -" println!(\"{a:?} igual a {b:?}: {}\", a.equals(&b));\n" -" println!(\"{a:?} diferente de {b:?}: {}\", a.not_equals(&b));\n" -"}\n" -"```" - -#: src/traits/default-methods.md:32 +#: src/traits/default-methods.md:25 +msgid "\"{a:?} equals {b:?}: {}\"" +msgstr "\"{a:?} igual a {b:?}: {}\"" + +#: src/traits/default-methods.md:26 +msgid "\"{a:?} not_equals {b:?}: {}\"" +msgstr "\"{a:?} diferente de {b:?}: {}\"" + +#: src/traits/default-methods.md:32 msgid "" "Traits may specify pre-implemented (default) methods and methods that users " "are required to implement themselves. Methods with default implementations " @@ -12162,54 +8974,10 @@ msgstr "Mova o método `not_equals` para um novo _trait_ `NotEquals`." msgid "Make `Equals` a super trait for `NotEquals`." msgstr "Faça `Equals` um _super trait_ 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 "Forneça uma implementação geral 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 "" -"```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" -"```" - #: src/traits/default-methods.md:58 msgid "" "With the blanket implementation, you no longer need `Equals` as a super " @@ -12230,32 +8998,26 @@ msgstr "" msgid "You can do this with `T: Trait` or `impl Trait`:" msgstr "Você consegue fazer isso com `T:Trait` ou `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 @@ -12264,26 +9026,6 @@ msgstr "" "Mostre uma cláusula `where`, os estudantes irão encontrá-la quando lerem " "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 "" -"```rust,ignore\n" -"fn duplicar(a: T) -> (T, T)\n" -"where\n" -" T: Clone,\n" -"{\n" -" (a.clone(), a.clone())\n" -"}\n" -"```" - #: src/traits/trait-bounds.md:46 msgid "It declutters the function signature if you have many parameters." msgstr "Organiza a assinatura da função se você tiver muitos parâmetros." @@ -12312,22 +9054,6 @@ msgstr "" "Semelhante aos limites do _trait_, a sintaxe do _trait_ `impl` pode ser " "usada em argumentos de funções e em valores de retorno:" -#: 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 "" @@ -12459,32 +9185,8 @@ msgid "" "Iterator.html) trait on your own types:" msgstr "Você pode implementar o _trait_ `Iterator` em seus próprios 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 @@ -12512,19 +9214,6 @@ msgid "" msgstr "" "`FromIterator` permite construir uma coleção a partir de um `Iterator`." -#: 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" -"```" -msgstr "" - #: src/traits/from-iterator.md:17 msgid "" "`Iterator` implements `fn collect(self) -> B where B: FromIterator(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 @@ -12669,32 +9309,17 @@ msgstr "" "Da mesma forma, [`Write`](https://doc.rust-lang.org/std/io/trait.Write.html) " "permite abstrair a escrita de dados do tipo `u8`:" -#: src/traits/read-write.md:25 +#: src/traits/read-write.md:30 #, fuzzy -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" -"```" +msgid "\"\\n\"" msgstr "" "fn main() -> Result\\<()> { let mut buffer = Vec::new(); log(&mut buffer, " "\"Olá\")?; log(&mut buffer, \"Mundo\")?; println!(\"Logado: {:?}\", buffer); " -"Ok(()) }\n" -"\n" -"```\n" -"```" +"Ok(()) }" + +#: src/traits/read-write.md:37 +msgid "\"Logged: {:?}\"" +msgstr "" #: src/traits/drop.md:1 msgid "The `Drop` Trait" @@ -12708,43 +9333,44 @@ msgstr "" "Valores que implementam [`Drop`](https://doc.rust-lang.org/std/ops/trait." "Drop.html) podem especificar o código a ser executado quando saem do escopo:" -#: src/traits/drop.md:5 +#: src/traits/drop.md:12 #, fuzzy -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" -"```" +msgid "\"Dropping {}\"" msgstr "" "fn main() { let a = Excluivel { nome: \"a\" }; { let b = Excluivel { nome: " "\"b\" }; { let c = Excluivel { nome: \"c\" }; let d = Excluivel { nome: " "\"d\" }; println!(\"Saindo do bloco B\"); } println!(\"Saindo do bloco " -"A\"); } drop(a); println!(\"Saindo do main\"); }\n" -"\n" -"```\n" -"```" +"A\"); } drop(a); println!(\"Saindo do main\"); }" + +#: src/traits/drop.md:17 src/exercises/concurrency/link-checker.md:92 +#: src/exercises/day-1/solutions-morning.md:107 +#: src/exercises/concurrency/solutions-morning.md:162 +msgid "\"a\"" +msgstr "" + +#: src/traits/drop.md:19 src/exercises/day-1/solutions-morning.md:107 +msgid "\"b\"" +msgstr "" + +#: src/traits/drop.md:21 src/exercises/day-1/solutions-morning.md:107 +msgid "\"c\"" +msgstr "" + +#: src/traits/drop.md:22 src/exercises/day-1/solutions-morning.md:107 +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 src/traits/operators.md:26 msgid "Discussion points:" @@ -12779,40 +9405,24 @@ msgstr "" "O _trait_ [`Default`](https://doc.rust-lang.org/std/default/trait.Default." "html) fornece uma implementação padrão para um 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 @@ -12875,26 +9485,8 @@ msgstr "" "A sobrecarga de operadores é implementada por meio do `trait` contido em " "[`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 @@ -12958,40 +9550,22 @@ msgstr "" "trait.FnMut.html) e [`FnOnce`](https://doc.rust-lang.org/std/ops/trait." "FnOnce.html):" -#: src/traits/closures.md:8 +#: src/traits/closures.md:10 #, fuzzy -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" -"```" +msgid "\"Calling function on {input}\"" +msgstr "\"Chamando a função com {entrada}\"" + +#: 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 "" -"```rust,editable\n" -"fn aplicar_com_registro(funcao: impl FnOnce(i32) -> i32, entrada: i32) -> " -"i32 {\n" -" println!(\"Chamando a função com {entrada}\");\n" -" funcao(entrada)\n" -"}\n" -"```" #: src/traits/closures.md:34 msgid "" @@ -13040,18 +9614,12 @@ msgid "" "keyword makes them capture by value." msgstr "" -#: 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 @@ -13104,177 +9672,74 @@ msgstr "" "Copie o código abaixo para , codifique os " "métodos `draw_into` para que você implemente o `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:23 +#: src/exercises/day-3/solutions-morning.md:24 +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 "A saída do programa acima pode ser algo simples como:" +#: src/exercises/day-3/simple-gui.md:26 +#: src/exercises/day-3/solutions-morning.md:27 +msgid "/// Draw the widget into a buffer.\n" +msgstr "" -#: src/exercises/day-3/simple-gui.md:132 -#, fuzzy -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:29 +#: src/exercises/day-3/solutions-morning.md:30 +msgid "/// Draw the widget on standard output.\n" msgstr "" -"```texto\n" -"========\n" -"Demonstração da GUI do Rust 1.23\n" -"========\n" -"```" -#: src/exercises/day-3/simple-gui.md:142 -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 " -"particular, notice how you can pad with different characters (here a `'/'`) " -"and how you can control alignment:" +#: src/exercises/day-3/simple-gui.md:33 +#: src/exercises/day-3/solutions-morning.md:34 +msgid "\"{buffer}\"" msgstr "" -"Se você quiser desenhar texto alinhado, você pode usar os operadores de " -"formatação [fill/alignment](https://doc.rust-lang.org/std/fmt/index." -"html#fillalignment). Em particular, observe como você pode preencher com " -"diferentes caracteres (aqui um `'/'`) e como você pode controlar o " -"alinhamento:" -#: src/exercises/day-3/simple-gui.md:147 +#: src/exercises/day-3/simple-gui.md:120 +#: src/exercises/day-3/solutions-morning.md:164 +msgid "\"Rust GUI Demo 1.23\"" +msgstr "" + +#: src/exercises/day-3/simple-gui.md:121 +#: src/exercises/day-3/solutions-morning.md:165 +msgid "\"This is a small text GUI demo.\"" +msgstr "" + +#: src/exercises/day-3/simple-gui.md:123 +#: src/exercises/day-3/solutions-morning.md:167 +msgid "\"Click me!\"" +msgstr "" + +#: src/exercises/day-3/simple-gui.md:124 +#: src/exercises/day-3/solutions-morning.md:168 +msgid "\"You clicked the button!\"" +msgstr "" + +#: src/exercises/day-3/simple-gui.md:130 +msgid "The output of the above program can be something simple like this:" +msgstr "A saída do programa acima pode ser algo simples como:" + +#: src/exercises/day-3/simple-gui.md:142 msgid "" -"```rust,editable\n" -"fn main() {\n" -" let width = 10;\n" -" println!(\"left aligned: |{:/width$}|\", \"foo\");\n" -"}\n" -"```" +"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 " +"particular, notice how you can pad with different characters (here a `'/'`) " +"and how you can control alignment:" msgstr "" -"```rust, editable\n" -"fn main() {\n" -" let largura = 10;\n" -" println!(\"alinhado à esquerda: |{:/largura$}|\", \"foo\");\n" -"}\n" -"```" +"Se você quiser desenhar texto alinhado, você pode usar os operadores de " +"formatação [fill/alignment](https://doc.rust-lang.org/std/fmt/index." +"html#fillalignment). Em particular, observe como você pode preencher com " +"diferentes caracteres (aqui um `'/'`) e como você pode controlar o " +"alinhamento:" + +#: src/exercises/day-3/simple-gui.md:150 +msgid "\"left aligned: |{:/width$}|\"" +msgstr "\"alinhado à direita: |{:/>largura$}|\"" #: src/exercises/day-3/simple-gui.md:156 msgid "" @@ -13283,30 +9748,6 @@ msgstr "" "Usando esses truques de alinhamento, você pode, por exemplo, produzir uma " "saída como esta:" -#: 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 "" -"```texto\n" -"+--------------------------------------------------+\n" -"| Rust GUI Demonstração 1.23 |\n" -"+==================================================+\n" -"| Esta é uma pequena demonstração de GUI de texto. |\n" -"| +----------------+ |\n" -"| | Clique-me! | |\n" -"| +----------------+ |\n" -"+--------------------------------------------------+\n" -"```" - #: src/error-handling.md:3 msgid "Error handling in Rust is done using explicit control flow:" msgstr "" @@ -13326,21 +9767,9 @@ msgstr "" "O Rust irá disparar um _panic_ (pânico) se um erro fatal ocorrer em tempo de " "execução:" -#: 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" -"```" -msgstr "" -"```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 "\"v[100]: {}\"" #: src/error-handling/panics.md:12 msgid "Panics are for unrecoverable and unexpected errors." @@ -13369,39 +9798,13 @@ msgstr "" "Por padrão, um pânico causará a _resolução_ da pilha. A resolução pode ser " "capturada:" -#: 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" -"```" -msgstr "" -"```rust,editable\n" -"use std::panic;\n" -"\n" -"fn main() {\n" -" let result = panic::catch_unwind(|| {\n" -" println!(\"olá!\");\n" -" });\n" -" assert!(result.is_ok());\n" -" \n" -" let result = panic::catch_unwind(|| {\n" -" panic!(\"ah não!\");\n" -" });\n" -" assert!(result.is_err());\n" -"}\n" -"```" +#: src/error-handling/panic-unwind.md:10 +msgid "\"hello!\"" +msgstr "\"olá!\"" + +#: src/error-handling/panic-unwind.md:15 +msgid "\"oh no!\"" +msgstr "\"ah não!\"" #: src/error-handling/panic-unwind.md:21 msgid "" @@ -13428,45 +9831,17 @@ msgstr "" "Já vimos o _enum_ `Result`. Ele é usado amplamente quando os erros são " "esperados como parte da operação 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" -"```" -msgstr "" -"```rust,editable\n" -"use std::fs;\n" -"use std::io::Read;\n" -"\n" -"fn main() {\n" -" let arquivo = fs::File::open(\"diario.txt\");\n" -" match arquivo {\n" -" Ok(mut arquivo) => {\n" -" let mut conteudo = String::new();\n" -" arquivo.read_to_string(&mut conteudo);\n" -" println!(\"Querido diário: {conteudo}\");\n" -" },\n" -" Err(err) => {\n" -" println!(\"Não foi possível abrir o diário: {err}\");\n" -" }\n" -" }\n" -"}\n" -"```" +#: src/error-handling/result.md:11 +msgid "\"diary.txt\"" +msgstr "\"diario.txt\"" + +#: src/error-handling/result.md:16 +msgid "\"Dear diary: {contents}\"" +msgstr "\"Querido diário: {conteudo}\"" + +#: src/error-handling/result.md:19 +msgid "\"The diary could not be opened: {err}\"" +msgstr "\"Não foi possível abrir o diário: {err}\"" #: src/error-handling/result.md:27 msgid "" @@ -13503,92 +9878,31 @@ msgstr "" "ocorrer um erro, este é retornado imediatamente ao chamador como retorno da " "função." -#: 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 "" -"```rust, ignore\n" -"match alguma_expressao {\n" -" Ok(valor) => valor,\n" -" Err(err) => return Err(err),\n" -"}\n" -"```" - #: src/error-handling/try-operator.md:13 msgid "into the much simpler" msgstr "O código acima pode ser simplificado para:" -#: src/error-handling/try-operator.md:15 -msgid "" -"```rust,ignore\n" -"some_expression?\n" -"```" -msgstr "" -"```rust, ignore\n" -"alguma_expressao?\n" -"```" - #: src/error-handling/try-operator.md:19 msgid "We can use this to simplify our error handling code:" msgstr "" "Podemos usar isso para simplificar nosso código de tratamento de erros:" -#: 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" -"```" -msgstr "" -"```rust,editable\n" -"use std::{fs, io};\n" -"use std::io::Read;\n" -"\n" -"fn ler_usuario(caminho: &str) -> Result {\n" -" let resultado_arq_usuario = fs::File::open(caminho);\n" -" let mut arquivo_usuario = match resultado_arq_usuario {\n" -" Ok(arquivo) => arquivo,\n" -" Err(err) => return Err(err),\n" -" };\n" -"\n" -" let mut nome_usuario = String::new();\n" -" match arquivo_usuario.read_to_string(&mut nome_usuario) {\n" -" Ok(_) => Ok(nome_usuario),\n" -" Err(err) => Err(err),\n" -" }\n" -"}\n" -"\n" -"fn main() {\n" -" //fs::write(\"config.dat\", \"alice\").unwrap();\n" -" let nome_usuario = ler_usuario(\"config.dat\");\n" -" println!(\"nome_usuario ou erro: {nome_usuario:?}\");\n" -"}\n" -"```" +#: src/error-handling/try-operator.md:40 +msgid "//fs::write(\"config.dat\", \"alice\").unwrap();\n" +msgstr "//fs::write(\"config.dat\", \"alice\").unwrap();\n" + +#: 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 "\"config.dat\"" + +#: src/error-handling/try-operator.md:42 +#: src/error-handling/converting-error-types-example.md:44 +msgid "\"username or error: {username:?}\"" +msgstr "\"nome_usuario ou erro: {nome_usuario:?}\"" #: src/error-handling/try-operator.md:50 #: src/error-handling/converting-error-types-example.md:52 @@ -13630,36 +9944,10 @@ msgstr "" "A expansão efetiva do operador `?` é um pouco mais complicada do que " "indicado anteriormente:" -#: src/error-handling/converting-error-types.md:5 -msgid "" -"```rust,ignore\n" -"expression?\n" -"```" -msgstr "" -"```rust,ignore\n" -"expressao?\n" -"```" - #: src/error-handling/converting-error-types.md:9 msgid "works the same as" msgstr "funciona da mesma forma 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 "" -"```rust,ignore\n" -"match expressao {\n" -" Ok(valor) => valor,\n" -" Err(err) => return Err(From::from(err)),\n" -"}\n" -"```" - #: src/error-handling/converting-error-types.md:18 msgid "" "The `From::from` call here means we attempt to convert the error type to the " @@ -13668,100 +9956,20 @@ msgstr "" "A chamada `From::from` aqui significa que tentamos converter o tipo de erro " "para o tipo retornado pela função:" -#: 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" -"```" -msgstr "" -"```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 LerNomeUsuarioErro {\n" -" ErroEs(io::Error),\n" -" NomeUsuarioVazio(String),\n" -"}\n" -"\n" -"impl Error for LerNomeUsuarioErro {}\n" -"\n" -"impl Display for LerNomeUsuarioErro {\n" -" fn fmt(&self, f: &mut Formatter) -> fmt::Result {\n" -" match self {\n" -" Self::ErroEs(e) => write!(f, \"Erro E/S: {e}\"),\n" -" Self::NomeUsuarioVazio(nome_arquivo) => write!(f, \"Nome de " -"usuário não encontrado em {nome_arquivo}\"),\n" -" }\n" -" }\n" -"}\n" -"\n" -"impl From for LerNomeUsuarioErro {\n" -" fn from(err: io::Error) -> LerNomeUsuarioErro {\n" -" LerNomeUsuarioErro::ErroEs(err)\n" -" }\n" -"}\n" -"\n" -"fn ler_nome_usuario(caminho: &str) -> Result {\n" -" let mut nome_usuario = String::with_capacity(100);\n" -" File::open(caminho)?.read_to_string(&mut nome_usuario)?;\n" -" if nome_usuario.is_empty() {\n" -" return Err(LerNomeUsuarioErro::NomeUsuarioVazio(String::" -"from(caminho)));\n" -" }\n" -" Ok(nome_usuario)\n" -"}\n" -"\n" -"fn main() {\n" -" //fs::write(\"config.dat\", \"\").unwrap();\n" -" let nome_usuario = ler_nome_usuario(\"config.dat\");\n" -" println!(\"nome_usuario ou erro: {nome_usuario:?}\");\n" -"}\n" -"```" +#: src/error-handling/converting-error-types-example.md:20 +msgid "\"IO error: {e}\"" +msgstr "\"Erro E/S: {e}\"" + +#: src/error-handling/converting-error-types-example.md:21 +msgid "\"Found no username in {filename}\"" +msgstr "\"Nome de usuário não encontrado em {nome_arquivo}\"" + +#: 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 "//fs::write(\"config.dat\", \"\").unwrap();\n" #: src/error-handling/converting-error-types-example.md:55 msgid "" @@ -13795,70 +10003,25 @@ msgstr "" "O _crate_ [thiserror](https://docs.rs/thiserror/) é uma maneira popular de " "criar um tipo enumerado (_enum_) de erro, como fizemos na 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" -"```" -msgstr "" -"```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 LerNomeUsuarioErro {\n" -" #[error(\"Não é possivel ler: {0}\")]\n" -" ErroES(#[from] io::Error),\n" -" #[error(\"Nome de usuário não encontrado em {0}\")]\n" -" NomeUsuarioVazio(String),\n" -"}\n" -"\n" -"fn ler_nome_usuario(caminho: &str) -> Result {\n" -" let mut nome_usuario = String::new();\n" -" fs::File::open(caminho)?.read_to_string(&mut nome_usuario)?;\n" -" if nome_usuario.is_empty() {\n" -" return Err(LerNomeUsuarioErro::NomeUsuarioVazio(String::" -"from(caminho)));\n" -" }\n" -" Ok(nome_usuario)\n" -"}\n" -"\n" -"fn main() {\n" -" //fs::write(\"config.dat\", \"\").unwrap();\n" -" match ler_nome_usuario(\"config.dat\") {\n" -" Ok(nome_usuario) => println!(\"Nome do usuário: {nome_usuario}\"),\n" -" Err(err) => println!(\"Erro: {err}\"),\n" -" }\n" -"}\n" -"```" +#: src/error-handling/deriving-error-enums.md:13 +msgid "\"Could not read: {0}\"" +msgstr "\"Não é possivel ler: {0}\"" + +#: src/error-handling/deriving-error-enums.md:15 +#: src/error-handling/dynamic-errors.md:13 +msgid "\"Found no username in {0}\"" +msgstr "\"Nome de usuário não encontrado em {0}\"" + +#: 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 "\"Nome do usuário: {nome_usuario}\"" + +#: src/error-handling/deriving-error-enums.md:32 +#: src/error-handling/dynamic-errors.md:29 +msgid "\"Error: {err}\"" +msgstr "\"Erro: {err}\"" #: src/error-handling/deriving-error-enums.md:39 msgid "" @@ -13885,64 +10048,6 @@ msgstr "" "escrever nosso próprio `Enum` abrangendo todas as diferentes possibilidades. " "`std::error::Error` torna isso fácil." -#: 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 "" -"```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(\"Nome de usuário não encontrado em {0}\")]\n" -"struct NomeUsuarioVazioErro(String);\n" -"\n" -"fn ler_nome_usuario(path: &str) -> Result> {\n" -" let mut nome_usuario = String::new();\n" -" fs::File::open(path)?.read_to_string(&mut nome_usuario)?;\n" -" if nome_usuario.is_empty() {\n" -" return Err(NomeUsuarioVazioErro(String::from(path)).into());\n" -" }\n" -" Ok(nome_usuario)\n" -"}\n" -"\n" -"fn main() {\n" -" //fs::write(\"config.dat\", \"\").unwrap();\n" -" match ler_nome_usuario(\"config.dat\") {\n" -" Ok(nome_usuario) => println!(\"nome_usuario: {nome_usuario}\"),\n" -" Err(err) => println!(\"Erro: {err}\"),\n" -" }\n" -"}\n" -"```" - #: src/error-handling/dynamic-errors.md:36 msgid "" "This saves on code, but gives up the ability to cleanly handle different " @@ -13967,59 +10072,21 @@ msgstr "" "ajudar a adicionar informações contextuais aos seus erros, permitindo que " "você tenha menos tipos de erros 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" -"```" -msgstr "" -"```rust,editable,compile_fail\n" -"use std::{fs, io};\n" -"use std::io::Read;\n" -"use anyhow::{Context, Result, bail};\n" -"\n" -"fn ler_nome_usuario(caminho: &str) -> Result {\n" -" let mut nome_usuario = String::with_capacity(100);\n" -" fs::File::open(caminho)\n" -" .with_context(|| format!(\"Falha ao abrir {caminho}\"))?\n" -" .read_to_string(&mut nome_usuario)\n" -" .context(\"Falha ao ler\")?;\n" -" if nome_usuario.is_empty() {\n" -" bail!(\"Nome de usuário não encontrado em {caminho}\");\n" -" }\n" -" Ok(nome_usuario)\n" -"}\n" -"\n" -"fn main() {\n" -" //fs::write(\"config.dat\", \"\").unwrap();\n" -" match ler_nome_usuario(\"config.dat\") {\n" -" Ok(nome_usuario) => println!(\"nome_usuario: {nome_usuario}\"),\n" -" Err(err) => println!(\"Erro: {err:?}\"),\n" -" }\n" -"}\n" -"```" +#: src/error-handling/error-contexts.md:15 +msgid "\"Failed to open {path}\"" +msgstr "\"Falha ao abrir {caminho}\"" + +#: src/error-handling/error-contexts.md:17 +msgid "\"Failed to read\"" +msgstr "\"Falha ao ler\"" + +#: src/error-handling/error-contexts.md:19 +msgid "\"Found no username in {path}\"" +msgstr "\"Nome de usuário não encontrado em {caminho}\"" + +#: src/error-handling/error-contexts.md:28 +msgid "\"Error: {err:?}\"" +msgstr "\"Erro: {err:?}\"" #: src/error-handling/error-contexts.md:35 msgid "`anyhow::Result` is a type alias for `Result`." @@ -14068,55 +10135,9 @@ msgstr "Testes de integração são suportados através do diretório `tests/`." msgid "Mark unit tests with `#[test]`:" msgstr "Marque os testes unitários com `#[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 "" -"```rust,editable,ignore\n" -"fn primeira_palavra(texto: &str) -> &str {\n" -" match texto.find(' ') {\n" -" Some(idx) => &texto[..idx],\n" -" None => &texto,\n" -" }\n" -"}\n" -"\n" -"#[test]\n" -"fn teste_vazio() {\n" -" assert_eq!(primeira_palavra(\"\"), \"\");\n" -"}\n" -"\n" -"#[test]\n" -"fn teste_palavra_unica() {\n" -" assert_eq!(primeira_palavra(\"Hello\"), \"Hello\");\n" -"}\n" -"\n" -"#[test]\n" -"fn teste_palavras_multiplas() {\n" -" assert_eq!(primeira_palavra(\"Hello World\"), \"Hello\");\n" -"}\n" -"```" +#: src/testing/unit-tests.md:25 +msgid "\"Hello World\"" +msgstr "\"Hello World\"" #: src/testing/unit-tests.md:29 msgid "Use `cargo test` to find and run the unit tests." @@ -14130,48 +10151,6 @@ msgstr "" "Testes unitários geralmente são colocados em um módulo aninhado (execute " "testes no [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" -"```" -msgstr "" -"```rust,editable\n" -"fn auxiliar(a: &str, b: &str) -> String {\n" -" format!(\"{a} {b}\")\n" -"}\n" -"\n" -"pub fn main() {\n" -" println!(\"{}\", auxiliar(\"Olá\", \"Mundo\"));\n" -"}\n" -"\n" -"#[cfg(test)]\n" -"mod tests {\n" -" use super::*;\n" -"\n" -" #[test]\n" -" fn teste_auxiliar() {\n" -" assert_eq!(auxiliar(\"foo\", \"bar\"), \"foo bar\");\n" -" }\n" -"}\n" -"```" - #: src/testing/test-modules.md:26 msgid "This lets you unit test private helpers." msgstr "Isso permite que você tenha testes unitários auxiliares privados." @@ -14186,9 +10165,8 @@ msgstr "" msgid "Rust has built-in support for documentation tests:" msgstr "Rust tem suporte embutido para testes de documentação:" -#: 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" @@ -14196,12 +10174,7 @@ msgid "" "/// 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 "" -"```rust\n" "/// Encurta uma string para o comprimento especificado.\n" "///\n" "/// ```\n" @@ -14209,10 +10182,6 @@ msgstr "" "/// assert_eq!(encurtar_string(\"Olá Mundo\", 4), \"Olá\");\n" "/// assert_eq!(encurtar_string(\"Olá Mundo\", 20), \"Olá Mundo\");\n" "/// ```\n" -"pub fn encurtar_string(s: &str, comprimento: usize) -> &str {\n" -" &s[..std::cmp::min(comprimento, s.len())]\n" -"}\n" -"```" #: src/testing/doc-tests.md:18 msgid "Code blocks in `///` comments are automatically seen as Rust code." @@ -14241,26 +10210,6 @@ msgstr "" msgid "Create a `.rs` file under `tests/`:" msgstr "Crie um arquivo `.rs` em `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 "" -"```rust,ignore\n" -"use minha_biblioteca::iniciar;\n" -"\n" -"#[test]\n" -"fn teste_iniciar() {\n" -" assert!(iniciar().is_ok());\n" -"}\n" -"```" - #: src/testing/integration-tests.md:16 msgid "These tests only have access to the public API of your crate." msgstr "Esses testes têm acesso somente à API pública do seu `crate`." @@ -14388,49 +10337,29 @@ msgstr "" msgid "Creating pointers is safe, but dereferencing them requires `unsafe`:" msgstr "Criar ponteiros é seguro, mas desreferenciá-los requer `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 "" -"```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" -" // Seguro porque r1 e r2 foram obtidos através de referências e logo é\n" +"// Seguro porque r1 e r2 foram obtidos através de referências e logo é\n" " // garantido que eles não sejam nulos e sejam propriamente alinhados, os " "objetos\n" " // cujas referências foram obtidas são válidos por\n" " // todo o bloco inseguro, e eles não sejam acessados tanto através das\n" " // referências ou concorrentemente através de outros ponteiros.\n" -" unsafe {\n" -" println!(\"r1 é: {}\", *r1);\n" -" *r1 = 10;\n" -" println!(\"r2 é: {}\", *r2);\n" -" }\n" -"}\n" -"```" + +#: src/unsafe/raw-pointers.md:18 +msgid "\"r1 is: {}\"" +msgstr "\"r1 é: {}\"" + +#: src/unsafe/raw-pointers.md:20 +msgid "\"r2 is: {}\"" +msgstr "\"r2 é: {}\"" #: src/unsafe/raw-pointers.md:27 msgid "" @@ -14489,23 +10418,13 @@ msgstr "" msgid "It is safe to read an immutable static variable:" msgstr "É seguro ler uma variável estática imutável:" -#: 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" -"```" -msgstr "" -"```rust,editable\n" -"static OLA_MUNDO: &str = \"Olá, mundo!\";\n" -"\n" -"fn main() {\n" -" println!(\"OLA_MUNDO: {OLA_MUNDO}\");\n" -"}\n" -"```" +#: src/unsafe/mutable-static-variables.md:6 +msgid "\"Hello, world!\"" +msgstr "\"Olá, mundo!\"" + +#: src/unsafe/mutable-static-variables.md:9 +msgid "\"HELLO_WORLD: {HELLO_WORLD}\"" +msgstr "\"OLA_MUNDO: {OLA_MUNDO}\"" #: src/unsafe/mutable-static-variables.md:13 msgid "" @@ -14515,36 +10434,14 @@ msgstr "" "No entanto, como podem ocorrer corridas de dados, não é seguro ler e gravar " "dados em variáveis estáticas mutáveis:" -#: 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" -"```" -msgstr "" -"```rust,editable\n" -"static mut CONTADOR: u32 = 0;\n" -"\n" -"fn adicionar_ao_contador(inc: u32) {\n" -" unsafe { CONTADOR += inc; } // Corrida de dados potencial!\n" -"}\n" -"\n" -"fn main() {\n" -" adicionar_ao_contador(42);\n" -"\n" -" unsafe { println!(\"CONTADOR: {CONTADOR}\"); } // Corrida de dados " -"potencial!\n" -"}\n" -"```" +#: src/unsafe/mutable-static-variables.md:20 +#: src/unsafe/mutable-static-variables.md:26 +msgid "// Potential data race!\n" +msgstr "// Corrida de dados potencial!\n" + +#: src/unsafe/mutable-static-variables.md:26 +msgid "\"COUNTER: {COUNTER}\"" +msgstr "\"CONTADOR: {CONTADOR}\"" #: src/unsafe/mutable-static-variables.md:32 msgid "" @@ -14561,35 +10458,17 @@ msgid "Unions are like enums, but you need to track the active field yourself:" msgstr "" "_Unions_ são como _enums_, mas você mesmo precisa rastrear o campo ativo:" -#: 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" -"```" -msgstr "" -"```rust,editable\n" -"#[repr(C)]\n" -"union MinhaUnion {\n" -" i: u8,\n" -" b: bool,\n" -"}\n" -"\n" -"fn main() {\n" -" let u = MinhaUnion { i: 42 };\n" -" println!(\"int: {}\", unsafe { u.i });\n" -" println!(\"bool: {}\", unsafe { u.b }); // Comportamento indefinido!\n" -"}\n" -"```" +#: src/unsafe/unions.md:14 +msgid "\"int: {}\"" +msgstr "\"int: {}\"" + +#: src/unsafe/unions.md:15 +msgid "\"bool: {}\"" +msgstr "\"bool: {}\"" + +#: src/unsafe/unions.md:15 +msgid "// Undefined behavior!\n" +msgstr "// Comportamento indefinido!\n" #: src/unsafe/unions.md:21 msgid "" @@ -14620,62 +10499,40 @@ msgstr "" "Uma função ou método pode ser marcado como `unsafe` se houver pré-condições " "extras que você deve respeitar para evitar comportamento 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 "" +"// Seguro porque os índices estão na ordem correta, dentro dos limites da\n" +" // slice da string, e contido dentro da sequência UTF-8.\n" + +#: src/unsafe/calling-unsafe-functions.md:13 +#: src/unsafe/calling-unsafe-functions.md:14 +#: src/unsafe/calling-unsafe-functions.md:15 +msgid "\"emoji: {}\"" +msgstr "\"emoji: {}\"" + +#: src/unsafe/calling-unsafe-functions.md:18 +msgid "\"char count: {}\"" +msgstr "\"contador de caracteres: {}\"" + +#: 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 "" -"```rust,editable\n" -"fn main() {\n" -" let emojis = \"🗻∈🌏\";\n" -"\n" -" // Seguro porque os índices estão na ordem correta, dentro dos limites " -"da\n" -" // slice da string, e contido dentro da sequência UTF-8.\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!(\"contador de caracteres: {}\", contador_caracteres(unsafe " -"{ emojis.get_unchecked(0..7) }));\n" -"\n" -" // Não manter o requerimento de codificação UTF-8 viola segurança de " +"// Não manter o requerimento de codificação UTF-8 viola segurança de " "memória!\n" " // println!(\"emoji: {}\", unsafe { emojis.get_unchecked(0..3) });\n" " // println!(\"contador caracter: {}\", contador_caracteres(unsafe " "{ emojis.get_unchecked(0..3) }));\n" -"}\n" -"\n" -"fn contador_caracteres(s: &str) -> usize {\n" -" s.chars().map(|_| 1).sum()\n" -"}\n" -"```" #: src/unsafe/writing-unsafe-functions.md:3 msgid "" @@ -14685,57 +10542,27 @@ msgstr "" "Você pode marcar suas próprias funções como _inseguras_ (`unsafe`) se elas " "exigirem condições específicas para evitar comportamentos indefinidos." -#: 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 "" -"```rust,editable\n" "/// Troca os valores apontadoes pelos ponteiros fornecidos.\n" "///\n" "/// # Segurança\n" "///\n" "/// Os ponteiros precisam ser válidos e corretamente alinhados.\n" -"unsafe fn trocar(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" -" // Seguro porque ...\n" -" unsafe {\n" -" trocar(&mut a, &mut b);\n" -" }\n" -"\n" -" println!(\"a = {}, b = {}\", a, b);\n" -"}\n" -"```" + +#: src/unsafe/writing-unsafe-functions.md:22 +msgid "// Safe because ...\n" +msgstr "// Seguro porque ...\n" + +#: src/unsafe/writing-unsafe-functions.md:27 +msgid "\"a = {}, b = {}\"" +msgstr "\"a = {}, b = {}\"" #: src/unsafe/writing-unsafe-functions.md:33 msgid "" @@ -14767,33 +10594,33 @@ msgstr "" "Funções de outras linguagens podem violar as garantias do Rust. Logo, chamá-" "las é inseguro:" -#: 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" -"```" -msgstr "" -"```rust,editable\n" -"extern \"C\" {\n" -" fn abs(entrada: i32) -> i32;\n" -"}\n" -"\n" -"fn main() {\n" -" unsafe {\n" -" // Comportamento indefinido se abs se comportar mal.\n" -" println!(\"Valor absoluto de -3 de acordo com 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/bare-metal/aps/exceptions.md:14 +#: src/bare-metal/aps/exceptions.md:20 src/bare-metal/aps/exceptions.md:26 +#: src/bare-metal/aps/exceptions.md:32 src/bare-metal/aps/exceptions.md:38 +#: src/bare-metal/aps/exceptions.md:44 src/bare-metal/aps/exceptions.md:50 +#: src/bare-metal/aps/exceptions.md:56 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:60 +#: src/exercises/bare-metal/solutions-afternoon.md:62 +msgid "\"C\"" +msgstr "\"C\"" + +#: src/unsafe/extern-functions.md:13 +msgid "// Undefined behavior if abs misbehaves.\n" +msgstr "// Comportamento indefinido se abs se comportar mal.\n" + +#: src/unsafe/extern-functions.md:14 +msgid "\"Absolute value of -3 according to C: {}\"" +msgstr "\"Valor absoluto de -3 de acordo com C: {}\"" #: src/unsafe/extern-functions.md:21 msgid "" @@ -14831,47 +10658,20 @@ msgstr "" "Por exemplo, o _crate_ `zerocopy` tem um _trait_ inseguro que parece [algo " "assim](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 "" -"```rust,editable\n" -"use std::mem::size_of_val;\n" -"use std::slice;\n" -"\n" "/// ...\n" "/// # Segurança\n" "/// O tipo precisa ter uma representação definida e nenhum preenchimento.\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" + +#: src/unsafe/unsafe-traits.md:23 +msgid "// Safe because u32 has a defined representation and no padding.\n" +msgstr "" "// Seguro porque u32 possui uma representação definida e sem preenchimento.\n" -"unsafe impl AsBytes for u32 {}\n" -"```" #: src/unsafe/unsafe-traits.md:30 msgid "" @@ -15086,163 +10886,59 @@ msgstr "" "Copie o código abaixo para e implemente as " "funções e métodos que faltam:" -#: src/exercises/day-3/safe-ffi-wrapper.md:48 -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" +#: 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:25 +#: src/exercises/day-3/solutions-afternoon.md:38 +#: src/exercises/day-3/solutions-afternoon.md:49 +#: src/exercises/day-3/solutions-afternoon.md:63 +#: src/exercises/day-3/solutions-afternoon.md:71 +msgid "\"macos\"" +msgstr "\"macos\"" + +#: src/exercises/day-3/safe-ffi-wrapper.md:57 +#: src/exercises/day-3/solutions-afternoon.md:28 +msgid "// Opaque type. See https://doc.rust-lang.org/nomicon/ffi.html.\n" +msgstr "// Tipo opaco. Veja https://doc.rust-lang.org/nomicon/ffi.html.\n" + +#: src/exercises/day-3/safe-ffi-wrapper.md:64 +#: src/exercises/day-3/solutions-afternoon.md:35 +msgid "" +"// 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 "" +"// Layout de acordo com a página man do Linux para readdir(3), onde ino_t e\n" +" // off_t são resolvidos de acordo com as definições em\n" +" // /usr/include/x86_64-linux-gnu/{sys/types.h, bits/typesizes.h}.\n" + +#: src/exercises/day-3/safe-ffi-wrapper.md:77 +#: src/exercises/day-3/solutions-afternoon.md:48 +msgid "// Layout according to the macOS man page for dir(5).\n" +msgstr "// Layout de acordo com a página man do macOS man page para dir(5).\n" + +#: 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:63 +#: src/exercises/day-3/solutions-afternoon.md:71 +msgid "\"x86_64\"" +msgstr "\"x86_64\"" + +#: src/exercises/day-3/safe-ffi-wrapper.md:95 +#: src/exercises/day-3/solutions-afternoon.md:66 +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" -" // 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 "" -"```rust,should_panic\n" -"// TODO: remova isto com estiver terminado com sua implementação.\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" -" // Tipo opaco. Veja 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 de acordo com a página man do Linux para readdir(3), onde " -"ino_t e\n" -" // off_t são resolvidos de acordo com as definições em\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 de acordo com a página man do macOS man page para 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" -" // Veja https://github.com/rust-lang/libc/issues/414 e a seção " -"sobre\n" +"// Veja https://github.com/rust-lang/libc/issues/414 e a seção sobre\n" " // _DARWIN_FEATURE_64_BIT_INODE na página man do macOS para " "stat(2).\n" " //\n" @@ -15250,53 +10946,41 @@ msgstr "" "disponíveis\" refere-se\n" " // ao macOS (ao contrário do iOS / wearOS / etc.) em Intel e " "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" -" // Chama opendir e retorna um valor Ok se funcionar,\n" + +#: src/exercises/day-3/safe-ffi-wrapper.md:101 +#: src/exercises/day-3/solutions-afternoon.md:72 +msgid "\"readdir$INODE64\"" +msgstr "\"readdir$INODE64\"" + +#: src/exercises/day-3/safe-ffi-wrapper.md:119 +msgid "" +"// Call opendir and return a Ok value if that worked,\n" +" // otherwise return Err with a message.\n" +msgstr "" +"// Chama opendir e retorna um valor Ok se funcionar,\n" " // ou retorna Err com uma mensagem.\n" -" unimplemented!()\n" -" }\n" -"}\n" -"\n" -"impl Iterator for DirectoryIterator {\n" -" type Item = OsString;\n" -" fn next(&mut self) -> Option {\n" -" // Continua chamando readdir até nós obtermos um ponteiro NULL de " -"volta.\n" -" unimplemented!()\n" -" }\n" -"}\n" -"\n" -"impl Drop for DirectoryIterator {\n" -" fn drop(&mut self) {\n" -" // Chama closedir se necessário.\n" -" unimplemented!()\n" -" }\n" -"}\n" -"\n" -"fn main() -> Result<(), String> {\n" -" let iter = DirectoryIterator::new(\".\")?;\n" -" println!(\"files: {:#?}\", iter.collect::>());\n" -" Ok(())\n" -"}\n" -"```" + +#: src/exercises/day-3/safe-ffi-wrapper.md:128 +msgid "// Keep calling readdir until we get a NULL pointer back.\n" +msgstr "" +"// Continua chamando readdir até nós obtermos um ponteiro NULL de volta.\n" + +#: src/exercises/day-3/safe-ffi-wrapper.md:135 +msgid "// Call closedir as needed.\n" +msgstr "// Chama closedir se necessário.\n" + +#: src/exercises/day-3/safe-ffi-wrapper.md:141 +#: src/android/interoperability/with-c/rust.md:44 +#: src/exercises/day-3/solutions-afternoon.md:142 +#: src/exercises/day-3/solutions-afternoon.md:167 +#: src/exercises/day-3/solutions-afternoon.md:182 +msgid "\".\"" +msgstr "\".\"" + +#: src/exercises/day-3/safe-ffi-wrapper.md:142 +#: src/exercises/day-3/solutions-afternoon.md:143 +msgid "\"files: {:#?}\"" +msgstr "\"files: {:#?}\"" #: src/android.md:1 msgid "Welcome to Rust in Android" @@ -15332,20 +11016,6 @@ msgstr "" "Iremos usar o um dispositivo virtual Android para testar nosso código. " "Assegure-se de ter acesso a um ou crie um novo com:" -#: 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 "" -"```shell\n" -"source build/envsetup.sh\n" -"lunch aosp_cf_x86_64_phone-userdebug\n" -"acloud create\n" -"```" - #: src/android/setup.md:12 msgid "" "Please see the [Android Developer Codelab](https://source.android.com/docs/" @@ -15470,47 +11140,30 @@ 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" -"```" -msgstr "" -"```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 "\"hello_rust\"" + +#: src/android/build-rules/binary.md:12 src/android/build-rules/library.md:19 +#: src/android/logging.md:12 +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" -"```" -msgstr "" -"```rust\n" -"//! Rust demo.\n" -"\n" -"/// Imprime uma saudação na saída padrão.\n" -"fn main() {\n" -" println!(\"Olá do Rust!\");\n" -"}\n" -"```" +#: src/android/build-rules/binary.md:19 src/android/build-rules/library.md:37 +msgid "//! Rust demo.\n" +msgstr "//! Rust demo.\n" + +#: src/android/build-rules/binary.md:20 src/android/build-rules/library.md:41 +msgid "/// Prints a greeting to standard output.\n" +msgstr "/// Imprime uma saudação na saída padrão.\n" + +#: src/android/build-rules/binary.md:23 +msgid "\"Hello from Rust!\"" +msgstr "\"Olá do Rust!\"" #: src/android/build-rules/binary.md:27 msgid "You can now build, push, and run the binary:" @@ -15530,16 +11183,6 @@ msgstr "" "adb shell /data/local/tmp/hello_rust\n" "```" -#: src/android/build-rules/binary.md:35 -msgid "" -"```text\n" -"Hello from Rust!\n" -"```" -msgstr "" -"```text\n" -"Olá do Rust!\n" -"```" - #: src/android/build-rules/library.md:1 msgid "Rust Libraries" msgstr "Bibliotecas de Rust" @@ -15567,95 +11210,42 @@ 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" -"```" -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:17 src/android/build-rules/library.md:18 +msgid "\"hello_rust_with_dep\"" +msgstr "\"hello_rust_with_dep\"" -#: 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" -"```" -msgstr "" -"```rust,ignore\n" -"//! Rust demo.\n" -"\n" -"use greetings::greeting;\n" -"use textwrap::fill;\n" -"\n" -"/// Imprime uma saudação na saída padrão.\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 "\"libgreetings\"" + +#: src/android/build-rules/library.md:22 +msgid "\"libtextwrap\"" +msgstr "\"libtextwrap\"" + +#: src/android/build-rules/library.md:29 +msgid "\"greetings\"" +msgstr "\"greetings\"" + +#: src/android/build-rules/library.md:30 src/android/aidl/implementation.md:31 +#: src/android/interoperability/java.md:38 +msgid "\"src/lib.rs\"" +msgstr "\"src/lib.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" -"```" -msgstr "" -"```rust,ignore\n" -"//! Greeting library.\n" -"\n" -"/// Saudação `nome`.\n" -"pub fn greeting(nome: &str) -> String {\n" -" format!(\"Olá {nome}, prazer em conhecê-lo!\")\n" -"}\n" -"```" +#: src/android/build-rules/library.md:51 +msgid "//! Greeting library.\n" +msgstr "//! Greeting library.\n" + +#: src/android/build-rules/library.md:52 +msgid "/// Greet `name`.\n" +msgstr "/// Saudação `nome`.\n" + +#: src/android/build-rules/library.md:55 +msgid "\"Hello {name}, it is very nice to meet you!\"" +msgstr "\"Olá {nome}, prazer em conhecê-lo!\"" #: src/android/build-rules/library.md:59 msgid "You build, push, and run the binary like before:" @@ -15677,18 +11267,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" -"Olá Bob, prazer em conhecê-lo!\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:" @@ -15718,59 +11297,29 @@ 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" -"```" -msgstr "" -"```java\n" -"package com.example.birthdayservice;\n" -"\n" -"/** Interface de serviço de aniversário. */\n" -"interface IBirthdayService {\n" -" /** Gera uma mensagem de feliz aniversário. */\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 "/** Interface de serviço de aniversário. */" + +#: src/android/aidl/interface.md:12 src/android/aidl/changing.md:11 +msgid "/** Generate a Happy Birthday message. */" +msgstr "/** Gera uma mensagem de feliz aniversário. */" #: 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" -"```" -msgstr "" -"```javascript\n" -"aidl_interface {\n" -" name: \"com.example.birthdayservice\",\n" -" srcs: [\"com/example/birthdayservice/*.aidl\"],\n" -" unstable: true,\n" -" backend: {\n" -" rust: { // Rust não está ativado por padrão\n" -" enabled: true,\n" -" },\n" -" },\n" -"}\n" -"```" +#: src/android/aidl/interface.md:21 +msgid "\"com.example.birthdayservice\"" +msgstr "\"com.example.birthdayservice\"" + +#: src/android/aidl/interface.md:22 +msgid "\"com/example/birthdayservice/*.aidl\"" +msgstr "\"com/example/birthdayservice/*.aidl\"" + +#: src/android/aidl/interface.md:25 +msgid "// Rust is not enabled by default\n" +msgstr "// Rust não está ativado por padrão\n" #: src/android/aidl/interface.md:32 msgid "" @@ -15792,81 +11341,41 @@ msgstr "Agora podemos implementar o serviço 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" -"```" -msgstr "" -"```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" -"/// A implementação de `IBirthdayService`.\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" -" \"Feliz aniversário {name}, parabéns pelos seus {years} anos!\"\n" -" ))\n" -" }\n" -"}\n" -"```" +#: src/android/aidl/implementation.md:8 +msgid "//! Implementation of the `IBirthdayService` AIDL interface.\n" +msgstr "//! Implementation of the `IBirthdayService` AIDL interface.\n" + +#: src/android/aidl/implementation.md:11 +msgid "/// The `IBirthdayService` implementation.\n" +msgstr "/// A implementação de `IBirthdayService`.\n" + +#: src/android/aidl/implementation.md:20 +msgid "\"Happy Birthday {name}, congratulations with the {years} years!\"" +msgstr "\"Feliz aniversário {name}, parabéns pelos seus {years} anos!\"" #: src/android/aidl/implementation.md:26 src/android/aidl/server.md:28 #: src/android/aidl/client.md:37 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" -"```" -msgstr "" -"```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 +msgid "\"libbirthdayservice\"" +msgstr "\"libbirthdayservice\"" + +#: src/android/aidl/implementation.md:32 src/android/aidl/server.md:13 +#: src/android/aidl/client.md:12 +msgid "\"birthdayservice\"" +msgstr "\"birthdayservice\"" + +#: src/android/aidl/implementation.md:34 src/android/aidl/server.md:36 +#: src/android/aidl/client.md:45 +msgid "\"com.example.birthdayservice-rust\"" +msgstr "\"com.example.birthdayservice-rust\"" + +#: src/android/aidl/implementation.md:35 src/android/aidl/server.md:37 +#: src/android/aidl/client.md:46 +msgid "\"libbinder_rs\"" +msgstr "\"libbinder_rs\"" #: src/android/aidl/server.md:1 msgid "AIDL Server" @@ -15880,83 +11389,25 @@ msgstr "Finalmente, podemos criar um servidor que expõe o serviço:" 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" -"```" -msgstr "" -"```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" -"/// Ponto de entrada para serviço de aniversário.\n" -"fn main() {\n" -" let birthday_service = BirthdayService;\n" -" let birthday_service_binder = BnBirthdayService::new_binder(\n" -" birthday_server,\n" -" binder::BinderFeatures::default(),\n" -" );\n" -" binder::add_service(SERVICE_IDENTIFIER, birthday_service_binder." -"as_binder())\n" -" .expect(\"Falha ao registrar o serviço\");\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 "//! Birthday service.\n" -#: 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" -"```" -msgstr "" -"```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 "/// Ponto de entrada para serviço de aniversário.\n" + +#: src/android/aidl/server.md:23 +msgid "\"Failed to register service\"" +msgstr "\"Falha ao registrar o serviço\"" + +#: src/android/aidl/server.md:32 src/android/aidl/server.md:33 +msgid "\"birthday_server\"" +msgstr "\"birthday_server\"" + +#: src/android/aidl/server.md:34 +msgid "\"src/server.rs\"" +msgstr "\"src/server.rs\"" #: src/android/aidl/deploy.md:3 msgid "We can now build, push, and start the service:" @@ -15982,66 +11433,10 @@ msgstr "" msgid "In another terminal, check that the service runs:" msgstr "Em outro terminal, verifique se o serviço está sendo executado:" -#: src/android/aidl/deploy.md:13 -msgid "" -"```shell\n" -"adb shell service check birthdayservice\n" -"```" -msgstr "" -"```shell\n" -"adb shell service check birthdayservice\n" -"```" - -#: src/android/aidl/deploy.md:17 -msgid "" -"```text\n" -"Service birthdayservice: found\n" -"```" -msgstr "" -"```text\n" -"Service birthdayservice: found\n" -"```" - #: src/android/aidl/deploy.md:21 msgid "You can also call the service with `service call`:" msgstr "Você também pode chamar o serviço com `service call`:" -#: src/android/aidl/deploy.md:23 -msgid "" -"```shell\n" -"adb shell service call birthdayservice 1 s16 Bob i32 24\n" -"```" -msgstr "" -"```shell\n" -"adb shell service call birthdayservice 1 s16 Bob i32 24\n" -"```" - -#: 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 "" -"```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" -"```" - #: src/android/aidl/client.md:1 msgid "AIDL Client" msgstr "Cliente AIDL" @@ -16054,101 +11449,29 @@ msgstr "Por fim, podemos criar um cliente Rust para nosso novo serviço." msgid "_birthday_service/src/client.rs_:" msgstr "_birthday_server/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" -"```" -msgstr "" -"```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" -"/// Connecta-se ao serviço de aniversário BirthdayService.\n" -"pub fn connect() -> Result, binder::" -"StatusCode> {\n" -" binder::get_interface(SERVICE_IDENTIFIER)\n" -"}\n" -"\n" -"/// Chama o serviço de aniversário.\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(\"Falha ao conectar-se a " -"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 "/// Connecta-se ao serviço de aniversário BirthdayService.\n" -#: 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" -"```" -msgstr "" -"```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" -" prefere_rlib: true,\n" -"}\n" -"```" +#: src/android/aidl/client.md:18 +msgid "/// Call the birthday service.\n" +msgstr "/// Chama o serviço de aniversário.\n" + +#: src/android/aidl/client.md:30 +msgid "\"Failed to connect to BirthdayService\"" +msgstr "\"Falha ao conectar-se a BirthdayService\"" + +#: src/android/aidl/client.md:32 +msgid "\"{msg}\"" +msgstr "\"{msg}\"" + +#: src/android/aidl/client.md:41 src/android/aidl/client.md:42 +msgid "\"birthday_client\"" +msgstr "\"birthday_client\"" + +#: src/android/aidl/client.md:43 +msgid "\"src/client.rs\"" +msgstr "\"src/client.rs\"" #: src/android/aidl/client.md:52 msgid "Notice that the client does not depend on `libbirthdayservice`." @@ -16174,16 +11497,6 @@ msgstr "" "adb shell /data/local/tmp/birthday_client Carlos 60\n" "```" -#: src/android/aidl/client.md:62 -msgid "" -"```text\n" -"Happy Birthday Charlie, congratulations with the 60 years!\n" -"```" -msgstr "" -"```text\n" -"Feliz aniversário Carlos, parabéns pelos seus 60 anos!\n" -"```" - #: src/android/aidl/changing.md:3 msgid "" "Let us extend the API with more functionality: we want to let clients " @@ -16192,28 +11505,6 @@ msgstr "" "Vamos estender a API com mais funcionalidades: queremos permitir que os " "clientes especifiquem uma lista de frases para o cartão de aniversário:" -#: 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 "" -"```java\n" -"package com.example.birthdayservice;\n" -"\n" -"/** Interface de serviço de aniversário. */\n" -"interface IBirthdayService {\n" -" /** Gera uma mensagem de feliz aniversário. */\n" -" String wishHappyBirthday(String name, int years, in String[] text);\n" -"}\n" -"```" - #: src/android/logging.md:3 msgid "" "You should use the `log` crate to automatically log to `logcat` (on-device) " @@ -16226,77 +11517,45 @@ 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" -"```" -msgstr "" -"```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 +msgid "\"hello_rust_logs\"" +msgstr "\"hello_rust_logs\"" + +#: src/android/logging.md:14 +msgid "\"liblog_rust\"" +msgstr "\"liblog_rust\"" + +#: src/android/logging.md:15 +msgid "\"liblogger\"" +msgstr "\"liblogger\"" #: 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" -"```" -msgstr "" -"```rust,ignore\n" -"//! Rust logging demo.\n" -"\n" -"use log::{debug, error, info};\n" -"\n" -"/// Registra uma saudação.\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!(\"Iniciando programa.\");\n" -" info!(\"As coisas estão indo bem.\");\n" -" error!(\"Algo deu errado!\");\n" -"}\n" -"```" +#: src/android/logging.md:25 +msgid "//! Rust logging demo.\n" +msgstr "//! Rust logging demo.\n" + +#: src/android/logging.md:28 +msgid "/// Logs a greeting.\n" +msgstr "/// Registra uma saudação.\n" + +#: src/android/logging.md:33 +msgid "\"rust\"" +msgstr "\"rust\"" + +#: src/android/logging.md:36 +msgid "\"Starting program.\"" +msgstr "\"Iniciando programa.\"" + +#: src/android/logging.md:37 +msgid "\"Things are going fine.\"" +msgstr "\"As coisas estão indo bem.\"" + +#: src/android/logging.md:38 +msgid "\"Something went wrong!\"" +msgstr "\"Algo deu errado!\"" #: src/android/logging.md:42 src/android/interoperability/with-c/bindgen.md:98 #: src/android/interoperability/with-c/rust.md:73 @@ -16323,33 +11582,6 @@ msgstr "" msgid "The logs show up in `adb logcat`:" msgstr "Os logs aparecem em `adb logcat`:" -#: src/android/logging.md:52 -msgid "" -"```shell\n" -"adb logcat -s rust\n" -"```" -msgstr "" -"```shell\n" -"adb logcat -s rust\n" -"```" - -#: 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 "" -"```text\n" -"09-08 08:38:32.454 2420 2420 D rust: hello_rust_logs: Iniciando o programa.\n" -"09-08 08:38:32.454 2420 2420 I rust: hello_rust_logs: As coisas estão indo " -"bem.\n" -"09-08 08:38:32.454 2420 2420 E rust: hello_rust_logs: Algo deu errado!\n" -"```" - #: src/android/interoperability.md:3 msgid "" "Rust has excellent support for interoperability with other languages. This " @@ -16391,31 +11623,9 @@ msgstr "" msgid "You can do it by hand if you want:" msgstr "Você pode fazer isso manualmente se quiser:" -#: 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" -"```" -msgstr "" -"```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 "\"{x}, {abs_x}\"" #: src/android/interoperability/with-c.md:20 msgid "" @@ -16458,55 +11668,31 @@ msgstr "Primeiro crie uma pequena biblioteca C:" 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 "" -"```c\n" -"typedef struct card {\n" -" const char* name;\n" -" int years;\n" -"} card;\n" -"\n" -"void print_card(const card* card);\n" -"```" - #: 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" -"```" -msgstr "" -"```c\n" -"#include \n" -"#include \"libbirthday.h\"\n" -"\n" -"void print_card(const card* card) {\n" -" printf(\"+--------------\\n\");\n" -" printf(\"|Feliz Aniversário %s!\\n\", card->nome);\n" -" printf(\"|Parabéns pelos %i anos!\\n\", card->anos);\n" -" printf(\"+--------------\\n\");\n" -"}\n" -"```" +#: src/android/interoperability/with-c/bindgen.md:22 +msgid "" +msgstr "" + +#: src/android/interoperability/with-c/bindgen.md:23 +#: src/android/interoperability/with-c/bindgen.md:50 +msgid "\"libbirthday.h\"" +msgstr "\"libbirthday.h\"" + +#: src/android/interoperability/with-c/bindgen.md:26 +#: src/android/interoperability/with-c/bindgen.md:29 +msgid "\"+--------------\\n\"" +msgstr "\"+--------------\\n\"" + +#: src/android/interoperability/with-c/bindgen.md:27 +msgid "\"| Happy Birthday %s!\\n\"" +msgstr "\"|Feliz Aniversário %s!\\n\"" + +#: src/android/interoperability/with-c/bindgen.md:28 +msgid "\"| Congratulations with the %i years!\\n\"" +msgstr "\"|Parabéns pelos %i anos!\\n\"" #: src/android/interoperability/with-c/bindgen.md:33 msgid "Add this to your `Android.bp` file:" @@ -16519,21 +11705,14 @@ msgstr "Adicione isto ao seu arquivo `Android.bp`:" msgid "_interoperability/bindgen/Android.bp_:" msgstr "_interoperability/bindgen/Android.bp_:" -#: src/android/interoperability/with-c/bindgen.md:37 -msgid "" -"```javascript\n" -"cc_library {\n" -" name: \"libbirthday\",\n" -" srcs: [\"libbirthday.c\"],\n" -"}\n" -"```" -msgstr "" -"```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 "\"libbirthday\"" + +#: src/android/interoperability/with-c/bindgen.md:40 +msgid "\"libbirthday.c\"" +msgstr "\"libbirthday.c\"" #: src/android/interoperability/with-c/bindgen.md:44 msgid "" @@ -16547,106 +11726,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 "" -"```c\n" -"#include \"libbirthday.h\"\n" -"```" - #: src/android/interoperability/with-c/bindgen.md:53 msgid "You can now auto-generate the bindings:" msgstr "Agora você pode gerar automaticamente as vinculações (_binding_):" -#: 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" -"```" -msgstr "" -"```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 "\"libbirthday_bindgen\"" + +#: src/android/interoperability/with-c/bindgen.md:60 +msgid "\"birthday_bindgen\"" +msgstr "\"birthday_bindgen\"" + +#: src/android/interoperability/with-c/bindgen.md:61 +msgid "\"libbirthday_wrapper.h\"" +msgstr "\"libbirthday_wrapper.h\"" + +#: src/android/interoperability/with-c/bindgen.md:62 +msgid "\"bindings\"" +msgstr "\"bindings\"" #: src/android/interoperability/with-c/bindgen.md:67 msgid "Finally, we can use the bindings in our Rust program:" msgstr "" "Finalmente, podemos usar as vinculações (_bindings_) em nosso programa 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" -"```" -msgstr "" -"```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 "\"print_birthday_card\"" + +#: src/android/interoperability/with-c/bindgen.md:74 +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" -"```" -msgstr "" -"```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(\"Pedro\").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:100 +#: src/android/interoperability/with-c/bindgen.md:82 +msgid "//! Bindgen demo.\n" +msgstr "//! Bindgen demo.\n" + +#: src/android/interoperability/with-c/bindgen.md:100 msgid "" "```shell\n" "m print_birthday_card\n" @@ -16668,41 +11790,27 @@ msgstr "" "Por fim, podemos executar testes gerados automaticamente para garantir que " "as vinculações funcionem:" -#: 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" -"```" -msgstr "" -"```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\", // Arquivo gerado, pule o 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 "\"libbirthday_bindgen_test\"" -#: src/android/interoperability/with-c/bindgen.md:122 -msgid "" -"```shell\n" -"atest libbirthday_bindgen_test\n" -"```" -msgstr "" -"```shell\n" -"atest libbirthday_bindgen_test\n" -"```" +#: src/android/interoperability/with-c/bindgen.md:113 +msgid "\":libbirthday_bindgen\"" +msgstr "\":libbirthday_bindgen\"" + +#: src/android/interoperability/with-c/bindgen.md:115 +msgid "\"general-tests\"" +msgstr "\"general-tests\"" + +#: src/android/interoperability/with-c/bindgen.md:117 +#: src/android/interoperability/with-c/bindgen.md:118 +msgid "\"none\"" +msgstr "\"none\"" + +#: src/android/interoperability/with-c/bindgen.md:117 +msgid "// Generated file, skip linting\n" +msgstr "// Arquivo gerado, pule o linting\n" #: src/android/interoperability/with-c/rust.md:1 msgid "Calling Rust" @@ -16716,93 +11824,42 @@ msgstr "Exportar funções e tipos do Rust para C é fácil:" 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" -"```" -msgstr "" -"```rust,editable\n" -"//! Rust FFI demo.\n" -"#![deny(improper_ctypes_definitions)]\n" -"\n" -"use std::os::raw::c_int;\n" -"\n" -"/// Analisar os números.\n" -"#[no_mangle]\n" -"pub extern \"C\" fn analyze_numbers(x: c_int, y: c_int) {\n" -" if x < y {\n" -" println!(\"x ({x}) é o menor!\");\n" -" } else {\n" -" println!(\"y ({y}) é provavelmente maior que x ({x})\");\n" -" }\n" -"}\n" -"```" +#: src/android/interoperability/with-c/rust.md:8 +msgid "//! Rust FFI demo.\n" +msgstr "//! Rust FFI demo.\n" + +#: src/android/interoperability/with-c/rust.md:12 +msgid "/// Analyze the numbers.\n" +msgstr "/// Analisar os números.\n" + +#: src/android/interoperability/with-c/rust.md:17 +msgid "\"x ({x}) is smallest!\"" +msgstr "\"x ({x}) é o menor!\"" + +#: src/android/interoperability/with-c/rust.md:19 +msgid "\"y ({y}) is probably larger than x ({x})\"" +msgstr "\"y ({y}) é provavelmente maior que x ({x})\"" #: 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 "" -"```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" -"```" - #: 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" -"```" -msgstr "" -"```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 "\"libanalyze_ffi\"" + +#: src/android/interoperability/with-c/rust.md:42 +msgid "\"analyze_ffi\"" +msgstr "\"analyze_ffi\"" + +#: src/android/interoperability/with-c/rust.md:43 +msgid "\"analyze.rs\"" +msgstr "\"analyze.rs\"" #: src/android/interoperability/with-c/rust.md:48 msgid "We can now call this from a C binary:" @@ -16812,49 +11869,21 @@ msgstr "Agora podemos chamá-lo a partir de um binário C:" msgid "_interoperability/rust/analyze/main.c_" msgstr "_interoperability/rust/analisar/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" -"```" -msgstr "" -"```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 "\"analyze.h\"" #: 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" -"```" -msgstr "" -"```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 "\"analyze_numbers\"" + +#: src/android/interoperability/with-c/rust.md:67 +msgid "\"main.c\"" +msgstr "\"main.c\"" #: src/android/interoperability/with-c/rust.md:75 msgid "" @@ -16960,74 +11989,40 @@ msgstr "Primeiro, criamos uma função Rust para exportar para 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" -"```" -msgstr "" -"```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" -"/// Implementação do método HelloWorld::hello.\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!(\"Olá, {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 "//! Rust <-> Java FFI demo.\n" + +#: src/android/interoperability/java.md:17 +msgid "/// HelloWorld::hello method implementation.\n" +msgstr "/// Implementação do método HelloWorld::hello.\n" + +#: src/android/interoperability/java.md:20 +msgid "\"system\"" +msgstr "\"system\"" + +#: src/android/interoperability/java.md:26 +msgid "\"Hello, {input}!\"" +msgstr "\"Olá, {input}!\"" #: src/android/interoperability/java.md:32 #: src/android/interoperability/java.md:62 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" -"```" -msgstr "" -"```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 "\"libhello_jni\"" + +#: src/android/interoperability/java.md:37 +#: src/android/interoperability/java.md:52 +msgid "\"hello_jni\"" +msgstr "\"hello_jni\"" + +#: src/android/interoperability/java.md:39 +msgid "\"libjni\"" +msgstr "\"libjni\"" #: src/android/interoperability/java.md:43 msgid "Finally, we can call this function from Java:" @@ -17037,76 +12032,22 @@ msgstr "Finalmente, podemos chamar esta função do 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" -"```" -msgstr "" -"```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 "\"helloworld_jni\"" -#: 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 "" -"```javascript\n" -"java_binary {\n" -" name: \"helloworld_jni\",\n" -" srcs: [\"HelloWorld.java\"],\n" -" main_class: \"HelloWorld\",\n" -" necessário: [\"libhello_jni\"],\n" -"}\n" -"```" +#: src/android/interoperability/java.md:67 +msgid "\"HelloWorld.java\"" +msgstr "\"HelloWorld.java\"" + +#: src/android/interoperability/java.md:68 +msgid "\"HelloWorld\"" +msgstr "\"HelloWorld\"" #: src/android/interoperability/java.md:73 msgid "Finally, you can build, sync, and run the binary:" msgstr "Por fim, você pode criar, sincronizar e executar o binário:" -#: 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 "" -"```shell\n" -"m helloworld_jni\n" -"adb sync # requer adb root && adb remount\n" -"adb shell /system/bin/helloworld_jni\n" -"```" - #: src/exercises/android/morning.md:3 msgid "" "This is a group exercise: We will look at one of the projects you work with " @@ -17180,50 +12121,21 @@ msgid "" "To get started, install some tools we'll need later. On gLinux or Debian:" msgstr "" -#: 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 "" - #: src/bare-metal.md:30 msgid "" "And give users in the `plugdev` group access to the micro:bit programmer:" msgstr "" -#: src/bare-metal.md:32 +#: src/bare-metal.md:33 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" -"```" +"'SUBSYSTEM==\"usb\", ATTR{idVendor}==\"0d28\", MODE=\"0664\", " +"GROUP=\"plugdev\"'" msgstr "" #: src/bare-metal.md:38 msgid "On MacOS:" msgstr "" -#: 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 "" - #: src/bare-metal/no_std.md:1 msgid "`no_std`" msgstr "" @@ -17336,21 +12248,6 @@ msgstr "" msgid "A minimal `no_std` program" msgstr "" -#: 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 "" - #: src/bare-metal/minimal.md:17 msgid "This will compile to an empty binary." msgstr "" @@ -17382,39 +12279,21 @@ msgid "" "rust-lang.org/stable/std/alloc/trait.GlobalAlloc.html)." msgstr "" -#: 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 "" + +#: src/bare-metal/alloc.md:33 +msgid "\"A string\"" msgstr "" #: src/bare-metal/alloc.md:39 @@ -17453,25 +12332,6 @@ msgid "" "Cortex M microcontrollers." msgstr "" -#: 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 " @@ -17494,69 +12354,35 @@ msgid "" "turning on an LED on our micro:bit:" msgstr "" -#: 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 @@ -17572,17 +12398,6 @@ msgstr "" msgid "Run the example with:" msgstr "" -#: src/bare-metal/microcontrollers/mmio.md:68 -#, fuzzy -msgid "" -"```sh\n" -"cargo embed --bin mmio\n" -"```" -msgstr "" -"```shell\n" -"$ cargo run\n" -"```" - #: src/bare-metal/microcontrollers/pacs.md:1 msgid "Peripheral Access Crates" msgstr "" @@ -17594,49 +12409,6 @@ msgid "" "pack/doc/CMSIS/SVD/html/index.html) files." msgstr "" -#: 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 " @@ -17666,17 +12438,6 @@ msgid "" "pac -- -d --no-show-raw-insn` to see the resulting binary." msgstr "" -#: src/bare-metal/microcontrollers/pacs.md:61 -#, fuzzy -msgid "" -"```sh\n" -"cargo embed --bin pac\n" -"```" -msgstr "" -"```shell\n" -"$ cargo run\n" -"```" - #: src/bare-metal/microcontrollers/hals.md:1 msgid "HAL crates" msgstr "" @@ -17689,37 +12450,8 @@ msgid "" "(https://crates.io/crates/embedded-hal)." msgstr "" -#: 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 @@ -17733,17 +12465,6 @@ msgid "" "STM32, GD32, nRF, NXP, MSP430, AVR and PIC microcontrollers." msgstr "" -#: src/bare-metal/microcontrollers/hals.md:45 -#, fuzzy -msgid "" -"```sh\n" -"cargo embed --bin hal\n" -"```" -msgstr "" -"```shell\n" -"$ cargo run\n" -"```" - #: src/bare-metal/microcontrollers/board-support.md:1 msgid "Board support crates" msgstr "Atalhos de teclado" @@ -17754,30 +12475,6 @@ msgid "" "board for convenience." msgstr "" -#: 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, " @@ -17794,48 +12491,16 @@ msgstr "" msgid "`microbit-v2` includes a simple driver for the LED matrix." msgstr "" -#: 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 "" -#: 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 @@ -17937,7 +12602,7 @@ msgid "SWD" msgstr "" #: src/bare-metal/microcontrollers/probe-rs.md:6 -msgid " and JTAG via CMSIS-DAP, ST-Link and J-Link probes" +msgid "and JTAG via CMSIS-DAP, ST-Link and J-Link probes" msgstr "" #: src/bare-metal/microcontrollers/probe-rs.md:7 @@ -17949,7 +12614,7 @@ msgid "DAP" msgstr "" #: src/bare-metal/microcontrollers/probe-rs.md:7 -msgid " server" +msgid "server" msgstr "" #: src/bare-metal/microcontrollers/probe-rs.md:8 @@ -17966,7 +12631,7 @@ msgstr "" #: src/bare-metal/microcontrollers/probe-rs.md:11 msgid "" -" output and connect GDB. It's configured by an `Embed.toml` file in your " +"output and connect GDB. It's configured by an `Embed.toml` file in your " "project directory." msgstr "" @@ -18032,42 +12697,19 @@ msgstr "" msgid "In one terminal under `src/bare-metal/microcontrollers/examples/`:" msgstr "" -#: 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 #, fuzzy msgid "In another terminal in the same directory:" msgstr "Em outro terminal, verifique se o serviço é executado:" -#: 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" -"```" +#: src/bare-metal/microcontrollers/debugging.md:22 +msgid "\"target remote :1337\"" msgstr "" #: src/bare-metal/microcontrollers/debugging.md:27 msgid "In GDB, try running:" msgstr "" -#: 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" @@ -18219,41 +12861,26 @@ msgstr "" msgid "`src/main.rs`:" msgstr "_hello_rust/src/main.rs_:" -#: src/exercises/bare-metal/compass.md:30 +#: src/exercises/bare-metal/compass.md:44 +#: src/exercises/bare-metal/solutions-morning.md:49 +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" +msgstr "" + +#: src/exercises/bare-metal/compass.md:55 +#: src/exercises/bare-metal/solutions-morning.md:75 +msgid "\"Ready.\"" +msgstr "" + +#: src/exercises/bare-metal/compass.md:58 +msgid "" +"// 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 @@ -18317,25 +12944,11 @@ msgstr "" msgid "See the serial output on Linux with:" msgstr "" -#: 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):" msgstr "" -#: 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 "" @@ -18529,43 +13142,49 @@ msgid "HVC" msgstr "" #: src/bare-metal/aps/inline-assembly.md:4 -msgid " to tell the firmware to power off the system:" +msgid "to tell the firmware to power off the system:" msgstr "" -#: 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: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 @@ -18665,22 +13284,13 @@ msgid "" "documentation/ddi0183/g) UART, so let's write a driver for that." msgstr "" -#: 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" @@ -18690,34 +13300,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 @@ -18755,24 +13363,11 @@ msgid "" "traits too." msgstr "" -#: 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:267 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 @@ -18967,37 +13562,54 @@ msgid "" "working with bitflags." msgstr "" -#: 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 @@ -19015,43 +13627,6 @@ msgid "" "We can use a struct to represent the memory layout of the UART's registers." msgstr "" -#: 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-" @@ -19065,69 +13640,28 @@ msgstr "" msgid "Now let's use the new `Registers` struct in our driver." msgstr "" -#: 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 @@ -19148,51 +13682,40 @@ msgid "" "and echo incoming bytes." msgstr "" -#: 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:50 +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:63 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 @@ -19214,50 +13737,12 @@ msgid "" "`Log` trait." msgstr "" -#: 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 @@ -19270,47 +13755,9 @@ msgstr "" msgid "We need to initialise the logger before we use it." msgstr "" -#: 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:142 +msgid "\"{info}\"" msgstr "" #: src/bare-metal/aps/logging/using.md:46 @@ -19332,61 +13779,36 @@ msgid "" "calling into Rust code:" msgstr "" -#: 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" -"```" +#: src/bare-metal/aps/exceptions.md:15 src/exercises/bare-metal/rtc.md:101 +msgid "\"sync_exception_current\"" +msgstr "" + +#: src/bare-metal/aps/exceptions.md:21 src/exercises/bare-metal/rtc.md:107 +msgid "\"irq_current\"" +msgstr "" + +#: src/bare-metal/aps/exceptions.md:27 src/exercises/bare-metal/rtc.md:114 +msgid "\"fiq_current\"" +msgstr "" + +#: src/bare-metal/aps/exceptions.md:33 src/exercises/bare-metal/rtc.md:120 +msgid "\"serr_current\"" +msgstr "" + +#: src/bare-metal/aps/exceptions.md:39 src/exercises/bare-metal/rtc.md:126 +msgid "\"sync_lower\"" +msgstr "" + +#: src/bare-metal/aps/exceptions.md:45 src/exercises/bare-metal/rtc.md:132 +msgid "\"irq_lower\"" +msgstr "" + +#: src/bare-metal/aps/exceptions.md:51 src/exercises/bare-metal/rtc.md:138 +msgid "\"fiq_lower\"" +msgstr "" + +#: src/bare-metal/aps/exceptions.md:57 src/exercises/bare-metal/rtc.md:144 +msgid "\"serr_lower\"" msgstr "" #: src/bare-metal/aps/exceptions.md:64 @@ -19499,43 +13921,6 @@ msgid "" "types." msgstr "" -#: 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), " @@ -19579,27 +13964,16 @@ msgid "" "Architecture." msgstr "" -#: 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 @@ -19637,23 +14011,12 @@ msgid "" "space for PCI BARs:" msgstr "" -#: 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" -"```" +#: src/bare-metal/useful-crates/buddy_system_allocator.md:19 +msgid "\"Failed to allocate 0x100 byte MMIO region\"" +msgstr "" + +#: src/bare-metal/useful-crates/buddy_system_allocator.md:20 +msgid "\"Allocated 0x100 byte MMIO region at {:#x}\"" msgstr "" #: src/bare-metal/useful-crates/buddy_system_allocator.md:26 @@ -19680,20 +14043,10 @@ msgid "" "and panics if you try to use more than are allocated." msgstr "" -#: 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" -"```" +#: src/bare-metal/useful-crates/tinyvec.md:13 +#: src/bare-metal/useful-crates/tinyvec.md:15 +#: src/bare-metal/useful-crates/tinyvec.md:17 +msgid "\"{numbers:?}\"" msgstr "" #: src/bare-metal/useful-crates/tinyvec.md:23 @@ -19725,19 +14078,9 @@ msgid "" "equivalents of many of these primitives." msgstr "" -#: 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" -"```" +#: src/bare-metal/useful-crates/spin.md:15 +#: src/bare-metal/useful-crates/spin.md:17 +msgid "\"count: {}\"" msgstr "" #: src/bare-metal/useful-crates/spin.md:23 @@ -19820,20 +14163,8 @@ msgid "" "build rules, along with an entry point, UART console logging and more." msgstr "" -#: 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" -"```" +#: src/bare-metal/android/vmbase.md:15 +msgid "\"Hello world\"" msgstr "" #: src/bare-metal/android/vmbase.md:21 @@ -19900,62 +14231,30 @@ msgid "" "look in the `rtc` directory for the following files." msgstr "" -#: src/exercises/bare-metal/rtc.md:23 +#: src/exercises/bare-metal/rtc.md:37 +#: src/exercises/bare-metal/solutions-afternoon.md:46 +msgid "/// Base addresses of the GICv3.\n" +msgstr "" + +#: src/exercises/bare-metal/rtc.md:52 +#: src/exercises/bare-metal/solutions-afternoon.md:68 +msgid "\"main({:#x}, {:#x}, {:#x}, {:#x})\"" +msgstr "" + +#: src/exercises/bare-metal/rtc.md:54 +#: src/exercises/bare-metal/solutions-afternoon.md:70 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 @@ -19964,9 +14263,16 @@ msgid "" "the exercise):" msgstr "" -#: 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 +#: src/exercises/bare-metal/solutions-morning.md:8 +#: src/exercises/bare-metal/solutions-afternoon.md:10 +#: src/exercises/bare-metal/solutions-afternoon.md:152 +#: src/exercises/concurrency/solutions-afternoon.md:8 +#: src/exercises/concurrency/solutions-afternoon.md:126 +#: src/exercises/concurrency/solutions-afternoon.md:211 +#, fuzzy msgid "" -"```rust,compile_fail\n" "// Copyright 2023 Google LLC\n" "//\n" "// Licensed under the Apache License, Version 2.0 (the \"License\");\n" @@ -19980,72 +14286,8 @@ 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:149 -msgid "`src/logger.rs` (you shouldn't need to change this):" msgstr "" - -#: src/exercises/bare-metal/rtc.md:153 -msgid "" -"```rust,compile_fail\n" -"// Copyright 2023 Google LLC\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" @@ -20058,167 +14300,79 @@ 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" -"// 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:108 +msgid "\"No pending interrupt\"" +msgstr "" + +#: src/exercises/bare-metal/rtc.md:109 +msgid "\"IRQ {intid:?}\"" +msgstr "" + +#: src/exercises/bare-metal/rtc.md:149 +msgid "`src/logger.rs` (you shouldn't need to change this):" +msgstr "" + +#: src/exercises/bare-metal/rtc.md:167 +#: src/exercises/day-1/solutions-morning.md:61 +#: src/exercises/day-3/solutions-morning.md:161 +#: src/exercises/day-3/solutions-afternoon.md:139 +#: src/exercises/bare-metal/solutions-morning.md:43 +#: src/exercises/bare-metal/solutions-afternoon.md:59 +#: src/exercises/concurrency/solutions-afternoon.md:183 +msgid "// ANCHOR: main\n" msgstr "" #: src/exercises/bare-metal/rtc.md:210 msgid "`src/pl011.rs` (you shouldn't need to change this):" msgstr "" -#: 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" @@ -20228,62 +14382,10 @@ 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:368 +msgid "// ANCHOR_END: Uart\n" msgstr "" #: src/exercises/bare-metal/rtc.md:389 @@ -20314,56 +14416,37 @@ msgstr "" msgid "`build.rs` (you shouldn't need to change this):" msgstr "" -#: src/exercises/bare-metal/rtc.md:414 -#, fuzzy -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 +msgid "\"aarch64-linux-gnu\"" +msgstr "" + +#: 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 +msgid "\"exceptions.S\"" +msgstr "" + +#: src/exercises/bare-metal/rtc.md:441 +msgid "\"idmap.S\"" +msgstr "" + +#: src/exercises/bare-metal/rtc.md:442 +msgid "\"empty\"" msgstr "" -"```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" -"```" #: src/exercises/bare-metal/rtc.md:446 msgid "`entry.S` (you shouldn't need to change this):" @@ -20901,52 +14984,10 @@ msgstr "" msgid "`Makefile` (you shouldn't need to change this):" msgstr "" -#: src/exercises/bare-metal/rtc.md:944 +#: src/exercises/bare-metal/rtc.md:945 #, fuzzy -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" -"```" +msgid "# Copyright 2023 Google LLC" msgstr "" -"```rust\n" "// Copyright 2022 Google LLC\n" "//\n" "// Licensed under the Apache License, Version 2.0 (the \"License\");\n" @@ -20960,7 +15001,22 @@ msgstr "" "// 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" -"```" + +#: src/exercises/bare-metal/rtc.md:959 +msgid "$(shell uname -s)" +msgstr "" + +#: src/exercises/bare-metal/rtc.md:961 +msgid "aarch64-linux-gnu" +msgstr "" + +#: 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:989 msgid "" @@ -21005,31 +15061,17 @@ msgstr "" "_Threads_ em Rust funcionam de maneira semelhante às _threads_ em outras " "linguagens:" -#: src/concurrency/threads.md:5 +#: src/concurrency/threads.md:12 #, fuzzy -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" -"```" +msgid "\"Count in thread: {i}!\"" msgstr "" "fn main() { thread::spawn(|| { for i in 1..10 { println!(\"Contador na " "thread: {i}!\"); thread::sleep(Duration::from_millis(5)); } });" +#: src/concurrency/threads.md:18 +msgid "\"Main thread: {i}\"" +msgstr "" + #: src/concurrency/threads.md:24 msgid "Threads are all daemon threads, the main thread does not wait for them." msgstr "" @@ -21073,32 +15115,13 @@ msgstr "" msgid "Normal threads cannot borrow from their environment:" msgstr "_Threads_ normais não podem emprestar de seu ambiente:" -#: src/concurrency/scoped-threads.md:5 +#: src/concurrency/scoped-threads.md:11 src/concurrency/scoped-threads.md:30 #, fuzzy -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" -"```" +msgid "\"Length: {}\"" msgstr "" -"```rust,editable\n" -"fn main() {\n" -" let s1: String = String::from(\"Olá!\");\n" -" let s2: String = s1;\n" -" println!(\"s2: {s2}\");\n" -" // println!(\"s1: {s1}\");\n" -"}\n" -"```" +"\"s2: {s2}\"\n" +"\n" +"// println!(\"s1: {s1}\");\n" #: src/concurrency/scoped-threads.md:20 msgid "" @@ -21108,41 +15131,11 @@ msgstr "" "No entanto, você pode usar uma [_thread_ com escopo](https://doc.rust-lang." "org/std/thread/fn.scope.html) para isso:" -#: src/concurrency/scoped-threads.md:22 +#: src/concurrency/scoped-threads.md:40 #, fuzzy 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 "" -"```\n" -"thread::scope(|scope| {\n" -" scope.spawn(|| {\n" -" println!(\"Comprimento: {}\", s.len());\n" -" });\n" -"});\n" -"```\n" -"\n" -"}\n" -"\n" -"```\n" -"```" - -#: src/concurrency/scoped-threads.md:40 -#, fuzzy -msgid "" -"The reason for that is that when the `thread::scope` function completes, all " -"the threads are guaranteed to be joined, so they can return borrowed data." +"The reason for that is that when the `thread::scope` function completes, all " +"the threads are guaranteed to be joined, so they can return borrowed data." msgstr "" "A razão para isso é que, quando a função `thread::scope` for concluída, " "todas as _threads_ serão unidas, para que possam retornar dados emprestados." @@ -21165,26 +15158,9 @@ msgstr "" "`Receiver`. As duas partes estão conectadas através do _channel_, mas " "você só vê os _end-points_." -#: 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:16 src/concurrency/channels.md:17 +#: src/concurrency/channels.md:21 +msgid "\"Received: {:?}\"" msgstr "" #: src/concurrency/channels.md:27 @@ -21209,32 +15185,10 @@ msgstr "" msgid "You get an unbounded and asynchronous channel with `mpsc::channel()`:" msgstr "Você obtém um canal ilimitado e assíncrono com `mpsc::channel()`:" -#: src/concurrency/channels/unbounded.md:5 +#: src/concurrency/channels/unbounded.md:16 +#: src/concurrency/channels/bounded.md:16 #, fuzzy -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" -"```" +msgid "\"Message {i}\"" msgstr "" "```\n" "thread::spawn(move || {\n" @@ -21248,51 +15202,27 @@ msgstr "" "thread::sleep(Duration::from_millis(100));\n" "```" +#: 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 #, fuzzy msgid "" "With bounded (synchronous) channels, `send` can block the current thread:" msgstr "Canais limitados e síncronos fazem `send` bloquear o _thread_ atual:" -#: src/concurrency/channels/bounded.md:5 -#, fuzzy -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 "" -"```\n" -"thread::spawn(move || {\n" -" let thread_id = thread::current().id();\n" -" for i in 1..10 {\n" -" tx.send(format!(\"Mensagem {i}\")).unwrap();\n" -" println!(\"{thread_id:?}: enviando a mensagem: {i}\");\n" -" }\n" -" println!(\"{thread_id:?}: feito\");\n" -"});\n" -"thread::sleep(Duration::from_millis(100));\n" -"```" - #: src/concurrency/channels/bounded.md:31 msgid "" "Calling `send` will block the current thread until there is space in the " @@ -21591,28 +15521,9 @@ msgstr "" "[`Arc`](https://doc.rust-lang.org/std/sync/struct.Arc.html) permite " "acesso somente leitura compartilhado por meio de seu método `clone`:" -#: src/concurrency/shared_state/arc.md:5 +#: src/concurrency/shared_state/arc.md:16 #, fuzzy -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" -"```" +msgid "\"{thread_id:?}: {v:?}\"" msgstr "" "fn main() { let v = Arc::new(vec![10, 20, 30\\]); let mut handles = Vec::" "new(); for _ in 1..5 { let v = v.clone(); handles.push(thread::spawn(move || " @@ -21670,23 +15581,9 @@ msgstr "" "exclusão mútua _e_ permite acesso mutável a `T` por trás de uma interface " "somente leitura:" -#: 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 @@ -21764,24 +15661,9 @@ msgstr "" msgid "Let us see `Arc` and `Mutex` in action:" msgstr "Vamos ver `Arc` e `Mutex` em ação:" -#: src/concurrency/shared_state/example.md:5 +#: src/concurrency/shared_state/example.md:6 #, fuzzy -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" -"```" +msgid "// use std::sync::{Arc, Mutex};\n" msgstr "" "fn main() { let mut v = vec![10, 20, 30\\]; let handle = thread::spawn(|| " "{ v.push(10); }); v.push(1000);" @@ -21790,33 +15672,6 @@ msgstr "" msgid "Possible solution:" msgstr "" -#: 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 "" @@ -21913,49 +15768,87 @@ msgstr "" "arquivo `src/main.rs`, preencha os espaços em branco, e teste se `cargo run` " "não trava:" -#: 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:41 +#: src/exercises/concurrency/solutions-afternoon.md:42 +msgid "\"Eureka! {} has a new idea!\"" +msgstr "" + +#: src/exercises/concurrency/dining-philosophers.md:41 +#: src/exercises/concurrency/dining-philosophers-async.md:36 +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:54 +#: src/exercises/concurrency/solutions-afternoon.md:58 +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:60 +#: src/exercises/concurrency/solutions-afternoon.md:68 +msgid "\"Socrates\"" +msgstr "" + +#: src/exercises/concurrency/dining-philosophers.md:48 +#: src/exercises/concurrency/dining-philosophers-async.md:43 +#: src/exercises/concurrency/solutions-morning.md:60 +#: src/exercises/concurrency/solutions-afternoon.md:68 +msgid "\"Plato\"" +msgstr "" + +#: src/exercises/concurrency/dining-philosophers.md:48 +#: src/exercises/concurrency/dining-philosophers-async.md:43 +#: src/exercises/concurrency/solutions-morning.md:60 +#: src/exercises/concurrency/solutions-afternoon.md:68 +msgid "\"Aristotle\"" +msgstr "" + +#: src/exercises/concurrency/dining-philosophers.md:48 +#: src/exercises/concurrency/dining-philosophers-async.md:43 +#: src/exercises/concurrency/solutions-morning.md:60 +#: src/exercises/concurrency/solutions-afternoon.md:68 +msgid "\"Thales\"" +msgstr "" + +#: src/exercises/concurrency/dining-philosophers.md:48 +#: src/exercises/concurrency/dining-philosophers-async.md:43 +#: src/exercises/concurrency/solutions-morning.md:60 +#: src/exercises/concurrency/solutions-afternoon.md:68 +msgid "\"Pythagoras\"" +msgstr "" + +#: src/exercises/concurrency/dining-philosophers.md:51 +#: src/exercises/concurrency/dining-philosophers-async.md:47 +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:77 +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:112 +msgid "// Output their thoughts\n" msgstr "" #: src/exercises/concurrency/dining-philosophers.md:61 @@ -21993,21 +15886,6 @@ msgstr "" "rs/reqwest/). Crie um novo Project com o Cargo e adicione `reqwest` como uma " "dependência:" -#: src/exercises/concurrency/link-checker.md:11 -#, fuzzy -msgid "" -"```shell\n" -"cargo new link-checker\n" -"cd link-checker\n" -"cargo add --features blocking,rustls-tls reqwest\n" -"```" -msgstr "" -"```shell\n" -"$ cargo new link-checker\n" -"$ cd link-checker\n" -"$ cargo add --features blocking,rustls-tls reqwest\n" -"```" - #: src/exercises/concurrency/link-checker.md:17 msgid "" "If `cargo add` fails with `error: no such subcommand`, then please edit the " @@ -22024,17 +15902,6 @@ msgstr "" "Você também precisará de uma maneira de encontrar links. Podemos usar " "[`scraper`](https://docs.rs/scraper/) para isso:" -#: src/exercises/concurrency/link-checker.md:22 -#, fuzzy -msgid "" -"```shell\n" -"cargo add scraper\n" -"```" -msgstr "" -"```shell\n" -"$ cargo add scraper\n" -"```" - #: src/exercises/concurrency/link-checker.md:26 msgid "" "Finally, we'll need some way of handling errors. We use [`thiserror`]" @@ -22043,17 +15910,6 @@ msgstr "" "Por fim, precisaremos de alguma forma de lidar com os erros. Usamos " "[`thiserror`](https://docs.rs/thiserror/) para isso:" -#: src/exercises/concurrency/link-checker.md:29 -#, fuzzy -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:" @@ -22098,90 +15954,48 @@ msgstr "" msgid "Your `src/main.rs` file should look something like this:" msgstr "Seu arquivo `src/main.rs` deve se parecer com isto:" -#: 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:132 +msgid "\"request error: {0}\"" +msgstr "" + +#: src/exercises/concurrency/link-checker.md:66 +#: src/exercises/concurrency/solutions-morning.md:134 +msgid "\"bad http response: {0}\"" +msgstr "" + +#: src/exercises/concurrency/link-checker.md:77 +#: src/exercises/concurrency/solutions-morning.md:147 +msgid "\"Checking {:#}\"" +msgstr "" + +#: src/exercises/concurrency/link-checker.md:95 +#: src/exercises/concurrency/solutions-morning.md:165 +msgid "\"href\"" +msgstr "" + +#: src/exercises/concurrency/link-checker.md:102 +#: src/exercises/concurrency/solutions-morning.md:172 +msgid "\"On {base_url:#}: ignored unparsable {href:?}: {err}\"" +msgstr "" + +#: src/exercises/concurrency/link-checker.md:111 +#: src/exercises/concurrency/solutions-morning.md:286 +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 "" #: src/exercises/concurrency/link-checker.md:120 msgid "Run the code in `src/main.rs` with" msgstr "Execute o código em `src/main.rs` com" -#: src/exercises/concurrency/link-checker.md:122 -#, fuzzy -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 " @@ -22258,25 +16072,8 @@ msgid "" "code:" msgstr "" -#: 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 "" #: src/async/async-await.md:27 @@ -22331,25 +16128,6 @@ msgid "" "doc.rust-lang.org/std/task/enum.Poll.html)." msgstr "" -#: 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 " @@ -22451,28 +16229,12 @@ msgstr "" msgid "A large ecosystem of libraries." msgstr "" -#: 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 @@ -22519,48 +16281,28 @@ msgid "" "and an I/O operation." msgstr "" -#: 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 @@ -22592,36 +16334,24 @@ msgid "" "Several crates have support for asynchronous channels. For instance `tokio`:" msgstr "" -#: 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 @@ -22679,34 +16409,20 @@ msgid "" "JavaScript or `asyncio.gather` in Python." msgstr "" -#: 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:38 @@ -22747,54 +16463,28 @@ msgid "" "the `future`'s result." msgstr "" -#: 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 @@ -22869,27 +16559,12 @@ msgid "" "possible." msgstr "" -#: 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 @@ -22947,61 +16622,42 @@ msgid "" "repeatedly in a `select!` often leads to issues with pinned values." msgstr "" -#: 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 @@ -23027,19 +16683,6 @@ msgid "" "Instead, add a `timeout_fut` containing that future outside of the `loop`:" msgstr "" -#: 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 " @@ -23047,19 +16690,6 @@ msgid "" "pin`:" msgstr "" -#: 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 msgid "" "This compiles, but once the timeout expires it is `Poll::Ready` on every " @@ -23094,50 +16724,12 @@ msgid "" "provides a workaround through a macro:" msgstr "" -#: 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 @@ -23169,72 +16761,16 @@ msgid "" "example, it shouldn't deadlock or lose data." msgstr "" -#: 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 +msgid "\"not UTF-8\"" +msgstr "" + +#: 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 @@ -23265,28 +16801,10 @@ msgid "" "struct:" msgstr "" -#: src/async/pitfalls/cancellation.md:83 +#: src/async/pitfalls/cancellation.md:95 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" +"// prefix buf and bytes with self.\n" " // ...\n" -" }\n" -"}\n" -"```" msgstr "" #: src/async/pitfalls/cancellation.md:104 @@ -23351,52 +16869,9 @@ msgstr "" "arquivo `src/main.rs`, preencha os espaços em branco, e teste se `cargo run` " "não trava:" -#: 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:101 +msgid "// Make them think and eat\n" msgstr "" #: src/exercises/concurrency/dining-philosophers-async.md:57 @@ -23537,46 +17012,29 @@ msgstr "" msgid "`src/bin/server.rs`:" msgstr "" -#: src/exercises/concurrency/chat-app.md:63 -msgid "" -"```rust,compile_fail\n" -"use futures_util::sink::SinkExt;\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:77 +#: src/exercises/concurrency/chat-app.md:122 +msgid "// TODO: For a hint, see the description of the task below.\n" +msgstr "" + +#: src/exercises/concurrency/chat-app.md:85 +#: src/exercises/concurrency/solutions-afternoon.md:190 +msgid "\"127.0.0.1:2000\"" +msgstr "" + +#: src/exercises/concurrency/chat-app.md:86 +#: src/exercises/concurrency/solutions-afternoon.md:191 +msgid "\"listening on port 2000\"" +msgstr "" + +#: src/exercises/concurrency/chat-app.md:90 +#: src/exercises/concurrency/solutions-afternoon.md:195 +msgid "\"New connection from {addr:?}\"" +msgstr "" + +#: src/exercises/concurrency/chat-app.md:93 +#: src/exercises/concurrency/solutions-afternoon.md:198 +msgid "// Wrap the raw TCP stream into a websocket.\n" msgstr "" #: src/exercises/concurrency/chat-app.md:102 @@ -23584,29 +17042,9 @@ msgstr "" msgid "`src/bin/client.rs`:" msgstr "" -#: src/exercises/concurrency/chat-app.md:106 -msgid "" -"```rust,compile_fail\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 = 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:114 +#: src/exercises/concurrency/solutions-afternoon.md:233 +msgid "\"ws://127.0.0.1:2000\"" msgstr "" #: src/exercises/concurrency/chat-app.md:127 @@ -23618,32 +17056,10 @@ msgstr "Executando o curso" msgid "Run the server with:" msgstr "" -#: src/exercises/concurrency/chat-app.md:130 -#, fuzzy -msgid "" -"```shell\n" -"cargo run --bin server\n" -"```" -msgstr "" -"```shell\n" -"$ cargo run\n" -"```" - #: src/exercises/concurrency/chat-app.md:134 msgid "and the client with:" msgstr "" -#: src/exercises/concurrency/chat-app.md:136 -#, fuzzy -msgid "" -"```shell\n" -"cargo run --bin client\n" -"```" -msgstr "" -"```shell\n" -"$ cargo run\n" -"```" - #: src/exercises/concurrency/chat-app.md:142 msgid "Implement the `handle_connection` function in `src/bin/server.rs`." msgstr "" @@ -23972,9 +17388,16 @@ msgstr "Dia 1 Exercícios matinais" msgid "([back to exercise](for-loops.md))" msgstr "([voltar ao exercício](for-loops.md))" -#: src/exercises/day-1/solutions-morning.md:7 +#: src/exercises/day-1/solutions-morning.md:8 +#: src/exercises/day-1/solutions-afternoon.md:8 +#: src/exercises/day-2/solutions-morning.md:8 +#: src/exercises/day-2/solutions-afternoon.md:8 +#: src/exercises/day-2/solutions-afternoon.md:102 +#: src/exercises/day-3/solutions-morning.md:8 +#: src/exercises/day-3/solutions-afternoon.md:8 +#: src/exercises/concurrency/solutions-morning.md:8 +#: src/exercises/concurrency/solutions-morning.md:109 msgid "" -"```rust\n" "// Copyright 2022 Google LLC\n" "//\n" "// Licensed under the Apache License, Version 2.0 (the \"License\");\n" @@ -23988,63 +17411,39 @@ 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" -"// 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" -"```" +msgstr "" + +#: src/exercises/day-1/solutions-morning.md:21 +msgid "// ANCHOR: transpose\n" +msgstr "" + +#: src/exercises/day-1/solutions-morning.md:24 +msgid "// ANCHOR_END: transpose\n" +msgstr "" + +#: src/exercises/day-1/solutions-morning.md:33 +msgid "// ANCHOR: pretty_print\n" +msgstr "" + +#: src/exercises/day-1/solutions-morning.md:36 +msgid "// ANCHOR_END: pretty_print\n" +msgstr "" + +#: src/exercises/day-1/solutions-morning.md:38 +msgid "\"{row:?}\"" +msgstr "" + +#: src/exercises/day-1/solutions-morning.md:41 +msgid "// ANCHOR: tests\n" +msgstr "" + +#: src/exercises/day-1/solutions-morning.md:46 +#: src/exercises/day-1/solutions-morning.md:54 +msgid "//\n" +msgstr "" + +#: src/exercises/day-1/solutions-morning.md:59 +msgid "// ANCHOR_END: tests\n" msgstr "" #: src/exercises/day-1/solutions-morning.md:78 @@ -24085,41 +17484,31 @@ msgstr "" "[`std::convert::AsRef`](https://doc.rust-lang.org/std/convert/trait.AsRef." "html) para abstrair qualquer coisa que pode ser referenciada como um _slice_." -#: src/exercises/day-1/solutions-morning.md:86 +#: src/exercises/day-1/solutions-morning.md:93 #, fuzzy -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" -"```" +msgid "// A line references a slice of items\n" msgstr "" "fn impressao_formatada\\(matriz: Matriz) where T: " "Debug, // Linha referencia uma slice de itens Linha: AsRef\\<\\[T\\]\\>, // " "Matriz referencia uma slice de linhas Matriz: AsRef\\<\\[Linha\\]\\> { for " "linha in matriz.as_ref() { println!(\"{:?}\", linha.as_ref()); } }" +#: src/exercises/day-1/solutions-morning.md:95 +msgid "// A matrix references a slice of lines\n" +msgstr "" + +#: src/exercises/day-1/solutions-morning.md:104 +msgid "// &[&[i32]]\n" +msgstr "" + +#: src/exercises/day-1/solutions-morning.md:106 +msgid "// [[&str; 2]; 2]\n" +msgstr "" + +#: src/exercises/day-1/solutions-morning.md:108 +msgid "// Vec>\n" +msgstr "" + #: src/exercises/day-1/solutions-morning.md:113 msgid "" "In addition, the type itself would not enforce that the child slices are of " @@ -24140,201 +17529,125 @@ msgstr "Projetando uma biblioteca" msgid "([back to exercise](book-library.md))" msgstr "([voltar ao exercício](book-library.md))" -#: src/exercises/day-1/solutions-afternoon.md:7 +#: src/exercises/day-1/solutions-afternoon.md:21 +#: src/exercises/day-3/solutions-morning.md:21 +#: src/exercises/concurrency/solutions-morning.md:124 +#: src/exercises/concurrency/solutions-afternoon.md:139 +#: src/exercises/concurrency/solutions-afternoon.md:224 +msgid "// ANCHOR: setup\n" +msgstr "" + +#: src/exercises/day-1/solutions-afternoon.md:49 +#: src/exercises/day-3/solutions-morning.md:88 +#: src/exercises/concurrency/solutions-morning.md:136 +#: src/exercises/concurrency/solutions-afternoon.md:146 +msgid "// ANCHOR_END: setup\n" +msgstr "" + +#: src/exercises/day-1/solutions-afternoon.md:51 +msgid "// ANCHOR: Library_new\n" +msgstr "" + +#: src/exercises/day-1/solutions-afternoon.md:53 +msgid "// ANCHOR_END: Library_new\n" +msgstr "" + +#: src/exercises/day-1/solutions-afternoon.md:57 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" +"// 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" +msgstr "" + +#: src/exercises/day-1/solutions-afternoon.md:66 +msgid "" +"// 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" +msgstr "" + +#: src/exercises/day-1/solutions-afternoon.md:75 +msgid "" +"// 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" +msgstr "" + +#: src/exercises/day-1/solutions-afternoon.md:84 +msgid "" +"// 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" +msgstr "" + +#: src/exercises/day-1/solutions-afternoon.md:91 +msgid "\"{}, published in {}\"" +msgstr "" + +#: src/exercises/day-1/solutions-afternoon.md:95 +msgid "" +"// 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" +msgstr "" + +#: src/exercises/day-1/solutions-afternoon.md:101 +msgid "" +"// 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" +msgstr "" + +#: src/exercises/day-1/solutions-afternoon.md:104 +msgid "// Longer hand-written solution:\n" +msgstr "" + +#: src/exercises/day-1/solutions-afternoon.md:115 +msgid "" "// 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-1/solutions-afternoon.md:141 +#: src/exercises/day-3/solutions-morning.md:171 +#: src/exercises/day-3/solutions-afternoon.md:145 +#: src/exercises/bare-metal/solutions-afternoon.md:75 +#: src/exercises/concurrency/solutions-afternoon.md:204 +msgid "// ANCHOR_END: main\n" +msgstr "" + +#: src/exercises/day-1/solutions-afternoon.md:150 +#: src/exercises/day-1/solutions-afternoon.md:161 +#: src/exercises/day-1/solutions-afternoon.md:168 +#: src/exercises/day-1/solutions-afternoon.md:180 +#: src/exercises/day-1/solutions-afternoon.md:183 +msgid "\"Lord of the Rings\"" +msgstr "" + +#: src/exercises/day-1/solutions-afternoon.md:151 +#: src/exercises/day-1/solutions-afternoon.md:169 +#: src/exercises/day-1/solutions-afternoon.md:186 +#: src/exercises/day-1/solutions-afternoon.md:189 +msgid "\"Alice's Adventures in Wonderland\"" +msgstr "" + +#: src/exercises/day-1/solutions-afternoon.md:170 +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:1 @@ -24345,109 +17658,41 @@ msgstr "Dia 2 Exercícios matinais" msgid "([back to exercise](points-polygons.md))" msgstr "([voltar ao exercício](points-polygons.md))" -#: src/exercises/day-2/solutions-morning.md:7 +#: src/exercises/day-2/solutions-morning.md:22 +msgid "// ANCHOR: Point\n" +msgstr "" + +#: src/exercises/day-2/solutions-morning.md:25 +msgid "// ANCHOR_END: Point\n" +msgstr "" + +#: src/exercises/day-2/solutions-morning.md:29 +msgid "// ANCHOR: Point-impl\n" +msgstr "" + +#: src/exercises/day-2/solutions-morning.md:32 +msgid "// ANCHOR_END: Point-impl\n" +msgstr "" + +#: src/exercises/day-2/solutions-morning.md:67 +msgid "// ANCHOR: Polygon\n" +msgstr "" + +#: src/exercises/day-2/solutions-morning.md:70 +msgid "// ANCHOR_END: Polygon\n" +msgstr "" + +#: src/exercises/day-2/solutions-morning.md:73 +msgid "// ANCHOR: Polygon-impl\n" +msgstr "" + +#: src/exercises/day-2/solutions-morning.md:76 +msgid "// ANCHOR_END: Polygon-impl\n" +msgstr "" + +#: src/exercises/day-2/solutions-morning.md:106 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" -"#[derive(Debug, Copy, Clone, PartialEq, Eq)]\n" -"// ANCHOR: Point\n" -"pub struct Point {\n" -" // ANCHOR_END: Point\n" -" x: i32,\n" -" y: i32,\n" -"}\n" -"\n" -"// ANCHOR: Point-impl\n" -"impl Point {\n" -" // ANCHOR_END: Point-impl\n" -" pub fn new(x: i32, y: i32) -> 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 " @@ -24457,135 +17702,42 @@ 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-2/solutions-morning.md:114 +msgid "// ANCHOR: Circle\n" +msgstr "" + +#: src/exercises/day-2/solutions-morning.md:117 +msgid "// ANCHOR_END: Circle\n" +msgstr "" + +#: src/exercises/day-2/solutions-morning.md:121 +msgid "// ANCHOR: Circle-impl\n" +msgstr "" + +#: src/exercises/day-2/solutions-morning.md:124 +msgid "// ANCHOR_END: Circle-impl\n" +msgstr "" + +#: src/exercises/day-2/solutions-morning.md:137 +msgid "// ANCHOR: Shape\n" +msgstr "" + +#: src/exercises/day-2/solutions-morning.md:142 +msgid "// ANCHOR_END: Shape\n" +msgstr "" + +#: src/exercises/day-2/solutions-morning.md:165 +#: src/exercises/day-2/solutions-afternoon.md:56 +#: src/exercises/day-2/solutions-afternoon.md:139 +msgid "// ANCHOR: unit-tests\n" +msgstr "" + +#: src/exercises/day-2/solutions-morning.md:236 +#: src/exercises/day-2/solutions-afternoon.md:93 +#: src/exercises/day-2/solutions-afternoon.md:172 +msgid "// ANCHOR_END: unit-tests\n" msgstr "" #: src/exercises/day-2/solutions-afternoon.md:1 @@ -24596,138 +17748,46 @@ msgstr "Dia 2 Exercícios da Tarde" msgid "([back to exercise](luhn.md))" msgstr "([voltar ao exercício](luhn.md))" -#: src/exercises/day-2/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" -"}\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-2/solutions-afternoon.md:21 +msgid "// ANCHOR: luhn\n" +msgstr "" + +#: src/exercises/day-2/solutions-afternoon.md:24 +msgid "// ANCHOR_END: luhn\n" +msgstr "" + +#: src/exercises/day-2/solutions-afternoon.md:50 +msgid "\"1234 5678 1234 5670\"" +msgstr "" + +#: src/exercises/day-2/solutions-afternoon.md:52 +msgid "\"Is {cc_number} a valid credit card number? {}\"" msgstr "" #: src/exercises/day-2/solutions-afternoon.md:99 msgid "([back to exercise](strings-iterators.md))" msgstr "([voltar ao exercício](strings-iterators.md))" -#: src/exercises/day-2/solutions-afternoon.md:101 +#: src/exercises/day-2/solutions-afternoon.md:115 +msgid "// ANCHOR: prefix_matches\n" +msgstr "" + +#: src/exercises/day-2/solutions-afternoon.md:118 +msgid "// ANCHOR_END: prefix_matches\n" +msgstr "" + +#: src/exercises/day-2/solutions-afternoon.md:120 +#: src/exercises/day-2/solutions-afternoon.md:122 +msgid "'/'" +msgstr "" + +#: src/exercises/day-2/solutions-afternoon.md:126 +msgid "\"*\"" +msgstr "" + +#: src/exercises/day-2/solutions-afternoon.md:132 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" @@ -24738,49 +17798,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 @@ -24791,176 +17808,91 @@ msgstr "Dia 3 Exercício matinal" msgid "([back to exercise](simple-gui.md))" msgstr "([voltar ao exercício](simple-gui.md))" -#: src/exercises/day-3/solutions-morning.md:7 +#: src/exercises/day-3/solutions-morning.md:90 +msgid "// ANCHOR: Window-width\n" +msgstr "" + +#: src/exercises/day-3/solutions-morning.md:94 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" +"// 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" +msgstr "" + +#: src/exercises/day-3/solutions-morning.md:99 +msgid "// ANCHOR: Window-draw_into\n" +msgstr "" + +#: src/exercises/day-3/solutions-morning.md:101 +msgid "// ANCHOR_END: Window-draw_into\n" +msgstr "" + +#: src/exercises/day-3/solutions-morning.md:109 +msgid "" +"// 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:112 +#: src/exercises/day-3/solutions-morning.md:118 +msgid "\"+-{:-,\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" +"// 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" +msgstr "" + +#: src/exercises/day-3/solutions-afternoon.md:95 +msgid "\"Invalid path: {err}\"" +msgstr "" + +#: src/exercises/day-3/solutions-afternoon.md:96 +msgid "// SAFETY: path.as_ptr() cannot be NULL.\n" +msgstr "" + +#: src/exercises/day-3/solutions-afternoon.md:99 +msgid "\"Could not open {:?}\"" +msgstr "" + +#: src/exercises/day-3/solutions-afternoon.md:105 +msgid "// ANCHOR: Iterator\n" +msgstr "" + +#: src/exercises/day-3/solutions-afternoon.md:110 +msgid "" +"// Keep calling readdir until we get a NULL pointer back.\n" " // ANCHOR_END: Iterator\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:115 +msgid "// We have reached the end of the directory.\n" +msgstr "" + +#: src/exercises/day-3/solutions-afternoon.md:118 +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" +msgstr "" + +#: src/exercises/day-3/solutions-afternoon.md:125 +msgid "// ANCHOR: Drop\n" +msgstr "" + +#: src/exercises/day-3/solutions-afternoon.md:129 +msgid "" +"// 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:132 +msgid "// SAFETY: self.dir is not NULL.\n" +msgstr "" + +#: src/exercises/day-3/solutions-afternoon.md:134 +msgid "\"Could not close {:?}\"" +msgstr "" + +#: src/exercises/day-3/solutions-afternoon.md:155 +msgid "\"no-such-directory\"" +msgstr "" + +#: src/exercises/day-3/solutions-afternoon.md:163 +#: src/exercises/day-3/solutions-afternoon.md:178 +msgid "\"Non UTF-8 character in path\"" +msgstr "" + +#: src/exercises/day-3/solutions-afternoon.md:167 +#: src/exercises/day-3/solutions-afternoon.md:182 +msgid "\"..\"" +msgstr "" + +#: src/exercises/day-3/solutions-afternoon.md:174 +#: src/exercises/day-3/solutions-afternoon.md:182 +msgid "\"foo.txt\"" +msgstr "" + +#: src/exercises/day-3/solutions-afternoon.md:174 +msgid "\"The Foo Diaries\\n\"" +msgstr "" + +#: src/exercises/day-3/solutions-afternoon.md:175 +#: src/exercises/day-3/solutions-afternoon.md:182 +msgid "\"bar.png\"" +msgstr "" + +#: src/exercises/day-3/solutions-afternoon.md:175 +msgid "\"\\n\"" +msgstr "" + +#: src/exercises/day-3/solutions-afternoon.md:176 +#: src/exercises/day-3/solutions-afternoon.md:182 +msgid "\"crab.rs\"" +msgstr "" + +#: src/exercises/day-3/solutions-afternoon.md:176 +msgid "\"//! Crab\\n\"" msgstr "" #: src/exercises/bare-metal/solutions-morning.md:1 @@ -25173,171 +18024,48 @@ msgstr "Dia 3 Exercício matinal" msgid "([back to exercise](compass.md))" msgstr "([voltar ao exercício](for-loops.md))" -#: src/exercises/bare-metal/solutions-morning.md:7 +#: src/exercises/bare-metal/solutions-morning.md:21 +#: src/exercises/bare-metal/solutions-afternoon.md:23 +msgid "// ANCHOR: top\n" +msgstr "" + +#: src/exercises/bare-metal/solutions-morning.md:29 +#: src/exercises/bare-metal/solutions-afternoon.md:30 +msgid "// ANCHOR_END: top\n" +msgstr "" + +#: src/exercises/bare-metal/solutions-morning.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" -"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" +"// 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" +msgstr "" + +#: src/exercises/bare-metal/solutions-morning.md:59 +msgid "\"Setting up IMU...\"" +msgstr "" + +#: src/exercises/bare-metal/solutions-morning.md:67 +msgid "// Set up display and timer.\n" +msgstr "" + +#: src/exercises/bare-metal/solutions-morning.md:74 +msgid "// ANCHOR: loop\n" +msgstr "" + +#: src/exercises/bare-metal/solutions-morning.md:78 +msgid "" +"// 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" -"```" +msgstr "" + +#: src/exercises/bare-metal/solutions-morning.md:87 +msgid "\"{},{},{}\\t{},{},{}\"" +msgstr "" + +#: src/exercises/bare-metal/solutions-morning.md:123 +msgid "" +"// 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 @@ -25349,210 +18077,108 @@ msgstr "([voltar ao exercício](luhn.md))" msgid "`main.rs`:" msgstr "" -#: src/exercises/bare-metal/solutions-afternoon.md:9 +#: src/exercises/bare-metal/solutions-afternoon.md:38 +msgid "// ANCHOR: imports\n" +msgstr "" + +#: src/exercises/bare-metal/solutions-afternoon.md:52 +msgid "// ANCHOR_END: imports\n" +msgstr "" + +#: src/exercises/bare-metal/solutions-afternoon.md:54 +msgid "/// Base address of the PL031 RTC.\n" +msgstr "" + +#: src/exercises/bare-metal/solutions-afternoon.md:56 +msgid "/// The IRQ used by the PL031 RTC.\n" +msgstr "" + +#: src/exercises/bare-metal/solutions-afternoon.md:77 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:82 +msgid "\"RTC: {time}\"" +msgstr "" + +#: src/exercises/bare-metal/solutions-afternoon.md:90 +msgid "// Wait for 3 seconds, without interrupts.\n" +msgstr "" + +#: src/exercises/bare-metal/solutions-afternoon.md:94 +#: src/exercises/bare-metal/solutions-afternoon.md:115 +msgid "\"Waiting for {}\"" +msgstr "" + +#: src/exercises/bare-metal/solutions-afternoon.md:98 +#: src/exercises/bare-metal/solutions-afternoon.md:106 +#: src/exercises/bare-metal/solutions-afternoon.md:122 +#: src/exercises/bare-metal/solutions-afternoon.md:130 +msgid "\"matched={}, interrupt_pending={}\"" +msgstr "" + +#: src/exercises/bare-metal/solutions-afternoon.md:110 +#: src/exercises/bare-metal/solutions-afternoon.md:134 +msgid "\"Finished waiting\"" +msgstr "" + +#: src/exercises/bare-metal/solutions-afternoon.md:112 +msgid "// Wait another 3 seconds for an interrupt.\n" +msgstr "" + +#: src/exercises/bare-metal/solutions-afternoon.md:136 +msgid "// ANCHOR: main_end\n" +msgstr "" + +#: src/exercises/bare-metal/solutions-afternoon.md:145 +msgid "// ANCHOR_END: main_end\n" msgstr "" #: src/exercises/bare-metal/solutions-afternoon.md:149 msgid "`pl031.rs`:" msgstr "" -#: src/exercises/bare-metal/solutions-afternoon.md:151 +#: src/exercises/bare-metal/solutions-afternoon.md:170 +msgid "/// Data register\n" +msgstr "" + +#: src/exercises/bare-metal/solutions-afternoon.md:172 +msgid "/// Match register\n" +msgstr "" + +#: src/exercises/bare-metal/solutions-afternoon.md:174 +msgid "/// Load register\n" +msgstr "" + +#: src/exercises/bare-metal/solutions-afternoon.md:176 +msgid "/// Control register\n" +msgstr "" + +#: src/exercises/bare-metal/solutions-afternoon.md:179 +msgid "/// Interrupt Mask Set or Clear register\n" +msgstr "" + +#: src/exercises/bare-metal/solutions-afternoon.md:182 +msgid "/// Raw Interrupt Status\n" +msgstr "" + +#: src/exercises/bare-metal/solutions-afternoon.md:185 +msgid "/// Masked Interrupt Status\n" +msgstr "" + +#: src/exercises/bare-metal/solutions-afternoon.md:188 +msgid "/// Interrupt Clear Register\n" +msgstr "" + +#: src/exercises/bare-metal/solutions-afternoon.md:192 +msgid "/// Driver for a PL031 real-time clock.\n" +msgstr "" + +#: src/exercises/bare-metal/solutions-afternoon.md:200 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" @@ -25562,76 +18188,55 @@ 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:214 +msgid "/// Reads the current RTC value.\n" +msgstr "" + +#: src/exercises/bare-metal/solutions-afternoon.md:216 +#: src/exercises/bare-metal/solutions-afternoon.md:224 +#: src/exercises/bare-metal/solutions-afternoon.md:232 +#: src/exercises/bare-metal/solutions-afternoon.md:243 +#: src/exercises/bare-metal/solutions-afternoon.md:255 +#: src/exercises/bare-metal/solutions-afternoon.md:262 +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:221 +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:229 +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" +" /// the interrupt is enabled.\n" +msgstr "" + +#: src/exercises/bare-metal/solutions-afternoon.md:238 +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:249 +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/bare-metal/solutions-afternoon.md:260 +msgid "/// Clears a pending interrupt, if any.\n" msgstr "" #: src/exercises/concurrency/solutions-morning.md:1 @@ -25643,104 +18248,56 @@ msgstr "Dia 3 Exercício matinal" msgid "([back to exercise](dining-philosophers.md))" msgstr "([voltar ao exercício](dining-philosophers.md))" -#: src/exercises/concurrency/solutions-morning.md:7 +#: src/exercises/concurrency/solutions-morning.md:21 +#: src/exercises/concurrency/solutions-afternoon.md:21 +msgid "// ANCHOR: Philosopher\n" +msgstr "" + +#: src/exercises/concurrency/solutions-morning.md:31 +#: src/exercises/concurrency/solutions-afternoon.md:32 +msgid "// ANCHOR_END: Philosopher\n" +msgstr "" + +#: src/exercises/concurrency/solutions-morning.md:36 +#: src/exercises/concurrency/solutions-afternoon.md:37 +msgid "// ANCHOR: Philosopher-think\n" +msgstr "" + +#: src/exercises/concurrency/solutions-morning.md:44 +#: src/exercises/concurrency/solutions-afternoon.md:45 +msgid "// ANCHOR_END: Philosopher-think\n" +msgstr "" + +#: src/exercises/concurrency/solutions-morning.md:46 +#: src/exercises/concurrency/solutions-afternoon.md:47 +msgid "// ANCHOR: Philosopher-eat\n" +msgstr "" + +#: src/exercises/concurrency/solutions-morning.md:48 +msgid "// ANCHOR_END: Philosopher-eat\n" +msgstr "" + +#: src/exercises/concurrency/solutions-morning.md:49 +msgid "\"{} is trying to eat\"" +msgstr "" + +#: src/exercises/concurrency/solutions-morning.md:53 +msgid "// ANCHOR: Philosopher-eat-end\n" +msgstr "" + +#: src/exercises/concurrency/solutions-morning.md:63 +msgid "// ANCHOR_END: Philosopher-eat-end\n" +msgstr "" + +#: src/exercises/concurrency/solutions-morning.md:75 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" +"// 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 "" + +#: src/exercises/concurrency/solutions-morning.md:99 +msgid "\"{thought}\"" msgstr "" #: src/exercises/concurrency/solutions-morning.md:104 @@ -25753,199 +18310,35 @@ msgstr "Verificador de links _multi-threads_" msgid "([back to exercise](link-checker.md))" msgstr "([voltar ao exercício](luhn.md))" -#: src/exercises/concurrency/solutions-morning.md:108 +#: src/exercises/concurrency/solutions-morning.md:138 +msgid "// ANCHOR: visit_page\n" +msgstr "" + +#: src/exercises/concurrency/solutions-morning.md:177 +msgid "// ANCHOR_END: visit_page\n" +msgstr "" + +#: src/exercises/concurrency/solutions-morning.md:195 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" +"/// Determine whether links within the given page should be extracted.\n" +msgstr "" + +#: src/exercises/concurrency/solutions-morning.md:203 +msgid "" +"/// 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 "" + +#: src/exercises/concurrency/solutions-morning.md:229 +msgid "// The sender got dropped. No more commands coming in.\n" +msgstr "" + +#: src/exercises/concurrency/solutions-morning.md:270 +msgid "\"Got crawling error: {:#}\"" +msgstr "" + +#: src/exercises/concurrency/solutions-morning.md:288 +msgid "\"Bad URLs: {:#?}\"" msgstr "" #: src/exercises/concurrency/solutions-afternoon.md:1 @@ -25958,123 +18351,51 @@ msgstr "Dia 1 Exercícios da Tarde" msgid "([back to exercise](dining-philosophers-async.md))" msgstr "([voltar ao exercício](dining-philosophers.md))" -#: src/exercises/concurrency/solutions-afternoon.md:7 +#: src/exercises/concurrency/solutions-afternoon.md:49 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" +"// 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" +msgstr "" + +#: src/exercises/concurrency/solutions-afternoon.md:52 +msgid "" +"// 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" +msgstr "" + +#: src/exercises/concurrency/solutions-afternoon.md:57 +msgid "// ANCHOR: Philosopher-eat-body\n" +msgstr "" + +#: src/exercises/concurrency/solutions-afternoon.md:60 +msgid "// ANCHOR_END: Philosopher-eat-body\n" +msgstr "" + +#: src/exercises/concurrency/solutions-afternoon.md:62 +msgid "" +"// 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" +msgstr "" + +#: src/exercises/concurrency/solutions-afternoon.md:72 +msgid "" +"// 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" +msgstr "" + +#: src/exercises/concurrency/solutions-afternoon.md:84 +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" -" 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 "" + +#: src/exercises/concurrency/solutions-afternoon.md:98 +msgid "// tx is dropped here, so we don't need to explicitly drop it later\n" +msgstr "" + +#: src/exercises/concurrency/solutions-afternoon.md:114 +msgid "\"Here is a thought: {thought}\"" msgstr "" #: src/exercises/concurrency/solutions-afternoon.md:121 @@ -26082,260 +18403,35 @@ msgstr "" msgid "([back to exercise](chat-app.md))" msgstr "([voltar ao exercício](luhn.md))" -#: src/exercises/concurrency/solutions-afternoon.md:125 +#: src/exercises/concurrency/solutions-afternoon.md:148 +msgid "// ANCHOR: handle_connection\n" +msgstr "" + +#: src/exercises/concurrency/solutions-afternoon.md:155 +msgid "// ANCHOR_END: handle_connection\n" +msgstr "" + +#: src/exercises/concurrency/solutions-afternoon.md:158 +msgid "\"Welcome to chat! Type a message\"" +msgstr "" + +#: src/exercises/concurrency/solutions-afternoon.md:162 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 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" +"// 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" -" let msg = msg.as_text()?;\n" -" println!(\"From client {addr:?} {msg:?}\");\n" -" bcast_tx.send(msg.into())?;\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 "" -#: src/exercises/concurrency/solutions-afternoon.md:210 +#: src/exercises/concurrency/solutions-afternoon.md:171 +msgid "\"From client {addr:?} {msg:?}\"" +msgstr "" + +#: src/exercises/concurrency/solutions-afternoon.md:240 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::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 = 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" +"// 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)) => println!(\"From server: {}\", msg." -"as_text()?),\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 "" -#~ "After looking at the exercises, you can look at the \\[solutions\\] " -#~ "provided." -#~ msgstr "" -#~ "Depois de ver os exercícios, você pode ver as " -#~ "\\[soluções\\]\\[solutions\\] fornecidas." - -#~ msgid "" -#~ "Note that since `println!` is a macro, `x` is not moved, even using the " -#~ "function like syntax of `println!(\"x: {}\", x)`" -#~ msgstr "" -#~ "Observe que como `println!` é uma macro, `x` não é movido, mesmo usando " -#~ "uma sintaxe parecida com a de uma função `println!(\"x: {}\", x)`" - -#~ msgid "" -#~ "Globally-scoped names for values can be given with static variables and " -#~ "constant definitions." -#~ msgstr "" -#~ "Nomes com escopo global podem ser obtidos por meio de variáveis estáticas " -#~ "e definições de constantes." - -#~ msgid "You can declare compile-time constants:" -#~ msgstr "Você pode declarar constantes em tempo de compilação:" - -#~ msgid "You can also declare static variables:" -#~ msgstr "Você também pode declarar variáveis estáticas:" - -#~ msgid "" -#~ "If you need to mutate the data inside an `Rc`, you will need to wrap the " -#~ "data in a type such as [`Cell` or `RefCell`](../concurrency/shared_state/" -#~ "arc.md)." -#~ msgstr "" -#~ "Se você precisar alterar os dados dentro de um `Rc`, você precisará " -#~ "agrupar os dados em um tipo como [`Cell` ou `RefCell`](../concurrency/" -#~ "shared_state/arc.md)." - -#~ msgid "" -#~ "Compare the different datatypes mentioned. `Box` enables (im)mutable " -#~ "borrows that are enforced at compile time. `RefCell` enables (im)mutable " -#~ "borrows that are enforced at run time and will panic if it fails at " -#~ "runtime." -#~ msgstr "" -#~ "Compare os diferentes tipos de dados mencionados. `Box` permite " -#~ "empréstimos mutáveis e imutáveis que são impostos em tempo de compilação. " -#~ "`RefCell` permite empréstimos mutáveis e imutáveis impostos em tempo de " -#~ "execução e irá lançar um `panic` caso falhe." - -#~ msgid "" -#~ "```rust,editable\n" -#~ "use std::rc::{Rc, Weak};\n" -#~ "use std::cell::RefCell;\n" -#~ "\n" -#~ "#[derive(Debug)]\n" -#~ "struct Node {\n" -#~ " value: i64,\n" -#~ " parent: Option>>,\n" -#~ " children: Vec>>,\n" -#~ "}\n" -#~ "\n" -#~ "fn main() {\n" -#~ " let mut root = Rc::new(RefCell::new(Node {\n" -#~ " value: 42,\n" -#~ " parent: None,\n" -#~ " children: vec![],\n" -#~ " }));\n" -#~ " let child = Rc::new(RefCell::new(Node {\n" -#~ " value: 43,\n" -#~ " children: vec![],\n" -#~ " parent: Some(Rc::downgrade(&root))\n" -#~ " }));\n" -#~ " root.borrow_mut().children.push(child);\n" -#~ "\n" -#~ " println!(\"graph: {root:#?}\");\n" -#~ "}\n" -#~ "```" -#~ msgstr "" -#~ "```rust,editable\n" -#~ "use std::rc::{Rc, Weak};\n" -#~ "use std::cell::RefCell;\n" -#~ "\n" -#~ "#[derive(Debug)]\n" -#~ "struct Node {\n" -#~ " valor: i64,\n" -#~ " pai: Option>>,\n" -#~ " filhos: Vec>>,\n" -#~ "}\n" -#~ "\n" -#~ "fn main() {\n" -#~ " let mut raiz = Rc::new(RefCell::new(Node {\n" -#~ " valor: 42,\n" -#~ " pai: None,\n" -#~ " filhos: vec![],\n" -#~ " }));\n" -#~ " let filho = Rc::new(RefCell::new(Node {\n" -#~ " valor: 43,\n" -#~ " filhos: vec![],\n" -#~ " pai: Some(Rc::downgrade(&raiz))\n" -#~ " }));\n" -#~ " raiz.borrow_mut().filhos.push(filho);\n" -#~ "\n" -#~ " println!(\"Grafo: {raiz:#?}\");\n" -#~ "}\n" -#~ "```" - -#~ msgid "" -#~ "Copy the following code to and implement " -#~ "the function:" -#~ msgstr "" -#~ "Copie o seguinte código para e implemente a " -#~ "função:" +#: src/exercises/concurrency/solutions-afternoon.md:246 +msgid "\"From server: {}\"" +msgstr ""