diff --git a/po/pt-BR.po b/po/pt-BR.po index ef77b5e3738..6d21d2d95af 100644 --- a/po/pt-BR.po +++ b/po/pt-BR.po @@ -505,7 +505,7 @@ msgstr "Dia 3: Tarde" #: src/SUMMARY.md:153 msgid "Error Handling" -msgstr "Manipulação de Erros" +msgstr "Tratamento de Erros" #: src/SUMMARY.md:154 msgid "Panics" @@ -561,7 +561,7 @@ msgstr "Testes de Integração" #: src/SUMMARY.md:168 msgid "Useful crates" -msgstr "" +msgstr "Crates Úteis para Testes" #: src/SUMMARY.md:169 msgid "Unsafe Rust" @@ -597,7 +597,7 @@ msgstr "Implementando Traits Inseguros" #: src/SUMMARY.md:178 msgid "Safe FFI Wrapper" -msgstr "Invólucro FFI seguro" +msgstr "Wrapper FFI seguro" #: src/SUMMARY.md:181 src/SUMMARY.md:251 msgid "Android" @@ -11352,27 +11352,27 @@ msgstr "" #: src/error-handling.md:1 msgid "# Error Handling" -msgstr "# Manipulação de erros" +msgstr "# Tratamento de Erros" #: src/error-handling.md:3 msgid "Error handling in Rust is done using explicit control flow:" -msgstr "O tratamento de erros em Rust é feito usando o fluxo de controle explícito:" +msgstr "O tratamento de erros em Rust é feito usando fluxo de controle explícito:" #: src/error-handling.md:5 msgid "" "* Functions that can have errors list this in their return type,\n" "* There are no exceptions." msgstr "" -"* As funções que podem ter erros mostram isso em seu tipo de retorno.\n" -"* Não há exceções." +"* Funções que podem ter erros mostram isso em seu tipo de retorno.\n" +"* Não há exceções (_exceptions_)." #: src/error-handling/panics.md:1 msgid "# Panics" -msgstr "# Panics (Pânico)" +msgstr "# _Panics_ (Pânicos)" #: src/error-handling/panics.md:3 msgid "Rust will trigger a panic if a fatal error happens at runtime:" -msgstr "O Rust disparará um _panic_ (pânico) se um erro fatal ocorrer em tempo de execução:" +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 "" @@ -11398,17 +11398,16 @@ msgid "" msgstr "" "* _Pânicos_ são para erros irrecuperáveis e inesperados.\n" " * Pânicos são sintomas de bugs no programa.\n" -"* Use APIs que não disparam erros do tipo _pânico_ (como `Vec::get`) se travar o programa não for " -"aceitável." +"* Use APIs que não disparam erros do tipo _pânico_ (como `Vec::get`) se não for " +"aceitável o travamento do programa." #: src/error-handling/panic-unwind.md:1 msgid "# Catching the Stack Unwinding" -msgstr "# Capturando o desenrolar da pilha" +msgstr "# Capturando a _Resolução_ da Pilha (_Stack Unwinding_)" #: src/error-handling/panic-unwind.md:3 msgid "By default, a panic will cause the stack to unwind. The unwinding can be caught:" -msgstr "" -"Por padrão, um pânico fará com que a pilha se desenrole. O desenrolamento pode ser capturado:" +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 "" @@ -11428,6 +11427,21 @@ msgid "" "}\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:21 msgid "" @@ -11441,18 +11455,17 @@ msgstr "" #: src/error-handling/result.md:1 msgid "# Structured Error Handling with `Result`" -msgstr "# Tratamento estruturado de erros com `Result`" +msgstr "# Tratamento Estruturado de Erros com `Result`" #: src/error-handling/result.md:3 msgid "" "We have already seen the `Result` enum. This is used pervasively when errors are\n" "expected as part of normal operation:" msgstr "" -"Já vimos o _Enum_ `Result`. Ele é usado amplamente quando os erros são\n" +"Já vimos o _enum_ `Result`. Ele é usado amplamente quando os erros são\n" "esperados como parte da operação normal:" #: src/error-handling/result.md:6 -#, fuzzy msgid "" "```rust,editable\n" "use std::fs;\n" @@ -11473,8 +11486,12 @@ msgid "" "}\n" "```" msgstr "" +"```rust,editable\n" +"use std::fs;\n" +"use std::io::Read;\n" +"\n" "fn main() {\n" -" let arquivo = File::open(\"diario.txt\");\n" +" let arquivo = fs::File::open(\"diario.txt\");\n" " match arquivo {\n" " Ok(mut arquivo) => {\n" " let mut conteudo = String::new();\n" @@ -11489,7 +11506,6 @@ msgstr "" "```" #: src/error-handling/result.md:27 -#, fuzzy msgid "" " * As with `Option`, the successful value sits inside of `Result`, forcing the developer to\n" " explicitly extract it. This encourages error checking. In the case where an error should never " @@ -11504,17 +11520,16 @@ msgstr "" " * Como em `Option`, o valor bem-sucedido fica dentro de `Result`, forçando o desenvolvedor a\n" " extraí-lo explicitamente. Isso encoraja a verificação de erros. No caso em que um erro nunca " "deve acontecer,\n" -" `unwrap()` ou `expect()` podem ser chamados, e isso sinaliza a intenção do desenvolvedor.\n" +" `unwrap()` ou `expect()` podem ser chamados, e isso também sinaliza a intenção do desenvolvedor.\n" " * A documentação de `Result` é uma leitura recomendada. Não durante o curso, mas vale a pena " "mencioná-la.\n" " Ele contém muitos métodos e funções de conveniência que ajudam na programação ao estilo " "funcional.\n" -" \n" -"" +" " #: src/error-handling/try-operator.md:1 msgid "# Propagating Errors with `?`" -msgstr "# Propagando erros com `?`" +msgstr "# Propagando Erros com `?`" #: src/error-handling/try-operator.md:3 msgid "" @@ -11542,7 +11557,7 @@ msgstr "" #: src/error-handling/try-operator.md:13 msgid "into the much simpler" -msgstr "Pode ser simplificado por:" +msgstr "O código acima pode ser simplificado para:" #: src/error-handling/try-operator.md:15 msgid "" @@ -11555,11 +11570,10 @@ msgstr "" "```" #: src/error-handling/try-operator.md:19 -msgid "We can use this to simplify our error handing code:" +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 -#, fuzzy msgid "" "```rust,editable\n" "use std::{fs, io};\n" @@ -11586,17 +11600,30 @@ msgid "" "}\n" "```" msgstr "" -"fn ler_nome_usuario(caminho: &str) -> Result {\n" -" let mut nome_usuario = String::with_capacity(100);\n" -" fs::File::open(caminho)\n" -" .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!(\"Não foi encontrado nenhum nome de usuário em {caminho}\");\n" +"```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" -" Ok (nome_usuario)\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:50 src/error-handling/converting-error-types-example.md:52 msgid "" @@ -11606,7 +11633,7 @@ msgid "" msgstr "" "* A variável `nome_usuario` pode ser `Ok(string)` ou `Err(error)`.\n" "* Use a chamada `fs::write` para testar os diferentes cenários: nenhum arquivo, arquivo vazio e " -"arquivo com name de usuário." +"arquivo com nome de usuário." #: src/error-handling/converting-error-types.md:1 #: src/error-handling/converting-error-types-example.md:1 @@ -11615,7 +11642,7 @@ msgstr "# Convertendo Tipos de Erro" #: src/error-handling/converting-error-types.md:3 msgid "The effective expansion of `?` is a little more complicated than previously indicated:" -msgstr "A efetiva expansão do operador `?` é um pouco mais complicada do que indicado anteriormente:" +msgstr "A expansão efetiva do operador `?` é um pouco mais complicada do que indicado anteriormente:" #: src/error-handling/converting-error-types.md:5 msgid "" @@ -11702,6 +11729,50 @@ msgid "" "}\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:55 msgid "" @@ -11716,13 +11787,13 @@ msgstr "" "e\n" "`Display`. Geralmente é útil para eles implementar `Clone` e `Eq` também quando possível, para " "tornar\n" -"mais fácil a vida ao testar e consumidor sua biblioteca. Neste caso, não podemos fazê-lo " +"mais fácil a vida para testes e consumidores da sua biblioteca. Neste caso, não podemos fazê-lo " "facilmente, porque\n" "`io::Error` não os implementa." #: src/error-handling/deriving-error-enums.md:1 msgid "# Deriving Error Enums" -msgstr "# Derivando _Enums_ de erro" +msgstr "# Derivando _Enums_ de Erro" #: src/error-handling/deriving-error-enums.md:3 msgid "" @@ -11730,10 +11801,9 @@ msgid "" "error enum like we did on the previous page:" msgstr "" "O _crate_ [thiserror](https://docs.rs/thiserror/) é uma maneira popular de criar um\n" -"tipo enumerado (enum) de erro, como fizemos na página anterior:" +"tipo enumerado (_enum_) de erro, como fizemos na página anterior:" #: src/error-handling/deriving-error-enums.md:6 -#, fuzzy msgid "" "```rust,editable,compile_fail\n" "use std::{fs, io};\n" @@ -11766,17 +11836,36 @@ msgid "" "}\n" "```" msgstr "" -"fn ler_nome_usuario(caminho: &str) -> Result {\n" -" let mut nome_usuario = String::with_capacity(100);\n" -" fs::File::open(caminho)\n" -" .context(format!(\"Falha ao abrir {caminho}\"))?\n" -" .read_to_string(&mut nome_usuario)\n" -" .context(\"Falha ao ler\")?;\n" +"```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" -" bail!(\"Não foi encontrado nenhum nome de usuário em {caminho}\");\n" +" return Err(LerNomeUsuarioErro::NomeUsuarioVazio(String::from(caminho)));\n" " }\n" -" Ok (nome_usuario)\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:39 msgid "" @@ -11785,10 +11874,10 @@ msgid "" "added).\n" "It also works for structs." msgstr "" -"A macro `thiserror` implementa automaticamente `std::error::Error`, e opcionalmente, `Display`\n" +"A _derive macro_ `thiserror` implementa automaticamente `std::error::Error`, e opcionalmente, `Display`\n" "(se os atributos `#[error(...)]` forem fornecidos) e `From` (se o atributo `#[from]` for " "adicionado).\n" -"Também funciona para estruturas." +"Também funciona para _structs_." #: src/error-handling/deriving-error-enums.md:43 msgid "It doesn't affect your public API, which makes it good for libraries." @@ -11796,7 +11885,7 @@ msgstr "Não afeta sua API pública, o que a torna boa para bibliotecas." #: src/error-handling/dynamic-errors.md:1 msgid "# Dynamic Error Types" -msgstr "# Tipos de erros dinâmicos" +msgstr "# Tipos de Erros Dinâmicos" #: src/error-handling/dynamic-errors.md:3 msgid "" @@ -11808,7 +11897,6 @@ msgstr "" "abrangendo todas as diferentes possibilidades. `std::error::Error` torna isso fácil." #: src/error-handling/dynamic-errors.md:6 -#, fuzzy msgid "" "```rust,editable,compile_fail\n" "use std::fs;\n" @@ -11838,17 +11926,33 @@ msgid "" "}\n" "```" msgstr "" -"fn ler_nome_usuario(caminho: &str) -> Result {\n" -" let mut nome_usuario = String::with_capacity(100);\n" -" fs::File::open(caminho)\n" -" .context(format!(\"Falha ao abrir {caminho}\"))?\n" -" .read_to_string(&mut nome_usuario)\n" -" .context(\"Falha ao ler\")?;\n" +"```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" -" bail!(\"Não foi encontrado nenhum nome de usuário em {caminho}\");\n" +" return Err(NomeUsuarioVazioErro(String::from(path)).into());\n" " }\n" -" Ok (nome_usuario)\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 "" @@ -11869,7 +11973,7 @@ msgstr "" #: src/error-handling/error-contexts.md:1 msgid "# Adding Context to Errors" -msgstr "# Adicionando contexto aos erros" +msgstr "# Adicionando Contexto a Erros" #: src/error-handling/error-contexts.md:3 msgid "" @@ -11877,12 +11981,11 @@ msgid "" "contextual information to your errors and allows you to have fewer\n" "custom error types:" msgstr "" -"O `crate` [anyhow](https://docs.rs/anyhow/) é amplamente usado pode ajudá-lo a adicionar\n" -"informações contextuais aos seus erros permitindo que você tenha menos\n" +"O `crate` [anyhow](https://docs.rs/anyhow/) é amplamente usado e pode lhe ajudar a adicionar\n" +"informações contextuais aos seus erros, permitindo que você tenha menos\n" "tipos de erros personalizados:" #: src/error-handling/error-contexts.md:7 -#, fuzzy msgid "" "```rust,editable,compile_fail\n" "use std::{fs, io};\n" @@ -11910,17 +12013,31 @@ msgid "" "}\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" -" .context(format!(\"Falha ao abrir {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!(\"Não foi encontrado nenhum nome de usuário em {caminho}\");\n" +" bail!(\"Nome de usuário não encontrado em {caminho}\");\n" " }\n" -" Ok (nome_usuario)\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:35 msgid "" @@ -11950,16 +12067,18 @@ msgid "Rust and Cargo come with a simple unit test framework:" msgstr "Rust e Cargo vêm com uma estrutura de testes unitários simples:" #: src/testing.md:5 -#, fuzzy msgid "" "* Unit tests are supported throughout your code.\n" "\n" "* Integration tests are supported via the `tests/` directory." -msgstr "* Testes de integração são suportados através do diretório `tests/`." +msgstr "" +"* Testes unitários são suportados em todo o seu código.\n" +"\n" +"* Testes de integração são suportados através do diretório `tests/`." #: src/testing/unit-tests.md:1 msgid "# Unit Tests" -msgstr "# Testes unitários" +msgstr "# Testes Unitários" #: src/testing/unit-tests.md:3 msgid "Mark unit tests with `#[test]`:" @@ -11991,6 +12110,29 @@ msgid "" "}\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:29 msgid "Use `cargo test` to find and run the unit tests." @@ -11998,14 +12140,14 @@ msgstr "Use `cargo test` para encontrar e executar os testes unitários." #: src/testing/test-modules.md:1 msgid "# Test Modules" -msgstr "# Módulos de teste" +msgstr "# Módulos de Teste" #: src/testing/test-modules.md:3 msgid "" "Unit tests are often put in a nested module (run tests on the\n" "[Playground](https://play.rust-lang.org/)):" msgstr "" -"Os testes unitários geralmente são colocados em um módulo aninhado (executar testes no\n" +"Testes unitários geralmente são colocados em um módulo aninhado (execute testes no\n" "[Playground](https://play.rust-lang.org/)):" #: src/testing/test-modules.md:6 @@ -12030,14 +12172,33 @@ msgid "" "}\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.\n" "* The `#[cfg(test)]` attribute is only active when you run `cargo test`." msgstr "" -"* Isso permite que você tenha testes unitários auxiliares e privados.\n" -"* O atributo `#[cfg(test)]` só fica ativo quando você executa `cargo test`." +"* Isso permite que você tenha testes unitários auxiliares privados.\n" +"* O atributo `#[cfg(test)]` somente fica ativo quando você executa `cargo test`." #: src/testing/doc-tests.md:1 msgid "# Documentation Tests" @@ -12066,11 +12227,11 @@ msgstr "" "/// Encurta uma string para o comprimento especificado.\n" "///\n" "/// ```\n" -"/// use playground::shorten_string;\n" -"/// assert_eq!(shorten_string(\"Hello World\", 5), \"Hello\");\n" -"/// assert_eq!(shorten_string(\"Olá Mundo\", 20), \"Olá Mundo\");\n" +"/// use playground::encurtar_string;\n" +"/// assert_eq!(encurtar_string(\"Olá Mundo\", 4), \"Olá\");\n" +"/// assert_eq!(encurtar_string(\"Olá Mundo\", 20), \"Olá Mundo\");\n" "/// ```\n" -"pub fn short_string(s: &str, comprimento: usize) -> &str {\n" +"pub fn encurtar_string(s: &str, comprimento: usize) -> &str {\n" " &s[..std::cmp::min(comprimento, s.len())]\n" "}\n" "```" @@ -12093,14 +12254,13 @@ msgstr "# Testes de Integração" #: src/testing/integration-tests.md:3 msgid "If you want to test your library as a client, use an integration test." -msgstr "Se quiser testar sua biblioteca como cliente, use um teste de integração." +msgstr "Se quiser testar sua biblioteca como um cliente, use um teste de integração." #: src/testing/integration-tests.md:5 msgid "Create a `.rs` file under `tests/`:" msgstr "Crie um arquivo `.rs` em `tests/`:" #: src/testing/integration-tests.md:7 -#, fuzzy msgid "" "```rust,ignore\n" "use my_library::init;\n" @@ -12111,28 +12271,30 @@ msgid "" "}\n" "```" msgstr "" +"```rust,ignore\n" +"use minha_biblioteca::iniciar;\n" +"\n" "#[test]\n" -"fn test_init() {\n" -" assert!(init().is_ok());\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 só têm acesso à API pública do seu `crate`." +msgstr "Esses testes têm acesso somente à API pública do seu `crate`." #: src/testing/useful-crates.md:1 msgid "## Useful crates for writing tests" -msgstr "" +msgstr "## _Crates_ Úteis para Escrever Testes" #: src/testing/useful-crates.md:3 -#, fuzzy msgid "Rust comes with only basic support for writing tests." -msgstr "Rust tem suporte embutido para testes de documentação:" +msgstr "Rust possui apenas suporte básico para escrever testes." #: src/testing/useful-crates.md:5 msgid "Here are some additional crates which we recommend for writing tests:" -msgstr "" +msgstr "Estes são alguns _crates_ adicionais que recomendamos para a escrita de testes:" #: src/testing/useful-crates.md:7 msgid "" @@ -12141,10 +12303,14 @@ msgid "" "* [proptest](https://docs.rs/proptest): Property-based testing for Rust.\n" "* [rstest](https://docs.rs/rstest): Support for fixtures and parameterised tests." msgstr "" +"* [googletest](https://docs.rs/googletest): Biblioteca abrangente para testes de assertividade na tradição " +"de GoogleTest para C++.\n" +"* [proptest](https://docs.rs/proptest): Testes baseados em propriedades para Rust.\n" +"* [rstest](https://docs.rs/rstest): Suporte para testes parametrizados e acessórios." #: src/unsafe.md:1 msgid "# Unsafe Rust" -msgstr "# Rust inseguro (unsafe)" +msgstr "# Rust Inseguro (_Unsafe_)" #: src/unsafe.md:3 msgid "The Rust language has two parts:" @@ -12155,8 +12321,8 @@ msgid "" "* **Safe Rust:** memory safe, no undefined behavior possible.\n" "* **Unsafe Rust:** can trigger undefined behavior if preconditions are violated." msgstr "" -"* **Safe Rust:** memória segura, nenhum comportamento indefinido é possível.\n" -"* **Insafe Rust:** pode desencadear um comportamento indefinido se as pré-condições forem violadas." +"* **Rust Seguro (_Safe_):** memória segura, nenhum comportamento indefinido é possível.\n" +"* **Rust Inseguro (_Unsafe_):** pode desencadear comportamento indefinido se pré-condições forem violadas." #: src/unsafe.md:8 msgid "" @@ -12171,8 +12337,8 @@ msgid "" "Unsafe code is usually small and isolated, and its correctness should be carefully\n" "documented. It is usually wrapped in a safe abstraction layer." msgstr "" -"Código inseguro é geralmente pequeno e isolado, e sua correção deve ser cuidadosamente\n" -"documentada. Geralmente é envolto em uma camada de abstração segura." +"Código inseguro é geralmente pequeno e isolado, e seu funcionamento correto deve ser cuidadosamente\n" +"documentado. Geralmente é envolto em uma camada de abstração segura." #: src/unsafe.md:14 msgid "Unsafe Rust gives you access to five new capabilities:" @@ -12189,8 +12355,8 @@ msgstr "" "* Desreferenciar ponteiros brutos.\n" "* Acessar ou modificar variáveis estáticas mutáveis.\n" "* Acessar os campos de uma `union`.\n" -"* Chamar funções inseguras (`unsafe`), incluindo funções `externas`.\n" -"* Implementar traits inseguros (`unsafe`)." +"* Chamar funções inseguras (`unsafe`), incluindo funções `extern` (externas).\n" +"* Implementar _traits_ inseguros (`unsafe` traits)." #: src/unsafe.md:22 msgid "" @@ -12208,21 +12374,20 @@ msgid "" "turned off the compiler safety features and have to write correct code by\n" "themselves. It means the compiler no longer enforces Rust's memory-safety rules." msgstr "" -"Rust inseguro não significa que o código está incorreto. Significa que os desenvolvedores\n" -"desligaram os recursos de segurança do compilador e tem que escrever o código corretamente\n" -"eles mesmos. Significa também que o compilador não impõe mais as regras de segurança de memória do " +"Rust inseguro não significa que o código esteja incorreto. Significa que os desenvolvedores\n" +"desligaram os recursos de segurança do compilador e precisam escrever o código corretamente\n" +"por eles mesmos. Significa também que o compilador não impõe mais as regras de segurança de memória do " "Rust." #: src/unsafe/raw-pointers.md:1 msgid "# Dereferencing Raw Pointers" -msgstr "# Desreferenciando ponteiros brutos" +msgstr "# Desreferenciando Ponteiros Brutos (_Raw_)" #: src/unsafe/raw-pointers.md:3 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 -#, fuzzy msgid "" "```rust,editable\n" "fn main() {\n" @@ -12244,11 +12409,18 @@ msgid "" "}\n" "```" msgstr "" -" // Seguro porque r1 e r2 foram obtidos de referências e, portanto, são garantidos como não " -"nulos e\n" -" // devidamente alinhados, os objetos subjacentes às referências das quais foram obtidos\n" -" // vivem em todo o bloco inseguro e não são acessados nem por meio de\n" -" // referências ou simultaneamente por meio de quaisquer outros ponteiros.\n" +"```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" +" // 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" @@ -12288,8 +12460,8 @@ msgstr "" " * O ponteiro deve ser não nulo.\n" " * O ponteiro deve ser _desreferenciável_ (dentro dos limites de um único objeto alocado).\n" " * O objeto não deve ter sido desalocado.\n" -" * Não deve haver acessos simultâneos ao mesmo local.\n" -" * Se o ponteiro foi obtido lançando uma referência, o objeto subjacente deve estar ativo e " +" * Não deve haver acessos simultâneos à mesma localização.\n" +" * Se o ponteiro foi obtido lançando uma referência, o objeto subjacente deve estar válido e " "nenhuma\n" " referência pode ser usada para acessar a memória." @@ -12299,14 +12471,13 @@ msgstr "Na maioria dos casos, o ponteiro também deve estar alinhado corretament #: src/unsafe/mutable-static-variables.md:1 msgid "# Mutable Static Variables" -msgstr "# Variáveis estáticas mutáveis" +msgstr "# Variáveis Estáticas Mutáveis" #: src/unsafe/mutable-static-variables.md:3 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 -#, fuzzy msgid "" "```rust,editable\n" "static HELLO_WORLD: &str = \"Hello, world!\";\n" @@ -12316,8 +12487,13 @@ msgid "" "}\n" "```" msgstr "" -"```rust, editable\n" -"static HELLO_WORLD: &str = \"Olá, mundo!\";" +"```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:13 msgid "" @@ -12343,6 +12519,19 @@ msgid "" "}\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:32 msgid "" @@ -12350,21 +12539,20 @@ msgid "" "sense\n" "in low-level `no_std` code, such as implementing a heap allocator or working with some C APIs." msgstr "" -"Usar uma variável estática mutável geralmente é uma má ideia, mas há alguns casos em que pode " +"Usar uma variável estática mutável geralmente é uma má ideia, mas há alguns casos em que isso pode " "fazer sentido,\n" -"em código `no_std` de baixo nível, como implementar um alocador de heap ou trabalhar com algumas " +"tais como em código `no_std` de baixo nível, como implementar um alocador de heap ou trabalhar com algumas " "APIs C." #: src/unsafe/unions.md:1 msgid "# Unions" -msgstr "# Unions (Uniões)" +msgstr "# _Unions_ (Uniões)" #: src/unsafe/unions.md:3 msgid "Unions are like enums, but you need to track the active field yourself:" -msgstr "As uniões `union` são como enums, mas você mesmo precisa rastrear o campo ativo:" +msgstr "_Unions_ são como _enums_, mas você mesmo precisa rastrear o campo ativo:" #: src/unsafe/unions.md:5 -#, fuzzy msgid "" "```rust,editable\n" "#[repr(C)]\n" @@ -12380,6 +12568,13 @@ msgid "" "}\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" @@ -12393,8 +12588,8 @@ msgid "" "needed\n" "for interacting with C library APIs." msgstr "" -"As uniões raramente são necessárias no Rust, pois geralmente você pode usar um `enum`. Elas são " -"ocasionalmente necessários\n" +"_Unions_ raramente são necessárias no Rust, pois geralmente você pode usar um _enum_. Elas são " +"ocasionalmente necessárias\n" "para interagir com as APIs da biblioteca C." #: src/unsafe/unions.md:24 @@ -12403,21 +12598,21 @@ msgid "" "[`std::mem::transmute`](https://doc.rust-lang.org/stable/std/mem/fn.transmute.html) or a safe\n" "wrapper such as the [`zerocopy`](https://crates.io/crates/zerocopy) crate." msgstr "" -"Se você deseja apenas reinterpretar os bytes como um tipo diferente, provavelmente usaria\n" +"Se você deseja apenas reinterpretar os bytes como um tipo diferente, você provavelmente deveria usar\n" "[`std::mem::transmute`](https://doc.rust-lang.org/stable/std/mem/fn.transmute.html) ou um\n" -"wrapper seguro como o `crate` [`zerocopy`](https://crates.io/crates/zerocopy)." +"wrapper seguro como o _crate_ [`zerocopy`](https://crates.io/crates/zerocopy)." #: src/unsafe/calling-unsafe-functions.md:1 msgid "# Calling Unsafe Functions" -msgstr "# Chamando funções inseguras" +msgstr "# Chamando Funções Inseguras" #: src/unsafe/calling-unsafe-functions.md:3 msgid "" "A function or method can be marked `unsafe` if it has extra preconditions you\n" "must uphold to avoid undefined behaviour:" msgstr "" -"Uma função ou método pode ser marcado como 'unsafe' se tiver pré-condições extras que você\n" -"deve respeitar para evitar comportamentos indefinidos:" +"Uma função ou método pode ser marcado como `unsafe` se houver pré-condições extras que você\n" +"deve respeitar para evitar comportamento indefinido:" #: src/unsafe/calling-unsafe-functions.md:6 msgid "" @@ -12445,10 +12640,33 @@ msgid "" "}\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 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:1 msgid "# Writing Unsafe Functions" -msgstr "# Escrevendo funções inseguras" +msgstr "# Escrevendo Funções Inseguras" #: src/unsafe/writing-unsafe-functions.md:3 msgid "" @@ -12456,12 +12674,11 @@ msgid "" "undefined\n" "behaviour." msgstr "" -"Você pode marcar suas próprias funções como _inseguras_ se elas exigirem condições específicas " +"Você pode marcar suas próprias funções como _inseguras_ (`unsafe`) se elas exigirem condições específicas " "para evitar\n" "comportamentos indefinidos." #: src/unsafe/writing-unsafe-functions.md:6 -#, fuzzy msgid "" "```rust,editable\n" "/// Swaps the values pointed to by the given pointers.\n" @@ -12489,21 +12706,34 @@ msgid "" "```" msgstr "" "```rust,editable\n" -"/// Trocando os valores dos parâmetros pode referência usando ponteiros\n" +"/// Troca os valores apontadoes pelos ponteiros fornecidos.\n" "///\n" -"/// # Safety\n" +"/// # Segurança\n" "///\n" "/// Os ponteiros precisam ser válidos e corretamente alinhados.\n" -"unsafe fn troca(a: *mut u8, b: *mut u8) {\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:33 msgid "We wouldn't actually use pointers for this because it can be done safely with references." msgstr "" -"Na verdade, não usaríamos ponteiros para isso porque isso pode ser feito com segurança usando " +"Na verdade, não usaríamos ponteiros para essa operação porque isso pode ser feito com segurança usando " "referências." #: src/unsafe/writing-unsafe-functions.md:35 @@ -12517,18 +12747,17 @@ msgstr "" #: src/unsafe/extern-functions.md:1 msgid "# Calling External Code" -msgstr "# Chamando código externo" +msgstr "# Chamando Código Externo" #: src/unsafe/extern-functions.md:3 msgid "" "Functions from other languages might violate the guarantees of Rust. Calling\n" "them is thus unsafe:" msgstr "" -"Funções de outras linguagens podem violar as garantias do Rust. Chamar\n" -"elas é, portanto, inseguro:" +"Funções de outras linguagens podem violar as garantias do Rust. Logo, chamá-las\n" +"é inseguro:" #: src/unsafe/extern-functions.md:6 -#, fuzzy msgid "" "```rust,editable\n" "extern \"C\" {\n" @@ -12543,9 +12772,14 @@ msgid "" "}\n" "```" msgstr "" +"```rust,editable\n" +"extern \"C\" {\n" +" fn abs(entrada: i32) -> i32;\n" +"}\n" +"\n" "fn main() {\n" " unsafe {\n" -" // Comportamento indefinido se o abs se comportar mal.\n" +" // Comportamento indefinido se abs se comportar mal.\n" " println!(\"Valor absoluto de -3 de acordo com C: {}\", abs(-3));\n" " }\n" "}\n" @@ -12558,7 +12792,7 @@ msgid "" "any\n" "arbitrary circumstances." msgstr "" -"Isso geralmente é apenas um problema para funções externas que fazem coisas com ponteiros que " +"Normalmente isso é apenas um problema para funções externas que fazem coisas com ponteiros que " "podem\n" "violar o modelo de memória do Rust, mas em geral qualquer função C pode ter comportamento " "indefinido sob quaisquer\n" @@ -12575,14 +12809,14 @@ msgstr "" #: src/unsafe/unsafe-traits.md:1 msgid "# Implementing Unsafe Traits" -msgstr "# Implementando traits inseguros" +msgstr "# Implementando _Traits_ Inseguros" #: src/unsafe/unsafe-traits.md:3 msgid "" "Like with functions, you can mark a trait as `unsafe` if the implementation must guarantee\n" "particular conditions to avoid undefined behaviour." msgstr "" -"Assim como nas funções, você pode marcar um `trait` como `unsafe` se a implementação deve " +"Assim como nas funções, você pode marcar um `trait` como `unsafe` se a implementação precisa " "garantir\n" "condições particulares para evitar comportamento indefinido." @@ -12591,11 +12825,10 @@ msgid "" "For example, the `zerocopy` crate has an unsafe trait that looks\n" "[something like this](https://docs.rs/zerocopy/latest/zerocopy/trait.AsBytes.html):" msgstr "" -"Por exemplo, o `crate` `zerocopy` tem uma característica insegura que parece\n" +"Por exemplo, o _crate_ `zerocopy` tem um _trait_ inseguro que parece\n" "[algo assim](https://docs.rs/zerocopy/latest/zerocopy/trait.AsBytes.html):" #: src/unsafe/unsafe-traits.md:9 -#, fuzzy msgid "" "```rust,editable\n" "use std::mem::size_of_val;\n" @@ -12616,16 +12849,24 @@ msgid "" "unsafe impl AsBytes for u32 {}\n" "```" msgstr "" +"```rust,editable\n" +"use std::mem::size_of_val;\n" +"use std::slice;\n" +"\n" "/// ...\n" -"/// # Safety\n" -"/// O tipo deve ter uma representação definida e nenhum preenchimento.\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" +"// 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 "" @@ -12633,15 +12874,15 @@ msgid "" "the trait to be safely implemented." msgstr "" "Deve haver uma seção `# Safety` no Rustdoc para o `trait` explicando os requisitos para\n" -"o `trait` ser implementado com segurança." +"ser implementado com segurança." #: src/unsafe/unsafe-traits.md:33 msgid "The actual safety section for `AsBytes` is rather longer and more complicated." -msgstr "A seção de segurança atual para `AsBytes` é bem mais longa e complicada." +msgstr "Na verdade, a seção de segurança para `AsBytes` é bem mais longa e complicada." #: src/unsafe/unsafe-traits.md:35 msgid "The built-in `Send` and `Sync` traits are unsafe." -msgstr "Os _traits_ incorporadas `Send` e `Sync` não são seguros." +msgstr "Os _traits_ integrados `Send` e `Sync` são inseguros." #: src/exercises/day-3/afternoon.md:1 msgid "# Day 3: Afternoon Exercises" @@ -12651,13 +12892,26 @@ msgstr "# Dia 3: Exercícios da Tarde" msgid "Let us build a safe wrapper for reading directory content!" msgstr "Vamos construir um wrapper seguro para ler o conteúdo do diretório!" -#: src/exercises/day-3/afternoon.md:7 +#: src/exercises/day-3/afternoon.md:5 +msgid "" +"For this exercise, we suggest using a local dev environment instead\n" +"of the Playground. This will allow you to run your binary on your own " +"machine." +msgstr "" +"Para este exercício, nós sugerimos a utilizaçao de um ambiente de desenvolvimento local\n" +"ao invés do _Playground_. Isto lhe permitirá executar o binário na sua própria máquina." + +#: src/exercises/day-3/afternoon.md:8 +msgid "To get started, follow the [running locally] instructions." +msgstr "Para começar, siga as instruçoes para [rodar localmente][running locally]." + +#: src/exercises/day-3/afternoon.md:14 msgid "After looking at the exercise, you can look at the [solution] provided." -msgstr "Depois de ver o exercício, você pode ver a [solução] fornecida." +msgstr "Depois de ver o exercício, você pode ver a [solução][solution] fornecida." #: src/exercises/day-3/safe-ffi-wrapper.md:1 msgid "# Safe FFI Wrapper" -msgstr "# _Wrapper_ FFI seguro" +msgstr "# _Wrapper_ FFI Seguro" #: src/exercises/day-3/safe-ffi-wrapper.md:3 msgid "" @@ -12666,8 +12920,8 @@ msgid "" "functions you would use from C to read the filenames of a directory." msgstr "" "Rust tem ótimo suporte para chamar funções por meio de uma interface para funções externas " -"(_function foreign\n" -"interface_ FFI). Usaremos isso para construir um invólucro seguro para as funções da `libc`\n" +"(_Function Foreign\n" +"Interface_ - FFI). Usaremos isso para construir um _wrapper_ (invólucro) seguro para as funções da `libc`\n" "de C que você usaria para ler os nomes dos arquivos de um diretório." #: src/exercises/day-3/safe-ffi-wrapper.md:7 @@ -12689,6 +12943,8 @@ msgid "" "You will also want to browse the [`std::ffi`] module. There you find a number of\n" "string types which you need for the exercise:" msgstr "" +"Você também vai querer navegar pelo módulo [`std::ffi`]. Lá você encontrará um número de\n" +"tipos de string que você precisará para o exercício:" #: src/exercises/day-3/safe-ffi-wrapper.md:16 msgid "" @@ -12698,10 +12954,15 @@ msgid "" "| [`CStr`] and [`CString`] | NUL-terminated | Communicating with C functions |\n" "| [`OsStr`] and [`OsString`] | OS-specific | Communicating with the OS |" msgstr "" +"| Tipos | Codificação | Uso |\n" +"|----------------------------|------------------|--------------------------------|\n" +"| [`str`] e [`String`] | UTF-8 | Processamento de texto em Rust |\n" +"| [`CStr`] e [`CString`] | terminado em NUL | Comunicação com funções em C |\n" +"| [`OsStr`] e [`OsString`] | específico ao SO | Comunicação com o SO |" #: src/exercises/day-3/safe-ffi-wrapper.md:22 msgid "You will convert between all these types:" -msgstr "" +msgstr "Você irá converter entre todos estes tipos:" #: src/exercises/day-3/safe-ffi-wrapper.md:24 msgid "" @@ -12715,10 +12976,19 @@ msgid "" "- `&OsStr` to `OsString`: you need to clone the data in `&OsStr` to be able to return it and call\n" " `readdir` again." msgstr "" +"- `&str` para `CString`: você precisa alocar espaço para o caracter terminador `\\0`,\n" +"- `CString` para `*const i8`: você precisa de um ponteiro para chamar funções em C,\n" +"- `*const i8` para `&CStr`: você você precisa de algo que pode encontrar o caracter terminador `\\0`,\n" +"- `&CStr` para `&[u8]`: um _slice_ de bytes é a interface universal para \"algum dado desconhecido\",\n" +"- `&[u8]` para `&OsStr`: `&OsStr` é um passo em direção a `OsString`, use\n" +" [`OsStrExt`](https://doc.rust-lang.org/std/os/unix/ffi/trait.OsStrExt.html)\n" +" para criá-lo,\n" +"- `&OsStr` para `OsString`: você precisa clonar os dados em `&OsStr` para poder retorná-lo e chamar\n" +" `readdir` novamente." #: src/exercises/day-3/safe-ffi-wrapper.md:34 msgid "The [Nomicon] also has a very useful chapter about FFI." -msgstr "" +msgstr "O [Nomicon] também tem um capítulo bastante útil sobre FFI." #: src/exercises/day-3/safe-ffi-wrapper.md:45 msgid "" @@ -12829,6 +13099,104 @@ msgid "" "}\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" +" // _DARWIN_FEATURE_64_BIT_INODE na página man do macOS para stat(2).\n" +" //\n" +" // \"Plataformas que existiram antes destas atualizações estarem 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" +" // 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/android.md:1 #, fuzzy @@ -16297,7 +16665,7 @@ msgstr "" #: src/bare-metal/useful-crates.md:1 msgid "# Useful crates" -msgstr "" +msgstr "_Crates_ Úteis" #: src/bare-metal/useful-crates.md:3 msgid "We'll go over a few crates which solve some common problems in bare-metal programming." @@ -21128,35 +21496,45 @@ msgid "" "// ANCHOR: prefix_matches\n" "pub fn prefix_matches(prefix: &str, request_path: &str) -> bool {\n" " // ANCHOR_END: prefix_matches\n" -" let prefixes = prefix.split('/');\n" -" let request_paths = request_path\n" -" .split('/')\n" -" .map(|p| Some(p))\n" -" .chain(std::iter::once(None));\n" -"\n" -" for (prefix, request_path) in prefixes.zip(request_paths) {\n" -" match request_path {\n" -" Some(request_path) => {\n" -" if (prefix != \"*\") && (prefix != request_path) {\n" -" return false;\n" -" }\n" -" }\n" -" None => return false,\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 " +"prefix\n" +" // and request segments. The zip() iterator is finished as soon as one " +"of\n" +" // the source iterators is finished, but we need to iterate over all " +"request\n" +" // segments. A neat trick that makes zip() work is to use map() and " +"chain()\n" +" // 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" +" 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" +" assert!(!prefix_matches(\"/v1/publishers\", " +"\"/v1/parent/publishers\"));\n" "}\n" "\n" "#[test]\n" @@ -21174,7 +21552,8 @@ msgid "" " \"/v1/publishers/foo/books/book1\"\n" " ));\n" "\n" -" assert!(!prefix_matches(\"/v1/publishers/*/books\", \"/v1/publishers\"));\n" +" assert!(!prefix_matches(\"/v1/publishers/*/books\", " +"\"/v1/publishers\"));\n" " assert!(!prefix_matches(\n" " \"/v1/publishers/*/books\",\n" " \"/v1/publishers/foo/booksByAuthor\"\n"