├── general ├── types.rs ├── enumeration.rs ├── abnt_rouding.rs ├── variables.rs ├── box.rs ├── default.md ├── tests_and_docs.md ├── correspondencia.rs ├── errorhandling.md ├── matrizes.md ├── tictactoe.rs ├── variables.md ├── loopExpressions └── types.md ├── 3_api ├── .gitignore ├── Cargo.toml ├── src │ ├── routes.rs │ ├── main.rs │ ├── like.rs │ └── tuite.rs └── Readme.md ├── actix-modules ├── cargo.toml ├── src │ ├── repo │ │ ├── mod.rs │ │ └── database.rs │ ├── main.rs │ ├── api.rs │ └── models.rs └── readme.md ├── 4_log ├── src │ └── main.rs ├── Cargo.lock └── Cargo.toml ├── Curso ├── qr.PNG ├── aula 1.pdf ├── aula 2.pdf ├── aula 3.pdf ├── revisao.pdf ├── programas │ ├── pascal.rs │ ├── consumo_pedidos.rs │ ├── bhaskara.rs │ ├── cadastro_alunos.rs │ ├── caixa.rs │ ├── velha.rs │ └── cobrinha.rs ├── revisao.md ├── aula 3.md ├── aula 1.md ├── aula 2.md └── Rust.md ├── arquitetura ├── Amazon.PNG ├── Grapho.PNG ├── Diretorios.png ├── arquitetura.png ├── distribuida.png ├── Readme.md └── diagrama.svg ├── algoritmos └── capitulo5 │ ├── A.PNG │ ├── B.PNG │ ├── C.PNG │ ├── D.PNG │ ├── E.PNG │ ├── F.PNG │ ├── G.PNG │ ├── H.PNG │ ├── I.PNG │ ├── J.PNG │ ├── K.PNG │ ├── L.PNG │ ├── M.PNG │ ├── N.PNG │ ├── O.PNG │ ├── P.PNG │ ├── Q.PNG │ ├── R.PNG │ ├── S.PNG │ ├── c.rs │ ├── j.rs │ ├── e.rs │ ├── f.rs │ ├── k.rs │ ├── d.rs │ ├── p.rs │ ├── g.rs │ ├── i.rs │ ├── a.rs │ ├── s.rs │ ├── o.rs │ ├── q.rs │ ├── n.rs │ ├── h.rs │ ├── r.rs │ ├── m.rs │ ├── b.rs │ ├── l.rs │ └── README.md ├── 7_env ├── src │ └── main.rs ├── Cargo.toml └── Cargo.lock ├── 8_cli ├── Cargo.toml ├── src │ └── main.rs └── Cargo.lock ├── 5_get └── Cargo.toml ├── 6_post ├── Cargo.toml └── Cargo.lock ├── Sudoku └── main.rs ├── .gitignore ├── Curadoria └── Readme.md ├── 9_calculadora └── main.rs ├── Modelos.md ├── terremoto └── ter.rs ├── actix └── readme.MD └── DesignPattern └── Readme.md /general/types.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /general/enumeration.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /3_api/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /actix-modules/cargo.toml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /actix-modules/src/repo/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod database; 2 | -------------------------------------------------------------------------------- /4_log/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("Hello, world!"); 3 | } 4 | -------------------------------------------------------------------------------- /Curso/qr.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/Curso/qr.PNG -------------------------------------------------------------------------------- /Curso/aula 1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/Curso/aula 1.pdf -------------------------------------------------------------------------------- /Curso/aula 2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/Curso/aula 2.pdf -------------------------------------------------------------------------------- /Curso/aula 3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/Curso/aula 3.pdf -------------------------------------------------------------------------------- /Curso/revisao.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/Curso/revisao.pdf -------------------------------------------------------------------------------- /arquitetura/Amazon.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/arquitetura/Amazon.PNG -------------------------------------------------------------------------------- /arquitetura/Grapho.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/arquitetura/Grapho.PNG -------------------------------------------------------------------------------- /algoritmos/capitulo5/A.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/algoritmos/capitulo5/A.PNG -------------------------------------------------------------------------------- /algoritmos/capitulo5/B.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/algoritmos/capitulo5/B.PNG -------------------------------------------------------------------------------- /algoritmos/capitulo5/C.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/algoritmos/capitulo5/C.PNG -------------------------------------------------------------------------------- /algoritmos/capitulo5/D.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/algoritmos/capitulo5/D.PNG -------------------------------------------------------------------------------- /algoritmos/capitulo5/E.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/algoritmos/capitulo5/E.PNG -------------------------------------------------------------------------------- /algoritmos/capitulo5/F.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/algoritmos/capitulo5/F.PNG -------------------------------------------------------------------------------- /algoritmos/capitulo5/G.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/algoritmos/capitulo5/G.PNG -------------------------------------------------------------------------------- /algoritmos/capitulo5/H.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/algoritmos/capitulo5/H.PNG -------------------------------------------------------------------------------- /algoritmos/capitulo5/I.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/algoritmos/capitulo5/I.PNG -------------------------------------------------------------------------------- /algoritmos/capitulo5/J.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/algoritmos/capitulo5/J.PNG -------------------------------------------------------------------------------- /algoritmos/capitulo5/K.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/algoritmos/capitulo5/K.PNG -------------------------------------------------------------------------------- /algoritmos/capitulo5/L.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/algoritmos/capitulo5/L.PNG -------------------------------------------------------------------------------- /algoritmos/capitulo5/M.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/algoritmos/capitulo5/M.PNG -------------------------------------------------------------------------------- /algoritmos/capitulo5/N.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/algoritmos/capitulo5/N.PNG -------------------------------------------------------------------------------- /algoritmos/capitulo5/O.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/algoritmos/capitulo5/O.PNG -------------------------------------------------------------------------------- /algoritmos/capitulo5/P.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/algoritmos/capitulo5/P.PNG -------------------------------------------------------------------------------- /algoritmos/capitulo5/Q.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/algoritmos/capitulo5/Q.PNG -------------------------------------------------------------------------------- /algoritmos/capitulo5/R.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/algoritmos/capitulo5/R.PNG -------------------------------------------------------------------------------- /algoritmos/capitulo5/S.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/algoritmos/capitulo5/S.PNG -------------------------------------------------------------------------------- /arquitetura/Diretorios.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/arquitetura/Diretorios.png -------------------------------------------------------------------------------- /arquitetura/arquitetura.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/arquitetura/arquitetura.png -------------------------------------------------------------------------------- /arquitetura/distribuida.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricardodarocha/Rust/HEAD/arquitetura/distribuida.png -------------------------------------------------------------------------------- /3_api/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "api" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | actix-web = "4" -------------------------------------------------------------------------------- /4_log/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "log" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /algoritmos/capitulo5/c.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut i = 1; 3 | let mut soma=0; 4 | 5 | // Usando while 6 | while i <= 100 { 7 | soma += i; 8 | i+=1; 9 | } 10 | -------------------------------------------------------------------------------- /general/abnt_rouding.rs: -------------------------------------------------------------------------------- 1 | 2 | fn AssertAbntRounding(Input::f32) 3 | format!("{:.2}", 1.2399); // returns "1.24" 4 | format!("{:.3}", 1.2399); // returns "1.240" 5 | format!("{:.2}", 1.2); // returns "1.20" -------------------------------------------------------------------------------- /4_log/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "log" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /algoritmos/capitulo5/j.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut c = 10; 3 | 4 | while c <= 100 { 5 | let f = (9*c+160)/5; 6 | println!("Cº {:>3} {}", c, f ); 7 | c += 10; 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /7_env/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | 3 | fn main() { 4 | match env::var("USER_AGENT") { 5 | Ok(lang) => println!("Language code: {}", lang), 6 | Err(e) => println!("Couldn't read NAME ({})", e), 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /7_env/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "env" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | dotenv = "0.15.0" 10 | -------------------------------------------------------------------------------- /algoritmos/capitulo5/e.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut i = 0; 3 | 4 | // Usando while 5 | loop { 6 | if i%2 != 0 { 7 | print!("{i}", ); 8 | } 9 | 10 | if i = 20 { 11 | break; 12 | } 13 | 14 | i+=1; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /algoritmos/capitulo5/f.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut i = 1; 3 | 4 | // Usando while 5 | loop { 6 | if i%4 == 0 { 7 | println!("{i}", ); 8 | } 9 | 10 | i+=1; 11 | if i < 20 { 12 | break; 13 | } 14 | 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /algoritmos/capitulo5/k.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut i = 1; 3 | let mut q = 1; 4 | let mut soma = 0; 5 | 6 | loop { 7 | soma += q; 8 | i += 1; 9 | q *= 2; 10 | if i > 64 { 11 | break; 12 | } 13 | } 14 | println!("{soma}"); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /general/variables.rs: -------------------------------------------------------------------------------- 1 | let variable_name = value; // no type specified 2 | let variable_name:dataType = value; //type specified 3 | 4 | fn salary() { 5 | let fees = 25_000; 6 | let salary:f64 = 35_000.00; 7 | println!("fees is {} and salary is {}",fees,salary); 8 | } 9 | -------------------------------------------------------------------------------- /8_cli/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cli" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | clap = { version = "3.0", features = ["derive"] } 10 | colored = "2.0.0" 11 | -------------------------------------------------------------------------------- /5_get/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "http" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | dotenv = "0.15.0" 10 | reqwest = { version = "0.11.10", features = ["blocking"]} 11 | -------------------------------------------------------------------------------- /6_post/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "http" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | dotenv = "0.15.0" 10 | reqwest = { version = "0.11.10", features = ["blocking"]} 11 | -------------------------------------------------------------------------------- /algoritmos/capitulo5/d.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut i = 1; 3 | let mut soma=0; 4 | 5 | // Usando while 6 | loop { 7 | if i%2 == 0 { 8 | soma += i; 9 | } 10 | 11 | if i = 500 { 12 | break; 13 | } 14 | 15 | i+=1; 16 | } 17 | print!("{soma}", ); 18 | } 19 | -------------------------------------------------------------------------------- /algoritmos/capitulo5/p.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | type int = i32; 3 | let mut soma: int; 4 | let mut quant: int; 5 | 6 | for i in 50..=70 { 7 | if i % 2 == 0 { 8 | soma += i; 9 | quant += 1; 10 | } 11 | } 12 | 13 | let media = soma / quant; 14 | println!("{}, {}", soma, media); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /algoritmos/capitulo5/g.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut e = 0; 3 | let base = 3; 4 | let mut x: i32; 5 | 6 | while e <=15 { 7 | if e == 0 { 8 | x = 1; 9 | } 10 | 11 | if e == 1 { 12 | x = base; 13 | } else { 14 | x = x * base; // x *= base 15 | } 16 | 17 | print!("{}, ", x) 18 | 19 | i+=1; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /3_api/src/routes.rs: -------------------------------------------------------------------------------- 1 | use actix_web::{get, post, HttpResponse, Responder}; 2 | 3 | #[get("/")] 4 | pub async fn hello() -> impl Responder { 5 | HttpResponse::Ok().body("Hello world!") 6 | } 7 | 8 | #[post("/echo")] 9 | pub async fn echo(req_body: String) -> impl Responder { 10 | HttpResponse::Ok().body(req_body) 11 | } 12 | 13 | pub async fn manual_hello() -> impl Responder { 14 | HttpResponse::Ok().body("Hey there!") 15 | } -------------------------------------------------------------------------------- /7_env/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "dotenv" 7 | version = "0.15.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" 10 | 11 | [[package]] 12 | name = "env" 13 | version = "0.1.0" 14 | dependencies = [ 15 | "dotenv", 16 | ] 17 | -------------------------------------------------------------------------------- /general/box.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug)] 2 | struct MinhaArvore { 3 | nome: String, 4 | ramos: Option>, 5 | } 6 | 7 | fn main() { 8 | let galileu = MinhaArvore { 9 | nome: "Galileu", 10 | ramos: Some(Box::new(MinhaArvore{ 11 | nome: "Newton", 12 | ramos: Some(Box::new(MinhaArvore){ 13 | nome: "Einstein", 14 | ramos: Some(Box::new(MinhaArvore)) 15 | }) 16 | }) 17 | ) 18 | } 19 | } 20 | 21 | println!("{#?}", galileu); 22 | 23 | -------------------------------------------------------------------------------- /Sudoku/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | 3 | let mut sudo = [[0 as u8; 9]; 9]; 4 | sudo[2][3] = 1; 5 | sudo[2][4] = 5; 6 | 7 | imprimir(sudo); 8 | 9 | } 10 | 11 | fn imprimir(sudo : [[u8; 9]; 9]) { 12 | for y in sudo { 13 | print!(" "); 14 | for x in y { 15 | print!("{:?} ", x); 16 | } 17 | println!(); 18 | } 19 | } 20 | 21 | fn indice(x: u8, y: u8) -> u8 { 22 | 9*x+y 23 | } 24 | 25 | fn linha(indice: u8) -> u8 { 26 | (indice-1) / 9 27 | } 28 | 29 | fn coluna(indice: u8) -> u8 { 30 | (indice-1) % 9 31 | } 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | target/ 4 | /target/ 5 | 6 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 7 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 8 | # Cargo.lock 9 | 10 | # These are backup files generated by rustfmt 11 | **/*.rs.bk 12 | .history 13 | 14 | # Env 15 | .env 16 | 17 | # Binaries 18 | *.exe 19 | *.bin 20 | 21 | 4_log/target/ 22 | 5_get/target/ 23 | 5_get/src/.env 24 | 5_get/src/main.rs 25 | 6_post/src/main.rs 26 | 6_post/target/ 27 | 7_env/target/ 28 | -------------------------------------------------------------------------------- /actix-modules/src/main.rs: -------------------------------------------------------------------------------- 1 | #[actix_web::main] 2 | async fn main() -> std::io::Result<()> { 3 | let todo_db = repository::database::Database::new(); 4 | let app_data = web::Data::new(todo_db); 5 | 6 | HttpServer::new(move || 7 | App::new() 8 | .app_data(app_data.clone()) 9 | .configure(api::api::config) 10 | .service(healthcheck) 11 | .default_service(web::route().to(not_found)) 12 | .wrap(actix_web::middleware::Logger::default()) 13 | ) 14 | .bind(("127.0.0.1", 8080))? 15 | .run() 16 | .await 17 | } 18 | 19 | -------------------------------------------------------------------------------- /Curso/programas/pascal.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | const SIZE: usize = 10; 3 | const MAX: usize = SIZE+1; 4 | let mut pascal = [[0; MAX]; MAX]; 5 | 6 | for col in 0..MAX { 7 | for row in 0..MAX { 8 | if (col + row) >= MAX { continue }; 9 | if (col > 0) && (row > 0) { 10 | pascal[col][row] = pascal[col - 1][row] + pascal[col][row - 1]; 11 | } else { 12 | pascal[col][row] = 1; 13 | } 14 | 15 | print!("{:5}", pascal[col][row]); 16 | } 17 | println!("\n"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /algoritmos/capitulo5/i.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut anterior = 0; //experimente comentar esta linha 3 | let mut atual = 0; 4 | let mut proximo = 1; 5 | let mut contador = 1; 6 | 7 | loop{ 8 | println!("{:>2} {} ", contador, atual); 9 | 10 | anterior = proximo; 11 | proximo = atual; 12 | atual = anterior + proximo; 13 | contador+=1; 14 | } 15 | } 16 | 17 | /// warning: unused variable: `anterior` 18 | /// let mut anterior = 0; 19 | /// | ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_anterior` 20 | /// | 21 | /// = note: `#[warn(unused_variables)]` on by default 22 | -------------------------------------------------------------------------------- /algoritmos/capitulo5/a.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut i = 15; 3 | 4 | // Usando while 5 | while i <= 200 { 6 | println!("{}", i * i); // Imprime i^2 7 | i += 1; 8 | } 9 | 10 | // Usando loop 11 | loop { 12 | if i > 200 { 13 | break; 14 | } 15 | println!("{}", i * i); // Imprime i^2 16 | i += 1; 17 | } 18 | 19 | // Simples 20 | // Usando for sem intervalo implícito e sem iter 21 | for i in 15..=200 { 22 | println!("{}", i * i); // Imprime i^2 23 | } 24 | 25 | //avançado 26 | //Usando for com intervalo implícito (com iter() e map): 27 | (15..=200).for_each(|i| println!("{}", i * i)); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /actix-modules/src/api.rs: -------------------------------------------------------------------------------- 1 | use actix_web::web; 2 | use actix_web::{web::{ 3 | Data, 4 | Json, 5 | }, post, HttpResponse}; 6 | use crate::{models::todo::Todo, repository::database::Database}; 7 | 8 | 9 | #[post("/todos")] 10 | pub async fn create_todo(db: Data, new_todo: Json) -> HttpResponse { 11 | let todo = db.create_todo(new_todo.into_inner()); 12 | match todo { 13 | Ok(todo) => HttpResponse::Ok().json(todo), 14 | Err(err) => HttpResponse::InternalServerError().body(err.to_string()), 15 | } 16 | } 17 | 18 | 19 | pub fn config(cfg: &mut web::ServiceConfig) { 20 | cfg.service( 21 | web::scope("/api") 22 | .service(create_todo) 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /Curadoria/Readme.md: -------------------------------------------------------------------------------- 1 | # Curadoria de projetos Rust 2 | 3 | A primeira referência que você poderá consultar para acompanhar tudo o que está sendo feito em Rust é o blog universal 4 | https://www.areweguiyet.com/ 5 | 6 | Em seguida eu elenco alguns dos projetos que eu mesmo analisei e achei incrível 7 | 8 | Apis e Servidores 9 | Arquivos 10 | Bancos de Dados 11 | BI 12 | Bibliotecas 13 | Ferramentas 14 | Games 15 | Interface Gráfica 16 | Json 17 | Módulos 18 | Tecnologias 19 | 20 | Windows 21 | 22 | --- 23 | Editores e Extensões 24 | 25 | Eu recomendo utilizar o Editor Gratuito VSCODE com a extensão Rust Analyser 26 | Se você está aprendendo Rust, poderá instalar a extensão Rust Analyser e deixá-la desabilitada até acostumar. 27 | -------------------------------------------------------------------------------- /8_cli/src/main.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused)] 2 | 3 | use clap::Parser; 4 | use colored::*; 5 | 6 | /// Search for a word in a file and display the lines that contain it. 7 | #[derive(Parser)] 8 | struct Cli { 9 | /// The word to look for 10 | word: String, 11 | /// The filename to the file to read 12 | #[clap(parse(from_os_str))] 13 | filename: std::path::PathBuf, 14 | } 15 | 16 | fn main() { 17 | 18 | let args = Cli::parse(); 19 | println!("searching for {}", &args.word.red()); 20 | let content = std::fs::read_to_string(&args.filename) 21 | .expect("could not read file"); 22 | 23 | for line in content.lines() { 24 | if line.contains(&args.word) { 25 | println!("{}", line.replace(&args.word,&args.word.red())); 26 | } 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /3_api/src/main.rs: -------------------------------------------------------------------------------- 1 | //Run > cargo run 8085 2 | 3 | use actix_web::{web, App, HttpServer}; 4 | use std::env; 5 | mod routes; 6 | 7 | #[actix_web::main] 8 | async fn main() -> std::io::Result<()> { 9 | let args: Vec<_> = env::args().collect(); 10 | let port = &args[1]; 11 | let port: u16 = match port.parse() { 12 | Ok(number) => { 13 | number 14 | }, 15 | Err(_) => { 16 | 8000 17 | }, 18 | }; 19 | 20 | println!("Running on port ... http://localhost:{port}"); 21 | 22 | HttpServer::new(|| { 23 | App::new() 24 | .service(routes::hello) 25 | .service(routes::echo) 26 | .route("/hey", web::get().to(routes::manual_hello)) 27 | }) 28 | .bind(("127.0.0.1", port))? 29 | .run() 30 | .await 31 | } -------------------------------------------------------------------------------- /actix-modules/src/models.rs: -------------------------------------------------------------------------------- 1 | // Neste arquivo são criadas as regras de negócios e as estruturas de dados, entidades, agregados, value objects e tipos, podendo ser dividida em submódulos para cada propósito 2 | 3 | pub mod types { 4 | use chrono::prelude::{DateTime, Utc}; 5 | type Id = String; 6 | type DataHora = DateTime; 7 | } 8 | 9 | pub mod entity { 10 | //Eu deixei a entidade para poder ser acessada pela layer models::Todo porém em geral as entidades ficam neste pacote sendo expostos apenas os seus agregados 11 | } 12 | use serde::{Deserialize, Serialize}; 13 | 14 | #[derive(Serialize, Deserialize, Debug, Clone)] 15 | pub struct Todo { 16 | pub id: Option, 17 | pub title: String, 18 | pub description: Option, 19 | pub created_at: Option, 20 | pub updated_at: Option, 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /general/default.md: -------------------------------------------------------------------------------- 1 | 2 | # Valores Default 3 | 4 | Imagine o seguinte conjunto de emojis representando um jogo da velha. 5 | Queremos iniciar nosso jogo da velha sempre com o valor "vazio" 6 | 7 | Nós podemos criar um enumerado com a diretiva `derive(Default)` ou implementar o trait Default. As duas formas são equivalentes 8 | 9 | ⭕❌⬜ 10 | 11 | ### Forma 1 12 | 13 | ```Rust 14 | #[derive(Default)] 15 | enum Tab{ 16 | O, 17 | X, 18 | #[default] 19 | Vazio 20 | } 21 | ``` 22 | 23 | ### Forma 2 24 | 25 | ```Rust 26 | enum Piece{O, X, Vazio} 27 | impl Default for Tab -> Self {Piece::Vazio} 28 | ``` 29 | 30 | o trait Default também pode ser implementado para objetos 31 | 32 | ``` 33 | struct Jogador { 34 | nome: String, 35 | idade: u16} 36 | 37 | impl Default for Jogador -> Self { 38 | Jogador { 39 | nome: "Anônimo".to_own, 40 | idade: 0 41 | } 42 | } 43 | ``` 44 | -------------------------------------------------------------------------------- /algoritmos/capitulo5/s.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | macro_rules! leia { 3 | ($var:ident : $t:ty) => { 4 | { 5 | use std::io::{self, Write}; 6 | let mut input = String::new(); 7 | println!("informe {}: ", stringify!($var)); 8 | io::stdout().flush().unwrap(); 9 | io::stdin().read_line(&mut input).expect("Falha ao ler entrada"); 10 | input = input.trim().to_string(); 11 | print!("> {}\n", input); 12 | $var = input.parse::<$t>().expect("Falha na conversão do valor"); 13 | } 14 | }; 15 | } 16 | type int = i32; 17 | 18 | fn main() { 19 | let mut q = 0; 20 | 21 | let mut a: int; 22 | leia!(a: int); 23 | 24 | let mut b: int; 25 | leia!(b: int); 26 | 27 | if b != 0 { 28 | if a > b { 29 | while q * b < a { 30 | q += 1; 31 | } 32 | } 33 | println!("{a}/{b}={q}"); 34 | } else { 35 | println!("indeterminação"; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /algoritmos/capitulo5/o.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | for contador in 1..=10 { //----------------------------+ 3 | let mut numero = contador; // | 4 | let mut fatorial = numero; // | 5 | // | 6 | while numero > 1 { //------+ // | 7 | print!("{}, ", fatorial); //🔥 // | // | 8 | numero = numero - 1; // | // | 9 | fatorial = numero * fatorial; // | // | 10 | } //------+ // | 11 | // | 12 | contador = contador + 2; // | 13 | println!("SOMA == {}", soma); // | 14 | // | 15 | } //-----------------------------+ 16 | println!("---------------------"); 17 | println!("fim do programa") 18 | 19 | } 20 | -------------------------------------------------------------------------------- /actix-modules/src/repo/database.rs: -------------------------------------------------------------------------------- 1 | // Esta camada simula uma conexão com o banco de dados, porém neste exemplo os dados são persistidos na memória 2 | use std::fmt::Error; 3 | use chrono::prelude::*; 4 | use std::sync::{Arc, Mutex}; 5 | 6 | use crate::models::todo::Todo; 7 | 8 | pub struct Database { 9 | pub todos: Arc>>, 10 | } 11 | 12 | impl Database { 13 | pub fn new() -> Self { 14 | let todos = Arc::new(Mutex::new(vec![])); 15 | Database { todos } 16 | } 17 | 18 | pub fn create_todo(&self, todo: Todo) -> Result { 19 | let mut todos = self.todos.lock().unwrap(); 20 | let id = uuid::Uuid::new_v4().to_string(); 21 | let created_at = Utc::now(); 22 | let updated_at = Utc::now(); 23 | let todo = Todo { 24 | id: Some(id), 25 | created_at: Some(created_at), 26 | updated_at: Some(updated_at), 27 | ..todo 28 | }; 29 | todos.push(todo.clone()); 30 | Ok(todo) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /general/tests_and_docs.md: -------------------------------------------------------------------------------- 1 | # In this section 2 | 3 | I will do an overview of 2 kind of relevant rust code structures 4 | They are code **documentation** and code **tests** 5 | 6 | to give your code documentation superpower just write comments with 3 /// instead of 2 // 7 | 8 | /// will appear as discussion text at generated documentaion 9 | 10 | lets create an example 11 | ```Rust 12 | /// this method provides a very good aproximation of pi using the ratio 22/7 13 | fn rpi {22/7} 14 | /// # Examples 15 | /// ``` 16 | ///fn circleArea (r) { 17 | /// 18 | /// r * r * rpi() 19 | ///} 20 | /// ``` 21 | ``` 22 | You can also write testable sentence inside those comment strucutures 23 | Use **cargo rustdoc --test** to try this 24 | 25 | ```Rust 26 | /// ``` 27 | /// // You can have rust code between fences inside the comments 28 | /// // If you pass --test to `rustdoc`, it will even test it for you! 29 | /// let a = circleArea(1); 30 | /// assert!(a, rpi()) 31 | /// let b = circleArea(5); 32 | /// assert!(b, 25 * rpi()) 33 | /// ``` 34 | ``` 35 | -------------------------------------------------------------------------------- /algoritmos/capitulo5/q.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | macro_rules! leia { 3 | ($var:ident : $t:ty) => { 4 | { 5 | use std::io::{self, Write}; 6 | let mut input = String::new(); 7 | println!("informe {}: ", stringify!($var)); 8 | io::stdout().flush().unwrap(); 9 | io::stdin().read_line(&mut input).expect("Falha ao ler entrada"); 10 | input = input.trim().to_string(); 11 | print!("> {}\n", input); 12 | $var = input.parse::<$t>().expect("Falha na conversão do valor"); 13 | } 14 | }; 15 | } 16 | type Inteiro = i64; 17 | type Texto = String; 18 | 19 | fn main() { 20 | 21 | loop { 22 | let nome: String; 23 | let comp: Inteiro; 24 | let larg: Inteiro; 25 | leia!(nome: String); 26 | leia!(comp: Inteiro); 27 | leia!(larg: Inteiro); 28 | 29 | println!("área_{nome} = {area} m²", area = comp * larg); 30 | // leia!(input: String); 31 | // if input == "NÃO" { break } 32 | 33 | println!("\nPróximo\nPara interromper, pressione "); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /algoritmos/capitulo5/n.rs: -------------------------------------------------------------------------------- 1 | #![allow(non_camel_case_types)] 2 | #![allow(dead_code)] 3 | #![allow(unused)] 4 | 5 | macro_rules! leia { 6 | ($var:ident : $t:ty) => { 7 | { 8 | use std::io::{self, Write}; 9 | let mut input = String::new(); 10 | // println!("o sistema está aguardando digitar um valor para {}: ", stringify!($var)); 11 | io::stdout().flush().unwrap(); 12 | io::stdin().read_line(&mut input).expect("Falha ao ler entrada"); 13 | input = input.trim().to_string(); 14 | print!("> {}\n", input); 15 | $var = input.parse::<$t>().expect("Falha na conversão do valor"); 16 | } 17 | }; 18 | } 19 | type Inteiro = i64; 20 | type int = i64; 21 | 22 | fn main() { 23 | let mut soma = 0; 24 | let mut contador = 0; 25 | 26 | loop { 27 | let mut numero: int; 28 | leia!(numero: int); 29 | if numero >= 0 { 30 | soma += numero; 31 | continue; 32 | } else { 33 | break 34 | } 35 | } 36 | 37 | print!("{soma}, {media}, {contador}", soma, media = soma/quant, contador); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /algoritmos/capitulo5/h.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | #![allow(unused)] 3 | macro_rules! leia { 4 | ($var:ident : $t:ty) => { 5 | { 6 | use std::io::{self, Write}; 7 | let mut input = String::new(); 8 | // println!("o sistema está aguardando digitar um valor para {}: ", stringify!($var)); 9 | io::stdout().flush().unwrap(); 10 | io::stdin().read_line(&mut input).expect("Falha ao ler entrada"); 11 | input = input.trim().to_string(); 12 | print!("> {}\n", input); 13 | $var = input.parse::<$t>().expect("Falha na conversão do valor"); 14 | } 15 | }; 16 | } 17 | type int = i64; 18 | 19 | fn main() { 20 | let mut base: int; 21 | let mut eleva: int; 22 | 23 | let mut x: i32; 24 | let mut e = 0; 25 | 26 | loop { 27 | if e == 0 { 28 | x = 1; 29 | } 30 | 31 | if e == 1 { 32 | x = base; 33 | } else { 34 | x = x * base; // x *= base 35 | } 36 | 37 | print!("{}, ", x) 38 | 39 | i+=1; 40 | 41 | if e > eleva break; 42 | } 43 | 44 | print!("{x}"); 45 | 46 | } 47 | -------------------------------------------------------------------------------- /algoritmos/capitulo5/r.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | macro_rules! leia { 3 | ($var:ident : $t:ty) => { 4 | { 5 | use std::io::{self, Write}; 6 | let mut input = String::new(); 7 | println!("informe {}: ", stringify!($var)); 8 | io::stdout().flush().unwrap(); 9 | io::stdin().read_line(&mut input).expect("Falha ao ler entrada"); 10 | input = input.trim().to_string(); 11 | print!("> {}\n", input); 12 | $var = input.parse::<$t>().expect("Falha na conversão do valor"); 13 | } 14 | }; 15 | } 16 | type Real = f64; 17 | 18 | fn main() { 19 | 20 | loop { 21 | let num1: Real; 22 | let mut maior = num1; 23 | let mut menor = num1; 24 | 25 | let mut numero: Real; 26 | 27 | if numero < 0 { 28 | break 29 | } else 30 | { 31 | if numero > maior { 32 | maior = numero; 33 | } 34 | if numero < menor { 35 | menor = numero; 36 | } 37 | } 38 | 39 | println!("Para interromper, informe < 0"); 40 | continue; 41 | } 42 | println!(">{maior}, <{menor}); 43 | 44 | } 45 | -------------------------------------------------------------------------------- /algoritmos/capitulo5/m.rs: -------------------------------------------------------------------------------- 1 | #![allow(non_camel_case_types)] 2 | #![allow(dead_code)] 3 | #![allow(unused)] 4 | 5 | macro_rules! leia { 6 | ($var:ident : $t:ty) => { 7 | { 8 | use std::io::{self, Write}; 9 | let mut input = String::new(); 10 | // println!("o sistema está aguardando digitar um valor para {}: ", stringify!($var)); 11 | io::stdout().flush().unwrap(); 12 | io::stdin().read_line(&mut input).expect("Falha ao ler entrada"); 13 | input = input.trim().to_string(); 14 | print!("> {}\n", input); 15 | $var = input.parse::<$t>().expect("Falha na conversão do valor"); 16 | } 17 | }; 18 | } 19 | type Inteiro = i64; 20 | type int = i64; 21 | 22 | fn main() { 23 | let mut contador = 0; 24 | let quant = 10; 25 | let mut soma = 0; 26 | 27 | loop { 28 | let mut numero: int; 29 | leia!(numero: int); 30 | soma += numero; 31 | contador += 1; 32 | 33 | if contador <= quant { 34 | continue 35 | } else { 36 | break 37 | } 38 | } 39 | 40 | print!("{soma}, {media}", soma, media = soma/quant); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /general/correspondencia.rs: -------------------------------------------------------------------------------- 1 | # O padrão Match 2 | 3 | o padrão match é um dos recursos mais importantes da linguagem Rust 4 | 5 | ```Rust 6 | let x: i32 = 1; 7 | 8 | match x { 9 | 1 => println!("um"), 10 | 2 => println!("dois"), 11 | 3 => println!("três"), 12 | - => println!("outro qualquer"), 13 | } 14 | ``` 15 | 16 | ```Rust 17 | let x = Some(5); 18 | //let y = 10; //Isto jamais será usado 19 | 20 | match x { 21 | Some(1) => println!("um"), 22 | 1|2 => println!("um ou dois"), 23 | 3..9 => println!("três .. nove"), 24 | Some(y) => println!("{}", y), 25 | _ => println!("qualqeur outro"), 26 | } 27 | ``` 28 | 29 | ```Rust 30 | enum Color { 31 | Rgb(i32,i32,i32), 32 | Hsv (i32,i32,i32), 33 | } 34 | 35 | let color = Hsv(0, 160, 255); 36 | 37 | match color { 38 | Collor::Rgb(r, g, b) => println!("RGB {} {} {} ", r, g, b), 39 | Collor::Hsv(h, s, v) => println!("HSV {} {} {} ", h, s, v), 40 | } 41 | ``` 42 | 43 | ```Rust 44 | type IRPF = (f32, f32); 45 | let renda = 3_000f32; 46 | 47 | let tax: IRPF = 48 | match renda { 49 | 0..1_903.98 => IRPF(0, 0), 50 | 1_903.99..2_826.65 => IRPF(7.5, 142.80), 51 | 2_826.66..3_751.05 => IRPF(15.0, 354.80), 52 | 3_751.06..4_664.68 => IRPF(22.5, 636.13), 53 | 4_664.68.. => IRPF(27.5, 869.36) 54 | } 55 | ``` 56 | 57 | https://www.youtube.com/watch?v=8_HPKGZGM5I _em inglês_ 58 | -------------------------------------------------------------------------------- /algoritmos/capitulo5/b.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | #![allow(unused)] 3 | macro_rules! imprima { 4 | ($($arg:tt)*) => {{ 5 | let formatted = format!("{}", format_args!($($arg)*)); 6 | let formatted = formatted 7 | .replace("true", "V") 8 | .replace("false", "F"); 9 | println!("{}", formatted); 10 | }}; 11 | } 12 | macro_rules! leia { 13 | ($var:ident : $t:ty) => { 14 | { 15 | use std::io::{self, Write}; 16 | let mut input = String::new(); 17 | // println!("o sistema está aguardando digitar um valor para {}: ", stringify!($var)); 18 | io::stdout().flush().unwrap(); 19 | io::stdin().read_line(&mut input).expect("Falha ao ler entrada"); 20 | input = input.trim().to_string(); 21 | print!("> {}\n", input); 22 | $var = input.parse::<$t>().expect("Falha na conversão do valor"); 23 | } 24 | }; 25 | } 26 | type Inteiro = i64; 27 | type Texto = String; 28 | 29 | fn main { 30 | let mut numero: Inteiro; 31 | imprima!("Informe um número", ); 32 | leia!(numero: Inteiro); 33 | 34 | imprima!("Tabuada do {numero} ", ); 35 | imprima!("====================", ); 36 | for i in 0..10 { 37 | imprima!("{numero} * {i} = {}" , numero * i); // Imprime numero * i 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /Curso/programas/consumo_pedidos.rs: -------------------------------------------------------------------------------- 1 | const CAMISAS: usize = 3; 2 | const BOTOES: usize = 2; 3 | const MESES: usize = 2; 4 | 5 | 6 | /// Matriz pedidos[CAMISAS][MESES] 7 | 8 | /// Camisa Maio Junho 9 | /// 0 100 50 10 | /// 1 50 100 11 | /// 2 50 50 12 | /// 🧮 Cálculo do Consumo 13 | 14 | /// O consumo de cada botão em cada mês é dado por: 15 | 16 | /// consumo[b][m] = Σ ( pedidos[c][m] * produtos[c][b] ) 17 | 18 | /// 📊 Resultado Final 19 | /// Mês Botão Consumo 20 | /// Maio P 500 21 | /// Maio G 1150 22 | /// Junho P 400 23 | /// Junho G 1150 24 | 25 | fn main() { 26 | let nome_botao: [&str; BOTOES] = ["P", "G"]; 27 | let nome_mes: [&str; MESES] = ["Maio", "Junho"]; 28 | 29 | let produtos: [[i32; BOTOES]; CAMISAS] = [ 30 | [3, 6], 31 | [1, 5], 32 | [3, 5], 33 | ]; 34 | 35 | let pedidos: [[i32; MESES]; CAMISAS] = [ 36 | [100, 50], 37 | [50, 100], 38 | [50, 50], 39 | ]; 40 | 41 | let mut consumo: [[i32; MESES]; BOTOES] = [[0; MESES]; BOTOES]; 42 | 43 | for m in 0..MESES { 44 | for b in 0..BOTOES { 45 | consumo[b][m] = 0; 46 | for c in 0..CAMISAS { 47 | consumo[b][m] += pedidos[c][m] * produtos[c][b]; 48 | } 49 | println!("{:6} {:3} {:-6}.00", nome_mes[m], nome_botao[b], consumo[b][m]); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /3_api/src/like.rs: -------------------------------------------------------------------------------- 1 | pub type Likes = Response; 2 | 3 | #[derive(Debug, Deserialize, Serialize)] 4 | pub struct Like { 5 | pub id: String, 6 | pub created_at: DateTime, 7 | } 8 | 9 | impl Like { 10 | pub fn new() -> Self { 11 | Self { 12 | id: Uuid::new_v4().to_string(), 13 | created_at: Utc::now(), 14 | } 15 | } 16 | } 17 | 18 | /// list last 50 likes from a tweet `/tweets/{id}/likes` 19 | #[get("/tweets/{id}/likes")] 20 | pub async fn list(path: Path<(String,)>) -> HttpResponse { 21 | // TODO find likes by tweet ID and return them 22 | let likes = Likes { results: vec![] }; 23 | 24 | HttpResponse::Ok() 25 | .content_type(APPLICATION_JSON) 26 | .json(likes) 27 | } 28 | 29 | /// add one like to a tweet `/tweets/{id}/likes` 30 | #[post("/tweets/{id}/likes")] 31 | pub async fn plus_one(path: Path<(String,)>) -> HttpResponse { 32 | // TODO add one like to a tweet 33 | let like = Like::new(); 34 | 35 | HttpResponse::Created() 36 | .content_type(APPLICATION_JSON) 37 | .json(like) 38 | } 39 | 40 | /// remove one like from a tweet `/tweets/{id}/likes` 41 | #[delete("/tweets/{id}/likes")] 42 | pub async fn minus_one(path: Path<(String,)>) -> HttpResponse { 43 | // TODO remove one like to a tweet 44 | HttpResponse::NoContent() 45 | .content_type(APPLICATION_JSON) 46 | .await 47 | .unwrap() 48 | } -------------------------------------------------------------------------------- /general/errorhandling.md: -------------------------------------------------------------------------------- 1 | # Raise an error 2 | 3 | ```Rust 4 | fn exit(x: i32) { 5 | if x == 0 { 6 | panic!("we got a 0"); 7 | } 8 | println!("things are fine") 9 | } 10 | ``` 11 | 12 | There is a difference between `enum Result` and `enum Option` 13 | 14 | ```Rust 15 | enum Result{ 16 | Ok(T), 17 | Err(E) 18 | } 19 | ``` 20 | 21 | ```Rust 22 | enum Option{ 23 | Some(T), 24 | None 25 | } 26 | ``` 27 | 28 | As we can see both can help handling errors, lets talk about the differences 29 | 30 | ```Rust 31 | let f: File = match f { 32 | Ok(file: File) => file, 33 | Err(error: Error) => panic!("Fail {:?}", error), 34 | }; 35 | let f: File = match f { 36 | Some(file: File) => file, 37 | None => panic!("Fail with a unknown error"), 38 | }; 39 | ``` 40 | 41 | A most sofysticated example 42 | 43 | ```Rust 44 | let f: File = match f { 45 | Ok(file: File) => file, 46 | Err(error: Error) => match error.kind() { 47 | ErrorKind::NotFound => match File::create("filename.txt") { 48 | Ok(fc: File) => fc, 49 | Err(e: Error) => panic!("Error creating file {:?}", e) 50 | }, 51 | otterError: ErrorKind => { 52 | panic!("Error {:?}", otherError) 53 | } 54 | 55 | 56 | }, 57 | }; 58 | ``` 59 | 60 | What about a non versobse sollution 61 | 62 | ```Rust 63 | let f = File::open("filename.txt").wnrap(); 64 | let f = File::open("filename.txt").expect("Couldn't open file"); 65 | let f = File::open("filename.txt")? 66 | ``` 67 | -------------------------------------------------------------------------------- /algoritmos/capitulo5/l.rs: -------------------------------------------------------------------------------- 1 | #![allow(non_camel_case_types)] 2 | #![allow(dead_code)] 3 | #![allow(unused)] 4 | 5 | macro_rules! leia { 6 | ($var:ident : $t:ty) => { 7 | { 8 | use std::io::{self, Write}; 9 | let mut input = String::new(); 10 | // println!("o sistema está aguardando digitar um valor para {}: ", stringify!($var)); 11 | io::stdout().flush().unwrap(); 12 | io::stdin().read_line(&mut input).expect("Falha ao ler entrada"); 13 | input = input.trim().to_string(); 14 | print!("> {}\n", input); 15 | $var = input.parse::<$t>().expect("Falha na conversão do valor"); 16 | } 17 | }; 18 | } 19 | type Inteiro = i64; 20 | type int = i64; 21 | 22 | fn main() { 23 | let mut contador = 1; 24 | let mut soma = 0; 25 | let max = 9; 26 | 27 | loop { 28 | print!("\nInforme um número [{n}/{m}]", n = contador, m = max); 29 | let mut numero: int; 30 | leia!(numero: int); 31 | 32 | let mut fatorial = numero; 33 | 34 | while numero > 1 { 35 | print!("{}, ", fatorial); //🔥 36 | numero = numero - 1; 37 | fatorial = numero * fatorial; 38 | } 39 | 40 | soma = soma + fatorial; 41 | print!("= {} \n", fatorial); //🔥 42 | 43 | contador = contador + 1; 44 | if contador > max { 45 | break; 46 | } 47 | } 48 | println!("\n---------------------"); 49 | println!("SOMA == {}", soma); 50 | println!("---------------------"); 51 | println!("fim do programa") 52 | 53 | } 54 | -------------------------------------------------------------------------------- /9_calculadora/main.rs: -------------------------------------------------------------------------------- 1 | // Este exemplo é uma contribuição de vários colegas da comunidade Rust do Telegram. Nos encontre lá 🦀 2 | // Eu modifiquei este exemplo para trabalhar com hashmap + anonymous function. O exemplo inicial usava arrow function apenas. 3 | 4 | use std::{io, collections::HashMap}; 5 | 6 | fn perform_operation(expression: &str, signal: char, op: impl Fn(f32, f32) -> f32) { 7 | let values: Vec<&str> = expression 8 | .split(signal) 9 | .map(|s| s.trim()) 10 | .collect(); 11 | let f = op( 12 | values[0].trim().parse::().unwrap(), 13 | values[1].trim().parse::().unwrap(), 14 | ); 15 | println!("The result is ->: {}", f); 16 | } 17 | 18 | fn main() { 19 | println!("============================= Simples calculator Example ====================================="); 20 | println!("Your operations need to follow the pattern as in the example: '5-2', '5+2', '5*2', '5/2'"); 21 | 22 | let signals_aritimetic = ['+', '-', '/', '*']; 23 | 24 | let mut engine = HashMap:: f32>::new(); 25 | engine.insert('*', |x, y| x * y); 26 | engine.insert('/', |x, y| x / y); 27 | engine.insert('+', |x, y| x + y); 28 | engine.insert('-', |x, y| x - y); 29 | 30 | println!("Enter your operation: "); 31 | 32 | let mut operation = String::new(); 33 | 34 | io::stdin() 35 | .read_line(&mut operation) 36 | .expect("Failed to get operation"); 37 | 38 | for &signal in signals_aritimetic.iter() { 39 | if let Some(_result) = operation.find(signal) { 40 | perform_operation(&operation, signal, engine[&signal]) 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /actix-modules/readme.md: -------------------------------------------------------------------------------- 1 | # Actix Modules 2 | 3 | ## Intro 4 | 5 | 🐺 Este é um exemplo básico sobre **criação de APIS com o RUST** 6 | Neste exemplo eu mostro as seguintes features 7 | - Criação de módulos 8 | - Uuid 9 | - Chrono 10 | 11 | Partindo do exemplo actix 2 (ver diretório rust/actix) nós fazemos algumas refatorações para quebrar o projeto em módulos 12 | Instale a linha de comando cargo mod para lhe auxiliar 13 | ``` 14 | cargo install cargo-mod 15 | cargo mod api 16 | cargo mod models 17 | cargo mod repo 18 | ``` 19 | 20 | ### Hierarquia de diretórios 21 | 22 | Neste exemplo nós dividimos a aplicação em três camadas começando pela camada de aplicação **api**. Esta camada também é comumente chamada **app** a depender do propósito da aplicação. Por exemplo, 23 | sendo um servidor de páginas html com várias rotas para renderizar uma aplicação vue-js, react ou svelte, ou uma aplicação com Interface do usuário, poderia ser chamado app. 24 | Ainda em se tratando de uma aplicação de linha de comando, cli, poderia ser chamado **cli** etc. O importante é que esta seja a _camada da aplicação_, ou seja, o nível mais próximo do usuário, a interface da aplicação. 25 | 26 | A pasta **models** é o core, ou domínio da aplicação, onde ficarão as regras de negócios junto com os modelos (aggregates, entidades, value objects) 27 | Esta pasta pode ou não ser divididas em subpastas por exemplo 28 | ``` 29 | models 30 | types 31 | interfaces 32 | entity 33 | valueobjecs 34 | dto 35 | ``` 36 | 37 | A pasta **repo** o **repository** é onde ficam as implementações do repositório, seja uma layer mock, uma camada de persistência para múltiplos bancos de dados ou um sistema de arquivos 38 | 39 | ### 40 | -------------------------------------------------------------------------------- /general/matrizes.md: -------------------------------------------------------------------------------- 1 | # Matrizes 2 | 3 | Há duas formas de trabalhar com matrizes no Rust, o que deverá ser levado em conta é se a matriz pussui dados constantes ou mutáveis, e se o tamamho da matriz é constante ou mutável. 4 | 5 | Uma matriz de tamanho constante pode ser representado como um array 6 | 7 | ## Array 8 | 9 | ```Rust 10 | let fib9 = [1,1,2,3,5,8,11,19,30] 11 | //o mesmo 12 | let fib9: [u8;9] = [1,1,2,3,5,8,11,19,30]; 13 | ``` 14 | 15 | Note que esta array não pode ser alterada. 16 | E também não podem ser inseridos novos valores nesta array. 17 | 18 | ## Arrays mutáveis 19 | 20 | Para trabalhar com um array mutável adiciona a palavra mut 21 | 22 | ```Rust 23 | let mut fib9: [u8;9] = [1,1,2,3,5,8,11,19,30]; 24 | fib9[0]=0 25 | ``` 26 | 27 | Agora podemos alterar um elemento deste array, contanto que o elemento esteja no intervalo \[0..9\] 28 | No entanto ainda não é possível inserir um novo elemento no array; Isto porque o array é um tipo de tamanho constante em Rust. 29 | 30 | ## Matrizes dinâmicas, Vetores 31 | 32 | Para trabalhar com matrizes dinâmicas é necessário declarar o tipo vetor 33 | 34 | ```Rust 35 | let mut fib9: Vec = vec![1,1,2,3,5,8,11,19,30]; 36 | fib9[0]=0; 37 | print!("{:?}", fib9) 38 | ``` 39 | 40 | Para inserir novos elementos é necessário chamar o método **push()** 41 | 42 | ```Rust 43 | let mut fib9: Vec = vec![1,1,2,3,5,8,11,19,30]; 44 | fib9.push(49); 45 | print!("{:?}", fib9) 46 | ``` 47 | 48 | # Matrizes bidimensionais 49 | 50 | ```Rust 51 | let mut vec = vec![vec!['⬜'; 3]; 3]; 52 | fn renderizar(board:&Vec>) { 53 | for i in 0..3 { 54 | for j in 0..3 { 55 | print!("{}", board[i][j]) 56 | } 57 | print!("\n") 58 | } 59 | print!("\n") 60 | 61 | } 62 | 63 | ``` 64 | -------------------------------------------------------------------------------- /Curso/programas/bhaskara.rs: -------------------------------------------------------------------------------- 1 | pub mod portugol { 2 | #[macro_export] 3 | macro_rules! leia { 4 | ($var:ident : $t:ty) => { 5 | { 6 | use std::io::{self, Write}; 7 | let mut input = String::new(); 8 | println!(" informe o campo {}:{} ", stringify!($var), stringify!($t), ); 9 | io::stdout().flush().unwrap(); 10 | io::stdin().read_line(&mut input).expect("Falha ao ler entrada"); 11 | input = input.trim().to_string(); 12 | print!("> {}\n", input); 13 | $var = input.parse::<$t>().expect("Falha na conversão do valor"); 14 | } 15 | }; 16 | } 17 | } 18 | 19 | pub mod bhaskara { 20 | 21 | pub type Num = f32; 22 | 23 | #[derive(Debug)] 24 | pub enum BResult { 25 | //f32 = (+-)0..2^5 26 | DuasRaizes(Num, Num), 27 | UmaRaiz(Num), 28 | Erro(String) 29 | } 30 | 31 | 32 | /// (X1, X2) 33 | /// X 34 | /// Erro -> a=0 (Nao e funcao do segundo grau) 35 | /// Erro -> delta=<0 (Nao existe raiz real) 36 | pub fn calc(a: Num, b: Num, c: Num) -> BResult { 37 | 38 | if a==0.0 { 39 | return BResult::Erro("Não é uma equação do segundo grau".to_string()); 40 | } 41 | 42 | let delta = b*b-4.0*a*c; 43 | if delta < 0.0 { 44 | return BResult::Erro("Nao possui raizes reais".to_string()); 45 | } 46 | 47 | if delta == 0.0 { 48 | return BResult::UmaRaiz(-b / 2.0*a); 49 | } 50 | 51 | let x1 = -b + f32::sqrt(delta)/ 2.0*a; 52 | let x2 = -b - f32::sqrt(delta)/ 2.0*a; 53 | 54 | 55 | return BResult::DuasRaizes(x1, x2); 56 | } 57 | } 58 | 59 | fn main() { 60 | let (a, b, c):(f32, f32, f32); 61 | leia!(a: f32); 62 | leia!(b: f32); 63 | leia!(c: f32); 64 | let result = bhaskara::calc(a, b, c); 65 | println!("{:?}", result); 66 | 67 | } 68 | -------------------------------------------------------------------------------- /general/tictactoe.rs: -------------------------------------------------------------------------------- 1 | enum Player {X, O} 2 | 3 | impl Player { 4 | fn next(&self) -> Player { 5 | match self { 6 | Player::X => Player::O, 7 | Player::O => Player::X, 8 | } 9 | 10 | fn render(&self) { 11 | match self{ 12 | Player::X => "🍎", 13 | Player::O => "🍏", 14 | } 15 | } 16 | } 17 | 18 | #[derive(Clone)] 19 | enum BitBoard {Player(Player), Empty} 20 | 21 | enum Winner {X, O, Empty} 22 | 23 | use BitBoard::Any as x; 24 | use std::io::stdin; 25 | 26 | fn winner(board: &Vec, player: Winner) -> Winner { 27 | match board[..] { 28 | [ x , x , x , _ , _ , _ , _ , _ , _ ] | 29 | [ _ , _ , _ , x , x , x , _ , _ , _ ] | 30 | [ _ , _ , _ , _ , _ , _ , x , x , x ] | 31 | [ x , _ , _ , _ , x , _ , _ , _ , x ] | 32 | [ x , _ , _ , x , _ , _ , x , _ , _ ] | 33 | [ _ , x , _ , _ , x , _ , _ , x , _ ] | 34 | [ _ , _ , x , _ , _ , x , _ , _ , x ] => player, 35 | _ => Winner::Empty 36 | } 37 | } 38 | 39 | fn render(board: &Vec) { 40 | format!("{} {} {} 41 | {} {} {} 42 | {} {} {}", board[0], 43 | board[1], 44 | board[2], 45 | board[3], ) 46 | } 47 | 48 | fn main() { 49 | let mut board_x = vec![BitBoard::Empty; 9]; 50 | let mut board_o = vec![BitBoard::Empty; 9]; 51 | 52 | let mut player = Player::X; 53 | 54 | loop { 55 | let mut input = String::new(); 56 | stdin() 57 | .read(&mut input); 58 | 59 | print!("{}", input); 60 | let i: u16 = input.parse; //parse a number 0..8 61 | 62 | match player { 63 | Player::X => board_x[i] = x, 64 | Player::O => board_o[i] = x, 65 | } 66 | 67 | match winner(&board_x, Winner::X) { 68 | Winner::X => print!("Winner 🍎"), 69 | _ => print!("Next") 70 | } 71 | 72 | match winner(&board_o, Winner::O) { 73 | Winner::O => print!("Winner 🍏"), 74 | _ => print!("Next") 75 | } 76 | 77 | render(board_x, board_o); 78 | player = player.next(); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /3_api/src/tuite.rs: -------------------------------------------------------------------------------- 1 | pub type Tweets = Response; 2 | 3 | #[derive(Debug, Deserialize, Serialize)] 4 | pub struct Tweet { 5 | pub id: String, 6 | pub created_at: DateTime, 7 | pub message: String, 8 | pub likes: Vec, 9 | } 10 | 11 | impl Tweet { 12 | pub fn new(message: String) -> Self { 13 | Self { 14 | id: Uuid::new_v4().to_string(), 15 | created_at: Utc::now(), 16 | message, 17 | likes: vec![], 18 | } 19 | } 20 | } 21 | 22 | #[derive(Debug, Deserialize, Serialize)] 23 | pub struct TweetRequest { 24 | pub message: Option, 25 | } 26 | 27 | impl TweetRequest { 28 | pub fn to_tweet(&self) -> Option { 29 | match &self.message { 30 | Some(message) => Some(Tweet::new(message.to_string())), 31 | None => None, 32 | } 33 | } 34 | } 35 | 36 | /// list 50 last tweets `/tweets` 37 | #[get("/tweets")] 38 | pub async fn list() -> HttpResponse { 39 | // TODO find the last 50 tweets and return them 40 | 41 | let tweets = Tweets { results: vec![] }; 42 | 43 | HttpResponse::Ok() 44 | .content_type(APPLICATION_JSON) 45 | .json(tweets) 46 | } 47 | 48 | /// create a tweet `/tweets` 49 | #[post("/tweets")] 50 | pub async fn create(tweet_req: Json) -> HttpResponse { 51 | HttpResponse::Created() 52 | .content_type(APPLICATION_JSON) 53 | .json(tweet_req.to_tweet()) 54 | } 55 | 56 | /// find a tweet by its id `/tweets/{id}` 57 | #[get("/tweets/{id}")] 58 | pub async fn get(path: Path<(String,)>) -> HttpResponse { 59 | // TODO find tweet a tweet by ID and return it 60 | let found_tweet: Option = None; 61 | 62 | match found_tweet { 63 | Some(tweet) => HttpResponse::Ok() 64 | .content_type(APPLICATION_JSON) 65 | .json(tweet), 66 | None => HttpResponse::NoContent() 67 | .content_type(APPLICATION_JSON) 68 | .await 69 | .unwrap(), 70 | } 71 | } 72 | 73 | /// delete a tweet by its id `/tweets/{id}` 74 | #[delete("/tweets/{id}")] 75 | pub async fn delete(path: Path<(String,)>) -> HttpResponse { 76 | // TODO delete tweet by ID 77 | // in any case return status 204 78 | 79 | HttpResponse::NoContent() 80 | .content_type(APPLICATION_JSON) 81 | .await 82 | .unwrap() 83 | } -------------------------------------------------------------------------------- /general/variables.md: -------------------------------------------------------------------------------- 1 | ```Rust 2 | let variable_name = value; // no type specified 3 | let variable_name:dataType = value; //type specified 4 | fn salary() { 5 | let fees = 25_000; 6 | let salary:f64 = 35_000.00; 7 | println!("fees is {} and salary is {}",fees,salary); 8 | } 9 | ``` 10 | 11 | ## Immutable 12 | 13 | By default, variables are immutable − read only in Rust. In other words, the variable's value cannot be changed once a value is bound to a variable name. 14 | 15 | Let us understand this with an example 16 | 17 | ``` Rust 18 | fn main() { 19 | let fees = 25_000; 20 | println!("fees is {} ",fees); 21 | fees = 35_000; 22 | println!("fees changed is {}",fees); 23 | } 24 | ``` 25 | 26 | ! Rowever you can override old reference using **let** again. 27 | 28 | ``` Rust 29 | fn main(r) { 30 | let A = 3.1415; 31 | println!("Pi is {} ",fees); 32 | let Area = A * ( r * r) 33 | println!("Area of {r} is {A}",fees); 34 | } 35 | ``` 36 | 37 | The output will be as shown below 38 | 39 | ``` bash 40 | error[E0384]: re-assignment of immutable variable `fees` 41 | --> main.rs:6:3 42 | | 43 | 3 | let fees = 25_000; 44 | | ---- first assignment to `fees` 45 | ... 46 | 6 | fees=35_000; 47 | | ^^^^^^^^^^^ re-assignment of immutable variable 48 | error: aborting due to previous error(s) 49 | ``` 50 | 51 | The error message indicates the cause of the error – you cannot assign values twice to immutable variable fees. This is one of the many ways Rust allows programmers to write code and takes advantage of the safety and easy concurrency. 52 | 53 | ## Mutable 54 | 55 | Variables are immutable by default. Prefix the variable name with mut keyword to make it mutable. The value of a mutable variable can be changed. 56 | 57 | The syntax for declaring a mutable variable is as shown below − 58 | 59 | ``` Rust 60 | let mut variable_name = value; 61 | let mut variable_name:dataType = value; 62 | Let us understand this with an example 63 | 64 | fn main() { 65 | let mut fees:i32 = 25_000; 66 | println!("fees is {} ",fees); 67 | fees = 35_000; 68 | println!("fees changed is {}",fees); 69 | } 70 | ``` 71 | 72 | The output of the snippet is given below − 73 | 74 | ``` bash 75 | fees is 25000 76 | fees changed is 35000 77 | ``` 78 | 79 | ## Variables - Complete guide 80 | 81 | ``` Rust 82 | i8 u8 83 | i16 u16 84 | i32 u32 85 | i64 u64 86 | isize usize 87 | ``` -------------------------------------------------------------------------------- /Curso/revisao.md: -------------------------------------------------------------------------------- 1 | --- 2 | marp: true 3 | math: katex 4 | theme: default 5 | class: 6 | - invert 7 | 8 | --- 9 | 10 | ## 🔘 Lógica binária (0️⃣ 1️⃣) 11 | 12 | - Boolean values: `true` or `false` 13 | - 1 = Verdadeiro, 0 = Falso 14 | 15 | ### 🔍 Tabela verdade E AND (`&&`) 16 | 17 | | A | B | A AND B | 18 | | --- | --- | ------- | 19 | | 0 | 0 | 0 | 20 | | 0 | 1 | 0 | 21 | | 1 | 0 | 0 | 22 | | 1 | 1 | 1 | 23 | 24 | --- 25 | 26 | ## Tabela verdade OU OR (`||`) 27 | 28 | | A | B | A OR B | 29 | | --- | --- | ------ | 30 | | 0 | 0 | 0 | 31 | | 0 | 1 | 1 | 32 | | 1 | 0 | 1 | 33 | | 1 | 1 | 1 | 34 | 35 | 36 | --- 37 | 38 | ## Potência de 2 39 | 40 | Binary grows in powers of 2: 41 | 42 | | n | 2ⁿ | 43 | | --- | --- | 44 | | 0 | 1 | 45 | | 1 | 2 | 46 | | 2 | 4 | 47 | | 3 | 8 | 48 | | 4 | 16 | 49 | | 5 | 32 | 50 | | 6 | 64 | 51 | | 7 | 128 | 52 | 53 | 💡 Computadores usam potência de 2, porque é possível converter qualquer número natual em um número binário facilmente usando esta técnica 54 | 55 | --- 56 | 57 | ## 🔄 Decimal to Binary 58 | 59 | Converta `13` em binário: 60 | 61 | $$ 13\ /\ 2\ =\ 6\ sobra\ 1\ $$ 62 | $$ 6\ /\ 2\ =\ 3\ sobra\ 0\ $$ 63 | $$ 3\ /\ 2\ =\ 1\ sobra\ 1\ $$ 64 | $$ 1\ /\ 2\ =\ 0\ sobra\ 1\ $$ 65 | 66 | --- 67 | 68 | ## 🧮 Hexadecimal (Base 16) 69 | 70 | Digits: `0 1 2 3 4 5 6 7 8 9 A B C D E F` 71 | Each hex digit = 4 bits (binary) 72 | 73 | ### Example: 74 | 75 | - Binary: `1111 0001` 76 | - Hex: `F1` 77 | 78 | --- 79 | 80 | ## Fatoração, Resto da divisão 81 | 82 | Problema do troco para notas de 50, 20, 10, 5, 2 83 | 84 | $$r = a - \lfloor \frac{a}{b} \rfloor* b $$ 85 | 86 | | divisor(a) | dividendo(b) | quociente(q) | resto(r) | 87 | | ---------- | ------------ | ------------ | -------- | 88 | | 187 | 50 | 3 | 37 | 89 | | 37 | 20 | 1 | 17 | 90 | | 17 | 10 | 1 | 7 | 91 | | 7 | 5 | 1 | 2 | 92 | | 2 | 2 | 1 | 0 | 93 | 94 | --- 95 | 96 | # Matrizes 97 | 98 | $ 99 | \left[\begin{matrix} 100 | 1 & 2 & 3\\ 101 | 4 & 5 & 6\\ 102 | 7 & 8 & 9 103 | \end{matrix}\right]$ 104 | 105 | $$A_{i⨉j}$$ 106 | $$ i = j = 3$$ 107 | --- 108 | 109 | # Funções 110 | 111 | $f(x) = 3x-1$ 112 | 113 | |x|fx| 114 | |-|-| 115 | |2|5| 116 | |3|8| 117 | |...| 118 | |6|17| 119 | 120 | 121 | --- 122 | -------------------------------------------------------------------------------- /3_api/Readme.md: -------------------------------------------------------------------------------- 1 | # RUST API 2 | 3 | ## Intro 4 | 5 | 🐤 Este é um exemplo para **criar APIS com o RUST** 6 | 7 | 🐘 Acesse também esta dica recente para criar [**APIS com RUST + Postgres**](https://github.com/ricardodarocha/sqlxpg) 8 | 9 | Neste exemplo eu mostro como criar uma API do zero 10 | ``` 11 | 💬 Há várias maneiras de criar APIS com Rust, inclusive há diversas libs entre elas Actix, Tokio, Axum, 12 | Algumas possuem suporte a assíncrono, threads e outros recursos. Neste exemplo eu criei 13 | a API da maneira mais simples possível, com Actix 14 | ``` 15 | 16 | Comece com o arquivo `main.rs` 17 | 18 | ```Rust 19 | HttpServer::new(|| { 20 | App::new() 21 | .service(routes::hello) 22 | .service(routes::echo) 23 | .route("/hey", web::get().to(routes::hello_world)) 24 | }) 25 | .bind(("127.0.0.1", port))? 26 | .run() 27 | .await 28 | ``` 29 | 30 | em seguida registre suas rotas 31 | 32 | ```Rust 33 | #[get("/")] 34 | pub async fn hello_world() -> impl Responder { 35 | HttpResponse::Ok().body("Hello world!") 36 | } 37 | ``` 38 | 39 | e rode o comando **cargo run** no shell 40 | 41 | Neste exemplo eu recomendo que você comece com dois arquivos, ou seja 42 | a regra de negócios principal fica no main.rs, onde você expõe o servidor e suas configurações básicas, como a porta. 43 | As rotas você deve deixar no arquivo routes.rs. 44 | Eu recomendo criar as rotas em um arquivo separado porque um projeto de API pode se tornar grande com o tempo, e mesmo para projetos pequenos, você criar uma melhor separação dos arquivos. 45 | 46 | ## Tutorial Completo 47 | 48 | Neste tutorial mais detalhado eu mostro como criar o projeto utilizando o CMD e como compilar os binários 49 | 🦀 50 | Abrir a linha de comandos em uma pasta de projetos e dentro dela rodar o comando 51 | 52 | ```shell 53 | cargo new api_name --bin 54 | code . 55 | ``` 56 | 57 | abra o arquivo **cargo.toml** que possui todas as configurações do projeto 58 | inclua a dependência para **actix-web** 59 | 60 | ```Rust 61 | [package] 62 | name = "api" 63 | version = "0.1.0" 64 | edition = "2021" 65 | 66 | [dependencies] 67 | actix-web = "4" 68 | ``` 69 | Crie dois arquivos 70 | main.rs 71 | routes.rs 72 | 73 | ou clone este repositório 74 | 75 | ``` 76 | git clone 77 | ``` 78 | 79 | Em seguida rode o programa 80 | 81 | ```shell 82 | cargo new api_name --bin 83 | code . 84 | ``` 85 | 86 | 🚧 _em manutenção_ 87 | 88 | # Veja mais 89 | 90 | Trabalhando com [JSON](https://github.com/ricardodarocha/Rust#lendo-json) 91 | Como criar [módulos](https://github.com/ricardodarocha/Rust/edit/main/README.md#Modules) 92 | -------------------------------------------------------------------------------- /Modelos.md: -------------------------------------------------------------------------------- 1 | # Implementando Models com Rust 2 | 3 | Nesta sessão eu mostro as inúmeras formas de implementar Models para os dados com **Structs** 4 | Apresento alguns conceitos como **composição** e explico porque Rust não é uma POO - Programação Orientada a Objetos, e as implicações disso. 5 | 6 | Em seguida eu introduzo conceitos mais avançados, como Traits, Enuns e Macros. 7 | 8 | --- 9 | 10 | Para começar, o que é um Model? (Modelo) 11 | 12 | Um Model é uma representação para uma estrutura de dados, também conhecido como uma Entidade ou uma Classe em POO. 13 | Outras variações para o termo Model que você irá encontrar 14 | 15 | Model 16 | Classe 17 | Entidade 18 | Record 19 | Documento 20 | Row 21 | 22 | --- 23 | 24 | Porque criamos Models? 25 | 26 | Models representam os dados do mundo real, por exemplo podemos modelar um servidor rest com os seguintes atributos 27 | 28 | ```Rust 29 | struct Req { 30 | host: String, 31 | porta: i32, 32 | parametros: vec! 33 | } 34 | ``` 35 | 36 | Em Rust Models são fortemente tipados, e possuem apenas os dados de uma regra de negócios. (Não possui lógica, comportamento, etc) 37 | 38 | No entanto podemos extender nosssos modelos para admitir comportamento, por meio da **implementação de traits** 39 | 40 | --- 41 | 42 | 43 | # Implementação de traits 44 | 45 | ```Rust 46 | exemplo trait1 47 | ``` 48 | 49 | Um trait pode ser inicialmente comparado com uma interface. Isso porque os traits contém contratos que uma determinada struct poderá implementar. 50 | No entanto há uma série de diferenças que tornam traits um tanto mais interessantes. 51 | 52 | ## Default 53 | 54 | Traits admitem implementações padrão 55 | 56 | # Enriquecendo modelos com traits padrão 57 | 58 | Algumas traits padrão já são fornecidas pela linguagem e permitem estender as funcionalidades dos nossos models. Por exemplo podemos estender nossos models para admitir que eles sejam mostrados como uma string em uma chamada format!, write! ou print! 59 | 60 | ## Estendendo a funcionalidade Display 61 | 62 | um bloco de código vale mais que mil palavas 63 | ```Rust 64 | struct User { 65 | name: String, 66 | email: String, 67 | } 68 | 69 | impl fmt::Display for User { 70 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 71 | write!(f, "{} <{}>", self.name, self.email) 72 | } 73 | } 74 | 75 | fn main() { 76 | let new_user = User { 77 | name: "Benjamin Lannon".to_string(), 78 | email: "email@example.com".to_string() 79 | } 80 | 81 | println!("{}", new_user); // Prints out "Benjamin Lannon " 82 | } 83 | ``` 84 | 85 | Fonte: https://lannonbr.com/blog/rust-display-impl/ 86 | 87 | -------------------------------------------------------------------------------- /general/loopExpressions: -------------------------------------------------------------------------------- 1 | # Loop expressions: 2 | 3 | Rust supports four loop expressions: 4 | - A **loop** expression denotes an infinite loop. 5 | - A **while** expression loops until a predicate is false. 6 | - A **while let** expression tests a pattern. 7 | - A **for** expression extracts values from an iterator, looping until the iterator is empty. 8 | All four types of loop support break expressions, continue expressions, and labels. Only loop supports evaluation to non-trivial values. 9 | 10 | ### Loop 11 | ``` Rust 12 | loop { println!("I live."); } 13 | ``` 14 | 15 | ### while 16 | ``` Rust 17 | let mut i = 0; 18 | 19 | while i < 10 { 20 | println!("hello"); 21 | i = i + 1; 22 | } 23 | ``` 24 | 25 | ### while let 26 | ``` Rust 27 | let mut x = vec![1, 2, 3]; 28 | 29 | while let Some(y) = x.pop() { 30 | println!("y = {}", y); 31 | } 32 | 33 | ``` 34 | 35 | Multiple patterns may be specified with the | operator. This has the same semantics as with | in match expressions: 36 | 37 | ``` Rust 38 | let mut vals = vec![2, 3, 1, 2, 2]; 39 | while let Some(v @ 1) | Some(v @ 2) = vals.pop() { 40 | // Prints 2, 2, then 1 41 | println!("{}", v); 42 | } 43 | ``` 44 | 45 | ### For 46 | A for expression is a syntactic construct for looping over elements provided by an implementation of std::iter::IntoIterator. If the iterator yields a value, that value is matched against the irrefutable pattern, the body of the loop is executed, and then control returns to the head of the for loop. If the iterator is empty, the for expression completes. 47 | 48 | ```Rust 49 | for x in 10 { println!("{}", x)} 50 | //0..9 51 | ``` 52 | 53 | ```Rust 54 | for x in 1..11{ // 11 is not inclusive 55 | if x==5 { 56 | continue; 57 | } 58 | ``` 59 | 60 | An example of a for loop over the contents of an array: 61 | 62 | ``` Rust 63 | let v = &["apples", "cake", "coffee"]; 64 | 65 | for text in v { 66 | println!("I like {}.", text); 67 | } 68 | ``` 69 | 70 | An example of a for loop over a series of integers: 71 | 72 | ``` Rust 73 | let mut sum = 0; 74 | for n in 1..11 { 75 | sum += n; 76 | } 77 | assert_eq!(sum, 55); 78 | ``` 79 | 80 | ## Looping break 81 | ``` Rust 82 | let mut i = 0; 83 | 84 | while i < 10 { 85 | 86 | if x 5 { 87 | break; } 88 | 89 | i = i + 1; 90 | println!("hello{}", I); 91 | } 92 | ``` 93 | 94 | When associated with a loop, a break expression may be used **to return a value** from that loop, via one of the forms break EXPR or break 'label EXPR, where EXPR is an expression whose result is returned from the loop. For example: 95 | 96 | 97 | ```Rust 98 | // Fibonacci 99 | let (mut a, mut b) = (1, 1); 100 | let result = loop { 101 | if b > 10 { 102 | break b; 103 | } 104 | let c = a + b; 105 | a = b; 106 | b = c; 107 | }; 108 | // first number in Fibonacci sequence over 10: 109 | assert_eq!(result, 13); 110 | ``` 111 | -------------------------------------------------------------------------------- /Curso/programas/cadastro_alunos.rs: -------------------------------------------------------------------------------- 1 | //https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=227e401a2213caede58c53df5776b508 2 | pub mod portugol { 3 | #[macro_export] 4 | macro_rules! leia { 5 | ($var:ident : $t:ty) => { 6 | { 7 | use std::io::{self, Write}; 8 | let mut input = String::new(); 9 | println!(" informe o campo {}:{} ", stringify!($var), stringify!($t), ); 10 | io::stdout().flush().unwrap(); 11 | io::stdin().read_line(&mut input).expect("Falha ao ler entrada"); 12 | input = input.trim().to_string(); 13 | print!("> {}\n", input); 14 | $var = input.parse::<$t>().expect("Falha na conversão do valor"); 15 | } 16 | }; 17 | } 18 | } 19 | 20 | /// Este programa possui a struct Aluno: 21 | /// nome (String), 22 | /// matrícula (i32), 23 | /// nota1 e nota2 (f32). 24 | /// O programa deve: 25 | /// Ter um menu para o usuário: 26 | /// (1) Cadastrar aluno 27 | /// (2) Listar alunos e suas médias 28 | /// (3) Sair 29 | /// Usar funções para: 30 | /// cadastrar um aluno, 31 | /// calcular a média, 32 | /// imprimir os dados. 33 | pub mod aluno { 34 | 35 | pub struct Aluno{ 36 | pub matricula: i32, 37 | pub nome: String, 38 | pub nota1: f32, 39 | pub nota2: f32, 40 | } 41 | 42 | pub fn novo() -> Aluno { 43 | 44 | // let (matricula, nome, nota1, nota2):(i32, String, f32, f32); 45 | // leia!(matricula: i32); 46 | // leia!(nome: String); 47 | // leia!(nota1: f32); 48 | // leia!(nota2: f32); 49 | 50 | Aluno { 51 | matricula: 1, 52 | nome: "Fulano".to_string(), 53 | nota1: 9.0, 54 | nota2: 8.5 55 | } 56 | 57 | } 58 | 59 | 60 | pub fn listar(alunos: &Vec) { 61 | for aluno in alunos { 62 | println!("{} {}", aluno.nome, (aluno.nota1 + aluno.nota2) / 2.0); 63 | } 64 | } 65 | } 66 | 67 | pub mod app { 68 | use crate::leia; 69 | 70 | pub enum Acao { 71 | Cadastrar, 72 | Listar, 73 | Sair, 74 | } 75 | 76 | pub fn menu() -> Acao { 77 | let opcao: i8; 78 | println!(" 79 | (1) Cadastrar 80 | (2) Listar 81 | (3) Sair 82 | 83 | "); 84 | leia!(opcao: i8); 85 | 86 | match opcao { 87 | 1 => Acao::Cadastrar, 88 | 2 => Acao::Listar, 89 | 3 => Acao::Sair, 90 | _ => menu(), 91 | } 92 | } 93 | } 94 | 95 | fn main() { 96 | let mut alunos: Vec = vec![]; 97 | use app::Acao; 98 | 99 | loop { 100 | let acao = app::menu(); 101 | match acao { 102 | Acao::Cadastrar => alunos.push(aluno::novo()), 103 | Acao::Listar => aluno::listar(&alunos), 104 | Acao::Sair => break, 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /Curso/aula 3.md: -------------------------------------------------------------------------------- 1 | --- 2 | marp: true 3 | theme: default 4 | class: 5 | - invert 6 | --- 7 | 8 | ## Funções 9 | 10 | ```rust 11 | fn soma(a, b) { 12 | a + b 13 | } 14 | ``` 15 | 16 | ```rust 17 | fn divide(a, b) { 18 | if b > 0 { 19 | a / b 20 | } 21 | } 22 | 23 | --- 24 | 25 | ## Soma 26 | 27 | ```rust 28 | fn soma(a: int, b: int) -> int { 29 | a + b 30 | } 31 | ``` 32 | 33 | [▶ executar](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6a4bb1dc15efc19082674847cf3dbaa8) 34 | 35 | ## Divisão 36 | 37 | 🔥 38 | ```rust 39 | fn divide(a: int, b: int) -> int { 40 | if b > 0 { 41 | a / b 42 | } else 43 | { 44 | panic!("Divisão por zero") 45 | } 46 | } 47 | ``` 48 | 49 | [▶ executar](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ab7602fa760acff77c12879c79da003b) 50 | 51 | 52 | 53 | --- 54 | 55 | ## Exercício 56 | 57 | Crie uma função para calcular o triplo de um número $n$ qualquer 58 | Calcule e imprima o triplo de 4 números $[2 3 5 8]$ 59 | 60 | [▶ executar](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6b1a4a24ead017a023f51a8095c351cc) 61 | 62 | ## Crie uma função para verificar o maior número 63 | 64 | série de teste $$32 65 17 11 41$$ 65 | 66 | ```rust 67 | fn maior(a: int, b: int) -> int { 68 | if a > b { 69 | a 70 | } else 71 | { 72 | b 73 | } 74 | } 75 | ``` 76 | 77 | [▶ executar](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=a6be006b9caa7c26c4564a4d5728dd9c) 78 | 79 | ## Funções de teste 80 | 81 | #[test] 82 | fn testar() { 83 | assert!(2 + 2 == 4); 84 | } 85 | 86 | [▶ executar](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=4c7fe0134fa7efdcdc27779b7c1e2d8d) 87 | 88 | --- 89 | 90 | ## Programação orientada a testes 91 | 92 | [▶ executar](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ae6d1f9fe5fe2b9df5966d911eba01b1) 93 | 94 | ## Exercício final 95 | 96 | Crie um programa que calcule o valor do Imposto de Renda a descontar de um funcionário com salário $s$ qualquer 97 | 98 | | Faixa salarial (mensal) | Alíquota (%) | 99 | | -------------------------------- | ------------ | 100 | | Até R\$ 2.000,00 | Isento | 101 | | De R\$ 2.000,01 até R\$ 2.800,00 | 7,5% | 102 | | De R\$ 2.800,01 até R\$ 3.700,00 | 15% | 103 | | De R\$ 3.700,01 até R\$ 4.500,00 | 22,5% | 104 | | Acima de R\$ 4.500,00 | 27,5% | 105 | 106 | ## Exercício final 107 | 108 | Crie um programa que calcule o valor do Inss a descontar de um funcionário com salário $s$ qualquer 109 | 110 | | Faixa Salarial (mensal) | Alíquota (%) | 111 | | -------------------------------- | ------------ | 112 | | Até R\$ 1.500,00 | 7,5% | 113 | | De R\$ 1.500,01 até R\$ 2.500,00 | 9,0% | 114 | | De R\$ 2.500,01 até R\$ 3.500,00 | 12,0% | 115 | | Acima de R\$ 3.500,00 | 14,0% | 116 | 117 | [▶ executar](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=3cf070802057e0e891452e92410a6ffd) -------------------------------------------------------------------------------- /terremoto/ter.rs: -------------------------------------------------------------------------------- 1 | https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=f7b4da2a96d087d38fee8441bf550f56 2 | pub mod portugol { 3 | #[macro_export] 4 | macro_rules! leia { 5 | ($var:ident : $t:ty, $msg:expr) => { 6 | { 7 | use std::io::{self, Write}; 8 | let mut input = String::new(); 9 | println!("{}", $msg); 10 | io::stdout().flush().unwrap(); 11 | io::stdin().read_line(&mut input).expect("Falha ao ler entrada"); 12 | input = input.trim().to_string(); 13 | print!("> {}\n", input); 14 | $var = input.parse::<$t>().expect("Falha na conversão do valor"); 15 | } 16 | }; 17 | ($var:ident : $t:ty) => { 18 | leia!($var : $t, concat!("Informe o campo ", stringify!($var), ":", stringify!($t))); 19 | }; 20 | } 21 | } 22 | 23 | const E0: f64 = 7e-3; 24 | fn magnitude_from_amplitude(a: f64, delta_t: f64) -> f64 { 25 | a.log10() + 3.0 * (8.0 * delta_t).log10() - 2.92 26 | } 27 | 28 | fn magnitude_from_energy(e: f64) -> f64 { 29 | (2.0 / 3.0) * (e / E0).log10() 30 | } 31 | 32 | fn energy_from_magnitude(m: f64) -> f64 { 33 | const E0: f64 = 7e-3; 34 | let mag = (m * 100.0).floor() / 100.0; 35 | E0 * 10f64.powf(1.5 * mag) 36 | } 37 | 38 | fn exibir_alerta(m: f64) { 39 | let limites = [8.0, 7.0, 6.1, 5.5, 3.5, 0.0]; 40 | let mensagens = [ 41 | "🚨 ALERTA: TERREMOTO ENORME (Danos severos a longas distâncias)", 42 | "🔴 ALERTA: GRANDE TERREMOTO (Terremoto altamente destrutivo detectado)", 43 | "🔶 ALERTA: TERREMOTO (Destrutivo em até 100 km do epicentro)", 44 | "🟠 ALERTA: TERREMOTO (Danos prováveis)", 45 | "🟡 Terremoto Registrado (Sem danos) ", 46 | "🟢 Registrado (não sentido) ", 47 | ]; 48 | 49 | for (i, &limite) in limites.iter().enumerate() { 50 | if m >= limite { 51 | println!("{}\n Magnitude {:.3}", mensagens[i], m, ); 52 | break; 53 | } 54 | } 55 | } 56 | 57 | fn _menu() -> i8 { 58 | println!("(1) Magnitude da amplitude (mm)"); 59 | println!("(2) Magnitude da energia despendida E"); 60 | let opcao: i8; 61 | leia!(opcao: i8, "\nModo: "); 62 | opcao 63 | } 64 | 65 | fn main() { 66 | 67 | loop{ 68 | 69 | // let opcao = menu(); 70 | let opcao = 1; 71 | 72 | if opcao == 1 { 73 | let a: f64; 74 | let delta_t: f64; 75 | leia!(a: f64, "Informe a Amplitude A (mm)\n> "); 76 | leia!(delta_t: f64, "Informe ΔT (s)\n> "); 77 | 78 | let m = magnitude_from_amplitude(a, delta_t); 79 | exibir_alerta(m); 80 | 81 | let e = energy_from_magnitude(m); 82 | println!(" Energia despendida (E) = {:.5E} kWh\n\nPROXIMA LEITURA", e); 83 | } else if opcao == 2 { 84 | let e: f64; 85 | println!(""); 86 | leia!(e: f64, "Informe a Energia despendida(E)\n> "); 87 | 88 | let m = magnitude_from_energy(e); 89 | println!("Magnitude (E) = {:.2} kWh", m); 90 | } else if opcao == 3 { 91 | break; 92 | } else { 93 | continue; 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /algoritmos/capitulo5/README.md: -------------------------------------------------------------------------------- 1 | ![](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/A.PNG) 2 | [Resolução A](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/a.rs) 3 | 4 | --- 5 | 6 | ![](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/B.PNG) 7 | [Resolução B](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/b.rs) 8 | 9 | --- 10 | 11 | ![](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/C.PNG) 12 | [Resolução C](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/c.rs) 13 | 14 | --- 15 | 16 | ![](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/D.PNG) 17 | [Resolução D](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/d.rs) 18 | 19 | --- 20 | 21 | ![](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/E.PNG) 22 | [Resolução E](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/e.rs) 23 | 24 | --- 25 | 26 | ![](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/F.PNG) 27 | [Resolução F](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/f.rs) 28 | 29 | --- 30 | 31 | ![](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/G.PNG) 32 | [Resolução G](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/g.rs) 33 | 34 | --- 35 | 36 | ![](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/H.PNG) 37 | [Resolução H](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/h.rs) 38 | 39 | --- 40 | 41 | ![](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/I.PNG) 42 | [Resolução I](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/i.rs) 43 | 44 | --- 45 | 46 | ![](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/J.PNG) 47 | [Resolução J](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/j.rs) 48 | 49 | --- 50 | 51 | ![](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/K.PNG) 52 | [Resolução K](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/k.rs) 53 | 54 | --- 55 | 56 | ![](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/L.PNG) 57 | [Resolução L](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/l.rs) 58 | 59 | --- 60 | 61 | ![](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/M.PNG) 62 | [Resolução M](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/m.rs) 63 | 64 | --- 65 | 66 | ![](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/N.PNG) 67 | [Resolução N](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/n.rs) 68 | 69 | --- 70 | 71 | ![](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/O.PNG) 72 | [Resolução O](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/o.rs) 73 | 74 | --- 75 | 76 | ![](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/P.PNG) 77 | [Resolução P](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/p.rs) 78 | 79 | --- 80 | 81 | ![](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/Q.PNG) 82 | [Resolução Q](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/q.rs) 83 | 84 | --- 85 | 86 | ![](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/R.PNG) 87 | [Resolução R](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/r.rs) 88 | 89 | --- 90 | 91 | ![](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/S.PNG) 92 | [Resolução S](https://github.com/ricardodarocha/Rust/blob/main/algoritmos/capitulo5/s.rs) 93 | 94 | --- 95 | -------------------------------------------------------------------------------- /Curso/aula 1.md: -------------------------------------------------------------------------------- 1 | --- 2 | marp: true 3 | theme: default 4 | class: 5 | - invert 6 | --- 7 | 8 | # Introdução aos Algoritmos com Rust 9 | 10 | ![QR Code](qr.PNG) 11 | 12 | https://github.com/ricardodarocha/Rust/blob/main/Curso/Rust.md 13 | 14 | --- 15 | 16 | ## Estrutura Básica de um Programa em Rust 17 | 18 | Um programa em Rust sempre começa pela função main: 19 | 20 | ```rust 21 | fn main() { 22 | println!("Olá, mundo!"); 23 | } 24 | ``` 25 | 26 | [▶ executar](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=16d3ecbe55229cc374cadc3551d76d08) 27 | 28 | --- 29 | 30 | ## Exercício 31 | 32 | `Imprima! "Olá {fulano}" | fulano = seu_nome` 33 | 34 | --- 35 | 36 | ## Variáveis 37 | 38 | ```rust 39 | let nome = "Aluno"; 40 | println!("Olá, {aluno}", aluno = nome); 41 | ``` 42 | 43 | [▶ executar](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ee38d196b4602936645bfdb004288e30) 44 | 45 | --- 46 | 47 | ## Tipos Primitivos 48 | 49 | Rust possui diversos tipos de dados primitivos: 50 | 51 | $\mathbb{N}$ Números naturais (u32, u64) 52 | $\mathbb{Z}$ Números Inteiros (i32, i64) 53 | $\mathbb{R}$ Real, Double (f32, f64) 54 | Booleano (bool) 55 | Caracteres (char) 56 | 57 | ```rust 58 | let inteiro: i32 = 10; 59 | let flutuante: f32 = 3.14; 60 | let mol = 6.02e23; 61 | let booleano: bool = true; 62 | let caractere: char = 'A'; 63 | ``` 64 | 65 | [▶ executar](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=1c3a984853e97042e9798c4020178fe5) 66 | 67 | --- 68 | 69 | ## Declaração de variáveis 70 | 71 | ```rust 72 | let nome = "Santos Dummont"; 73 | let nascimento = 1873; 74 | let idade = 2025 - nascimento; 75 | ``` 76 | 77 | [▶ executar](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6b428dc2da0f8e98f7e5846e5e818f4e) 78 | 79 | --- 80 | 81 | ## Exercício 2 82 | 83 | Faça o programa imprimir 14 bis. Percorra um fluxo de repetição de 1 a 14, incrementando um contador e imprima o número atual, 84 | até que na última iteração o programa imprima 14 bis 85 | 86 | --- 87 | 88 | ```rust 89 | for i in 1..=14 { 90 | imprima!("{} bis", i); 91 | } 92 | 93 | ``` 94 | 95 | --- 96 | 97 | ## Variáveis mutáveis 98 | 99 | ```rust 100 | let contador = 1; ❌ 101 | let mut contador = 1; ✅ 102 | contador += 1; 103 | ``` 104 | 105 | --- 106 | 107 | ## Tipo String 108 | 109 | ```rust 110 | let mut jogador: String; 111 | 112 | jogador = "Elfo".to_string(); 113 | jogador = "Bruxo".to_string(); 114 | 115 | ``` 116 | 117 | [▶ executar](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=eef652370312d7b8bc4c96672bb60f8c) 118 | 119 | --- 120 | 121 | ## Blocos de decisão 122 | 123 | ```rust 124 | if x == 42 { 125 | 126 | } 127 | ``` 128 | 129 | --- 130 | 131 | ## Exemplo 132 | 133 | ```rust 134 | fn main() { 135 | let idade = 26; 136 | if idade > 18 { 137 | println!("Maior de idade"); 138 | } else 139 | println!("Menor de idade"); 140 | } 141 | ``` 142 | 143 | --- 144 | 145 | ## Fluxo de repetição 146 | 147 | ```rust 148 | fn main() { 149 | let mut contador = 0; 150 | loop { 151 | if contador >= 5 { 152 | break; 153 | } 154 | println!("Contador: {}", contador); 155 | contador += 1; 156 | } 157 | } 158 | ``` 159 | 160 | --- 161 | 162 | ## For 163 | 164 | ```rust 165 | fn main() { 166 | for i in 1..=5 { 167 | println!("Número: {}", i); 168 | } 169 | } 170 | ``` 171 | 172 | --- 173 | 174 | ## Matrizes Array 175 | 176 | ```rust 177 | let alfabeto: [char; 3] = ['a','b','c']; 178 | ``` 179 | 180 | [▶ executar](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=91d00c7a8e2654d4a0e234ad9dc7c724) 181 | -------------------------------------------------------------------------------- /general/types.md: -------------------------------------------------------------------------------- 1 | # Scalar Types 2 | A scalar type represents a single value. Rust has four primary scalar types: integers, floating-point numbers, Booleans, and characters. You’ll likely recognize these from other programming languages, but let’s jump into how they work in Rust. 3 | 4 | ## Integer Types 5 | An integer is a number without a fractional component. We used one integer type earlier in this chapter, the u32 type. This type declaration indicates that the value it’s associated with should be an unsigned integer (signed integer types start with i instead of u) that takes up 32 bits of space. Table 3-1 shows the built-in integer types in Rust. Each variant in the Signed and Unsigned columns (for example, i16) can be used to declare the type of an integer value. 6 | 7 | ## Integer 8 | 9 | Table: Integer Types in Rust 10 | | Length | Signed | Unsigned | 11 | |--------|--------|----------| 12 | | 8-bit | i8 | u8 | 13 | | 16-bit | i16 | u16 | 14 | | 32-bit | i32 | u32 | 15 | | 64-bit | i64 | u64 | 16 | | arch | isize | usize | 17 | 18 | The integer Byte Range 19 | 20 | | DATA | TYPE | MIN MAX | e | 21 | |------|-------------|------------|--------| 22 | | i8 | -128 | 127 | | 23 | | u8 | 0 | 255 | | 24 | | i16 | -32768 | 32767 | 6x10e4 | 25 | | u16 | -32768 | 65535 | 6x10e4 | 26 | | i32 | -2147483648 | 2147483647 | 2x10e9 | 27 | | u32 | -2147483648 | 4294967295 | 4x10e9 | 28 | 1000000000 29 | special cases 30 | | | | | | 31 | |------|------------------------------------------|-----------------------------------------|---------| 32 | | i64 | -9223372036854775808 | 9223372036854775807 | 9x10e18 | 33 | | u64 | 0 | 18446744073709551615 | 1x10e19 | 34 | | i128 | -170141183460469231731687303715884105728 | 170141183460469231731687303715884105727 | 1x10e38 | 35 | | u128 | 0 | 340282366920938463463374607431768211455 | 3x10e38 | 36 | 37 | 38 | ## floating-point numbers 39 | 40 | Rust also has two primitive types for floating-point numbers, which are numbers with decimal points. Rust’s floating-point types are f32 and f64, which are 32 bits and 64 bits in size, respectively. The default type is f64 because on modern CPUs it’s roughly the same speed as f32 but is capable of more precision. 41 | 42 | Here’s an example that shows floating-point numbers in action: 43 | 44 | ``` Rust 45 | fn main() { 46 | let x = 2.0; // f64 47 | 48 | let y: f32 = 3.0; // f32 49 | let y: f64 = 3.0; // f64 50 | } 51 | ``` 52 | 53 | Look the study for ABNT - Brasil especification to round Float Number [] 54 | 55 | Floating-point numbers are represented according to the IEEE-754 standard. The f32 type is a single-precision float, and f64 has double precision. 56 | 57 | ## Booleans 58 | 59 | Boleans are defined by keyword **bool** 60 | 61 | A standard boolean. Can be either `true` or `false` 62 | 63 | ```Rust 64 | let t = true; 65 | let f = false; 66 | 67 | ``` 68 | 69 | ## characters 70 | 71 | char 72 | A 4 byte character. 73 | 74 | ```Rust 75 | let a = 'a'; 76 | let b = 'b'; 77 | let keyboard = '⌨'; 78 | ``` 79 | 80 | For example, remove a list of emojy of a string 81 | 82 | ``` Rust 83 | /// let demojified_string = demoji(String::from("⚡hel✅🙂lo🙂")) 84 | pub fn demoji(string: String) -> String { 85 | let regex = Regex::new(concat!( 86 | "[", 87 | "\u{01F600}-\u{01F64F}", // emoticons 88 | "\u{01F300}-\u{01F5FF}", // symbols & pictographs 89 | "\u{01F680}-\u{01F6FF}", // transport & map symbols 90 | "\u{01F1E0}-\u{01F1FF}", // flags (iOS) 91 | "\u{002702}-\u{0027B0}", 92 | "\u{0024C2}-\u{01F251}", 93 | "]+", 94 | )) 95 | .unwrap(); 96 | 97 | regex.replace_all(&string, "").to_string() 98 | } 99 | ``` 100 | 101 | -------------------------------------------------------------------------------- /Curso/programas/caixa.rs: -------------------------------------------------------------------------------- 1 | /// # Programa CCaixa - Controle de Caixa 2 | /// Um livro de caixa é uma reunião de lançamentos de entradas (recebimentos) 3 | /// e saídas (pagamentos), e possui operações de Lancamento, Soma das entradas, 4 | /// Soma das saídas e Apuração do saldo 5 | /// [▶ execute este programa](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b80ad83ad5560cb4d0c8df0deadd0f1e) 6 | struct Caixa { 7 | reg: Vec, 8 | } 9 | 10 | struct Lancamento { 11 | val: f32, 12 | descr: String, 13 | } 14 | 15 | impl Caixa { 16 | 17 | /// Função para abrir o caixa, informando o `Saldo Inicial` 18 | fn abrir(saldo_inicial: f32) -> Self { 19 | let mut novo_caixa = Caixa { 20 | reg: vec![], 21 | }; 22 | 23 | novo_caixa.registrar(saldo_inicial, "Abertura do caixa".to_string()); 24 | novo_caixa 25 | } 26 | 27 | fn registrar_str(&mut self, val: f32, descr: &'static str) -> &mut Self { 28 | let reg: Lancamento = Lancamento{val, descr: descr.to_string()}; 29 | self.reg.push(reg); 30 | self 31 | } 32 | 33 | fn registrar(&mut self, val: f32, descr: String) -> &mut Self { 34 | let reg: Lancamento = Lancamento{val, descr: descr}; 35 | self.reg.push(reg); 36 | self 37 | } 38 | 39 | fn apurar(&self) -> (f32, f32, f32) { 40 | (self.entradas(), self.saidas(), self.saldo()) 41 | } 42 | 43 | fn entradas(&self) -> f32 { 44 | self.reg 45 | .iter() 46 | .filter(|x| x.val > 0.) 47 | .fold(0.0, |a, b| a + b.val) 48 | } 49 | 50 | fn saidas(&self) -> f32 { 51 | self.reg 52 | .iter() 53 | .filter(|x| x.val < 0.) 54 | .fold(0.0, |a, b| a - b.val) 55 | } 56 | 57 | fn saldo(&self) -> f32 { 58 | self.entradas() - self.saidas() 59 | } 60 | } 61 | 62 | fn imprimir_saldo(entrada: f32, saida: f32, saldo: f32) { 63 | print!("\n {:>9.2} Entradas\n {:>9.2} Saídas\n--------------------\n {:>9.2} Saldo\n\n", entrada, saida, saldo); 64 | println!("─────────────────────────────────────────────────────────────────"); 65 | } 66 | 67 | fn main() { 68 | //---- P A R T E 1 (B Á S I C O) ---------- 69 | //---- código estático 70 | 71 | println!("Exemplo 1"); 72 | 73 | let mut caixa = Caixa::abrir(500.0); 74 | caixa 75 | .registrar_str(-300., &"🏋️") 76 | .registrar_str(-120., &"📚") 77 | .registrar_str(3000., &"💰") 78 | .registrar_str(-300., &"💳") 79 | .registrar_str(-300., &"🍣") 80 | .registrar_str( 300., &"💹"); 81 | 82 | for reg in &caixa.reg { 83 | println!(" {:>9.2} {}", reg.val, reg.descr); 84 | } 85 | 86 | let (e, s, c) = caixa.apurar(); 87 | imprimir_saldo(e, s, c); 88 | 89 | //---- P A R T E 2 (A V A N Ç A D O) ---------- 90 | //---- código interativo 91 | 92 | println!("Exemplo 2"); 93 | 94 | println!("Vamos começar a interação\n Informe negativo para saídas e positivo para entradas"); 95 | let saldo_inicial: f32; 96 | leia!(saldo_inicial: f32); 97 | println!("Abrindo o caixa com R$ {saldo_inicial:.2}"); 98 | let mut caixa = Caixa::abrir(saldo_inicial); 99 | loop { 100 | let valor: f32; 101 | let descricao: String; 102 | 103 | leia!(valor: f32); 104 | if valor == 0.0 { 105 | let (total_entradas, total_saidas, saldo) = caixa.apurar(); 106 | imprimir_saldo(total_entradas, total_saidas, saldo); 107 | break; 108 | } else if valor > 0.0 { 109 | println!("Qual a descrição da entrada?"); 110 | } else if valor < 0.0 { 111 | println!("Qual a descrição da saída?"); 112 | } 113 | leia!(descricao: String); 114 | println!("-------------------------------------------"); 115 | println!("💲registrando R$ {valor:10.2} {descricao:9}"); 116 | println!("-------------------------------------------"); 117 | caixa.registrar(valor, descricao); 118 | } 119 | } 120 | 121 | pub mod portugol { 122 | #[macro_export] 123 | macro_rules! leia { 124 | ($var:ident : $t:ty) => { 125 | { 126 | use std::io::{self, Write}; 127 | let mut input = String::new(); 128 | println!(" informe o campo {}: ", stringify!($var)); 129 | io::stdout().flush().unwrap(); 130 | io::stdin().read_line(&mut input).expect("Falha ao ler entrada"); 131 | input = input.trim().to_string(); 132 | print!("> {}\n", input); 133 | $var = input.parse::<$t>().expect("Falha na conversão do valor"); 134 | } 135 | }; 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /Curso/aula 2.md: -------------------------------------------------------------------------------- 1 | --- 2 | marp: true 3 | theme: default 4 | class: 5 | - invert 6 | --- 7 | 8 | ## Fluxo de repetição 9 | 10 | ```rust 11 | fn main() { 12 | let mut contador = 0; 13 | loop { 14 | if contador >= 5 { 15 | break; 16 | } 17 | println!("Contador: {}", contador); 18 | contador += 1; 19 | } 20 | } 21 | ``` 22 | 23 | --- 24 | 25 | ## For 26 | 27 | ```rust 28 | fn main() { 29 | for i in 1..=5 { 30 | println!("Número: {}", i); 31 | } 32 | } 33 | ``` 34 | 35 | --- 36 | 37 | ## Tabela verdade 38 | 39 | Gere a tabela verdade do AND e do OR para os valores V e F 40 | $Sejam a, b variáveis lógicas$ 41 | $|$ or 42 | $&$ and 43 | 44 | 45 | ```rust 46 | println!("Tabela Verdade do AND"); 47 | for a in ['V', 'F'] { 48 | for b in ['V', 'F'] { 49 | if (a=='V') & (b=='V') { 50 | println!("{} e {} | {}", a, b, "V") 51 | } 52 | else { 53 | println!("{} e {} | {}", a, b, "F") 54 | } 55 | } 56 | } 57 | 58 | ``` 59 | 60 | --- 61 | ```rust 62 | println!("Tabela Verdade do OR"); 63 | for a in ['V', 'F'] { 64 | for b in ['V', 'F'] { 65 | if (a=='V') | (b=='V') { 66 | println!("{} ou {} | {}", a, b, "V") 67 | } 68 | else { 69 | println!("{} ou {} | {}", a, b, "F") 70 | } 71 | } 72 | } 73 | ``` 74 | 75 | --- 76 | 77 | ## Exercícios 78 | 79 | Fazer a tabela verdade do condicional 80 | Fazer a tabela verdade do bicondicional 81 | Fazer a tabela verdade do ou excluiso 82 | 83 | 84 | --- 85 | 86 | ## Vetor Array 87 | 88 | ```rust 89 | let alfabeto: [char; 3] = ['a','b','c']; 90 | ``` 91 | 92 | [▶ executar](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=91d00c7a8e2654d4a0e234ad9dc7c724) 93 | 94 | ## Iteração 95 | 96 | ```rust 97 | let naipes = ['🔶', '♠️', '🧡', '♣️']; 98 | let fig = ['👸', '👨', '🤴', ]; 99 | 100 | for n in naipes { 101 | for f in fig { 102 | println!("{}{}", n, f); 103 | } 104 | } 105 | ``` 106 | 107 | --- 108 | 109 | ♠ Alt + 6 110 | ♣ Alt + 5 111 | ♦ Alt + 4 112 | ♥ Alt + 3 113 | 114 | --- 115 | 116 | ## Exercício 117 | 118 | Imprima a tabuada do 7; 119 | 120 | --- 121 | 122 | ## Exercício 123 | 124 | Imprima a tabuada do 3 ao 9 multiplicando números de 1 a 10 125 | 126 | --- 127 | 128 | ## Exercício 129 | 130 | Imprima todas as cartas do baralho 131 | 132 | --- 133 | 134 | ## Exercício Senha 135 | 136 | Usando números de "0" a "9" escreva todas as senhas possívels com 2 caracteres 137 | 138 | ```rust 139 | let alfa = "0".."9"; 140 | for a in alfa { 141 | for b in alfa { 142 | 143 | } 144 | 145 | } 146 | ``` 147 | 148 | --- 149 | 150 | ## Exercício Senha 151 | 152 | Usando números de "0" a "9" escreva todas as senhas possívels com 2 caracteres sem repeticao 153 | 154 | ```rust 155 | let alfa = "0".."9"; 156 | for a in alfa { 157 | for b in alfa { 158 | if a == b { 159 | continue 160 | } 161 | else { 162 | println!("{}{}", a, b) 163 | } 164 | 165 | } 166 | 167 | } 168 | ``` 169 | 170 | ## Exercício Senha 171 | 172 | Usando letras de "A" a "M" escreva todas as senhas possívels com 3 caracteres sem repeticao 173 | 174 | ## Exercício Senha 175 | 176 | Crie o sorteio do grupo G da Copa do mundo de 2022 sabendo que as seleções são Brasil Suíça Camarões Sérvia 177 | Use os símbolos BRA SUI CAM SER 178 | 179 | --- 180 | 181 | ## Exercício Senha 182 | 183 | Crie o sorteio do grupo G da Copa do mundo de 2022 sabendo que as seleções são Brasil Suíça Camarões Sérvia 184 | Use os símbolos BRA SUI CAM SER 185 | 186 | ```rust 187 | let grupo_g = ["BRA", "SUI", "CAM", "SER"]; 188 | for p in grupo_g { 189 | for q in grupo_g { 190 | println!("{}⨉{}", p, q) 191 | 192 | } 193 | } 194 | ``` 195 | 196 | --- 197 | 198 | ## Exercício Seleção 199 | 200 | Imprima uma tabela com a classificação final sabendo que cada seleção alcançou x vitórias e z empates 201 | Calcule e imprima o numero de jogos, o numero de pontos 202 | 203 | ``` 204 | V E 205 | BRA 2 0 206 | SUI 2 0 207 | CAM 1 1 208 | SER 0 1 209 | ``` 210 | 211 | --- 212 | 213 | ```rust 214 | let grupo_g = ["BRA", "SUI", "CAM", "SER"]; 215 | for p in grupo_g { 216 | for q in grupo_g { 217 | println!("{}⨉{}", p, q) 218 | 219 | } 220 | } 221 | ``` 222 | 223 | --- 224 | 225 | ## Produto cartesiano 226 | 227 | $$Sejam os conjuntos M, N calcule o produto cartesiano M⨉N$$ 228 | 229 | ```rust 230 | 231 | //crie os elementos do conjunto 232 | let R = "R"; 233 | let X = "X"; 234 | let A = "A"; 235 | let E = "E"; 236 | let I = "I"; 237 | let I = "O"; 238 | let U = "U"; 239 | 240 | 241 | //crie o conjunto 242 | let M = [R, X]; 243 | let N = [A,E,I,O,U]; 244 | 245 | for m in M { 246 | for n in N { 247 | println!("{}{}", m, n); 248 | } 249 | } 250 | ``` 251 | 252 | --- 253 | 254 | ## Produto cartesiano 255 | 256 | $$Sejam os elementos A..=Z, e os numeros 1..65535 desenhe todas as celulas possíveis da tabela do excel$$ 257 | 258 | ```rust 259 | print!(" |"); 260 | for x in 'A'..='Z' { 261 | print!(" {} |", x); 262 | } 263 | println!(""); 264 | 265 | for y in 1..16 { 266 | print!("{:2} | ", y); 267 | for x in 'A'..'X' { 268 | print!("| "); 269 | } 270 | println!(""); 271 | } 272 | 273 | 274 | 275 | ``` 276 | 277 | ## Funcoes 278 | 279 | Crie um programa em rust que desenhe um grafico com os valores (x,y) informados em uma lista 280 | 281 | --- 282 | ## Tuplas 283 | 284 | $$Sejam os conjuntos M, N encontre os pares ordenados M⨉N$$ 285 | 286 | ```rust 287 | 288 | 289 | //crie o conjunto 290 | let M = "A"..="F"; 291 | let N = 0..=9; 292 | 293 | for m in M { 294 | for n in 0..=3 { 295 | let po = (m, n); 296 | println!("{:?}", po); 297 | } 298 | 299 | } -------------------------------------------------------------------------------- /Curso/programas/velha.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | //Esta implementação de jogo da velha utiliza conceitos avançados da linguagem Rust 3 | //▶ https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=a2f1d3bbec29050415dadd6801d8e395 4 | 5 | use std::ops::{Index, IndexMut}; 6 | 7 | struct Board { 8 | cols: usize, 9 | tiles: [T; SIZE], 10 | } 11 | 12 | // impl Board { 13 | impl Board { 14 | fn new(cols: usize) -> Self { 15 | Self { 16 | cols, 17 | tiles: [T::default(); SIZE], 18 | } 19 | } 20 | 21 | fn value(&self, x: usize, y: usize) -> T { 22 | self.tiles[self.index(x, y)] 23 | } 24 | 25 | fn chunk(&self, index: usize) -> &[T] { 26 | let start = index * self.cols; 27 | let end = start + self.cols; 28 | &self.tiles[start..end] 29 | } 30 | 31 | fn vchunk(&self, col: usize) -> impl Iterator { 32 | let width = self.lines() as usize; // assuming lines() == width 33 | (0..width).map(move |row| &self.tiles[row * width + col]) 34 | } 35 | 36 | fn set_value(&mut self, index: usize, value: T) { 37 | self.tiles[index] = value; 38 | } 39 | 40 | fn set_valuexy(&mut self, x: usize, y: usize, value: T) { 41 | self.tiles[self.index(x, y)] = value; 42 | } 43 | 44 | fn index(&self, x: usize, y: usize) -> usize { 45 | x + y * self.cols 46 | } 47 | 48 | fn col(&self, x: usize) -> u16 { 49 | (x % self.cols) as u16 50 | } 51 | 52 | fn lin(&self, x: usize) -> u16 { 53 | (x / self.cols) as u16 54 | } 55 | 56 | fn lines(&self) -> u16 { 57 | ((SIZE - 1) / self.cols + 1) as u16 58 | } 59 | 60 | fn same_col(&self, a: usize, b: usize) -> bool { 61 | self.col(a) == self.col(b) 62 | } 63 | 64 | fn same_lin(&self, a: usize, b: usize) -> bool { 65 | self.lin(a) == self.lin(b) 66 | } 67 | 68 | fn same_diagonal(&self, a: usize, b: usize) -> bool { 69 | let (x0, y0) = (self.col(a) as i16, self.lin(a) as i16); 70 | let (x1, y1) = (self.col(b) as i16, self.lin(b) as i16); 71 | (x1 - x0).abs() == (y1 - y0).abs() 72 | } 73 | } 74 | 75 | impl Index for Board { 76 | type Output = T; 77 | 78 | fn index(&self, index: usize) -> &Self::Output { 79 | &self.tiles[index] 80 | } 81 | } 82 | 83 | impl IndexMut for Board { 84 | fn index_mut(&mut self, index: usize) -> &mut Self::Output { 85 | &mut self.tiles[index] 86 | } 87 | } 88 | 89 | struct Velha { 90 | board: Board, 91 | n: u8, 92 | } 93 | 94 | use std::fmt::{Display, Formatter, Result}; 95 | 96 | impl Display for Velha { 97 | fn fmt(&self, f: &mut Formatter<'_>) -> Result { 98 | for i in 0..9 { 99 | let repr = match self.board[i] { 100 | x if x == Self::X => '❌', 101 | o if o == Self::O => '⭕', 102 | _ => '⬜', 103 | }; 104 | write!(f, "{}", repr)?; 105 | 106 | // Print a line break after every 3 tiles (for a 3x3 board) 107 | if (i + 1) % 3 == 0 { 108 | writeln!(f)?; 109 | } else { 110 | write!(f, "")?; // spacing between tiles 111 | } 112 | } 113 | Ok(()) 114 | } 115 | } 116 | 117 | impl Velha { 118 | pub const X: i8 = 1; 119 | pub const O: i8 = -1; 120 | pub const EMPTY: i8 = 0; 121 | 122 | fn x(&mut self, index: usize) -> &mut Self { 123 | self.board[index] = Self::X; 124 | self.n += 1; 125 | self 126 | } 127 | 128 | fn o(&mut self, index: usize) -> &mut Self { 129 | self.board[index] = Self::O; 130 | self.n += 1; 131 | self 132 | } 133 | fn clear(&mut self, index: usize) -> &mut Self { 134 | self.board[index] = Self::EMPTY; 135 | self.n -= 1; 136 | self 137 | } 138 | 139 | fn winner(&self, player: i8) -> bool { 140 | if self.n < 3 { 141 | return false; 142 | } 143 | 144 | for i in 0..3 { 145 | if self.board.chunk(i).iter().all(|&v| v == player) { 146 | return true; 147 | } 148 | } 149 | 150 | for i in 0..3 { 151 | if self.board.vchunk(i).all(|&v| v == player) { 152 | return true; 153 | } 154 | } 155 | 156 | if (0..=8) 157 | .step_by(4) 158 | // .collect::>() 159 | .all(|i| self.board[i] == player) 160 | { 161 | return true; 162 | } else if (2..=6) 163 | .step_by(2) 164 | // .collect::>() 165 | .all(|i| self.board[i] == player) 166 | { 167 | return true; 168 | } else { 169 | return false; 170 | } 171 | } 172 | } 173 | 174 | fn main() { 175 | const SIZE: usize = 64; 176 | let board: Board = Board::new(8); 177 | println!( 178 | "Board with {} columns {} lines and {} tiles ({},{})", 179 | board.cols, 180 | board.lines(), 181 | board.tiles.len(), 182 | board.col(SIZE - 1) + 1, 183 | board.lin(SIZE - 1) + 1 184 | ); 185 | 186 | let mut velha: Velha = Velha { 187 | board: Board::new(3), 188 | n: 0, 189 | }; 190 | 191 | // velha.x(3).o(2); 192 | // print!("{}", velha); 193 | use rand::Rng; 194 | for player in [Velha::X, Velha::O].into_iter().cycle() { 195 | println!("Player: {}", player); 196 | 197 | let mut rng = rand::rng(); 198 | let mut r = rng.random_range(0..9); 199 | 200 | while velha.board[r] != Velha::EMPTY { 201 | r = rng.random_range(0..9); 202 | } 203 | 204 | if player == Velha::X { 205 | velha.x(r); 206 | } else 207 | if player == Velha::O { 208 | velha.o(r); 209 | } 210 | 211 | print!("{}", velha); 212 | 213 | if velha.winner(player) { 214 | println!("🏆 {}", player); 215 | break; 216 | } 217 | 218 | if velha.n == 9 { 219 | println!("🤝 {}", "Empate"); 220 | break 221 | } 222 | } 223 | } 224 | -------------------------------------------------------------------------------- /actix/readme.MD: -------------------------------------------------------------------------------- 1 | # RUST Api Actix level 2 2 | 3 | ## Intro 4 | 5 | 🐶 Este é um exemplo de um nível básico, mas exige um pouco mais de experiência 6 | 7 | Neste exemplo eu mostro algumas features adicionais como uuid, chrono 8 | 9 | ```shell 10 | cargo add api_name & cd api_name 11 | cargo add actix-web 12 | cargo add serde --features derive 13 | cargo add serde_json 14 | cargo add chrono --features serde 15 | cargo add uuid --features v4 16 | ``` 17 | 18 | Irá produzir o seguinte **cargo.toml** 19 | 20 | ```rust 21 | [dependencies] 22 | actix-web = "4.3.1" 23 | serde = { version = "1.0", features = ["derive"] } 24 | serde_json = "1.0" 25 | chrono = { version = "0.4.26", features = ["serde"] } 26 | uuid = { version = "1.4.1", features = ["v4"] } 27 | ``` 28 | 29 | Para produzir uma api básica cole o código no **main.rs** 30 | 31 | ```rust 32 | ///para mais informações consulte https://www.vultr.com/docs/building-rest-apis-in-rust-with-actix-web/ 33 | 34 | use actix_web::{get, post, put, delete, web, App, HttpRequest, HttpResponse, HttpServer, Responder, ResponseError}; 35 | use actix_web::http::header::ContentType; 36 | use actix_web::http::StatusCode; 37 | use actix_web::body::BoxBody; 38 | 39 | use serde::{Serialize, Deserialize}; 40 | 41 | use std::fmt::Display; 42 | use std::sync::Mutex; 43 | 44 | #[derive(Serialize, Deserialize)] 45 | struct Nf{ 46 | id: u32, 47 | author: String, 48 | } 49 | 50 | // Implement Responder Trait for Nf 51 | impl Responder for Nf { 52 | type Body = BoxBody; 53 | 54 | fn respond_to(self, _req: &HttpRequest) -> HttpResponse { 55 | let res_body = serde_json::to_string(&self).unwrap(); 56 | 57 | // Create HttpResponse and set Content Type 58 | HttpResponse::Ok() 59 | .content_type(ContentType::json()) 60 | .body(res_body) 61 | } 62 | } 63 | 64 | #[derive(Debug, Serialize)] 65 | struct ErrNoId { 66 | id: u32, 67 | err: String, 68 | } 69 | 70 | // Implement ResponseError for ErrNoId 71 | impl ResponseError for ErrNoId { 72 | fn status_code(&self) -> StatusCode { 73 | StatusCode::NOT_FOUND 74 | } 75 | 76 | fn error_response(&self) -> HttpResponse { 77 | let body = serde_json::to_string(&self).unwrap(); 78 | let res = HttpResponse::new(self.status_code()); 79 | res.set_body(BoxBody::new(body)) 80 | } 81 | } 82 | 83 | // Implement Display for ErrNoId 84 | impl Display for ErrNoId { 85 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 86 | write!(f, "{:?}", self) 87 | } 88 | } 89 | 90 | struct AppState { 91 | tickets: Mutex>, 92 | } 93 | 94 | // Create a ticket 95 | #[post("/tickets")] 96 | async fn post_ticket(req: web::Json, data: web::Data) -> impl Responder { 97 | let new_ticket = Nf { 98 | id: req.id, 99 | author: String::from(&req.author), 100 | }; 101 | 102 | let mut tickets = data.tickets.lock().unwrap(); 103 | 104 | let response = serde_json::to_string(&new_ticket).unwrap(); 105 | 106 | tickets.push(new_ticket); 107 | HttpResponse::Created() 108 | .content_type(ContentType::json()) 109 | .body(response) 110 | } 111 | 112 | // Get all tickets 113 | #[get("/tickets")] 114 | async fn get_tickets(data: web::Data) -> impl Responder { 115 | let tickets = data.tickets.lock().unwrap(); 116 | 117 | let response = serde_json::to_string(&(*tickets)).unwrap(); 118 | 119 | HttpResponse::Ok() 120 | .content_type(ContentType::json()) 121 | .body(response) 122 | } 123 | 124 | // Get a ticket with the corresponding id 125 | #[get("/tickets/{id}")] 126 | async fn get_ticket(id: web::Path, data: web::Data) -> Result { 127 | let ticket_id: u32 = *id; 128 | let tickets = data.tickets.lock().unwrap(); 129 | 130 | let ticket: Vec<_> = tickets.iter() 131 | .filter(|x| x.id == ticket_id) 132 | .collect(); 133 | 134 | if !ticket.is_empty() { 135 | Ok(Nf { 136 | id: ticket[0].id, 137 | author: String::from(&ticket[0].author) 138 | }) 139 | } else { 140 | let response = ErrNoId { 141 | id: ticket_id, 142 | err: String::from("ticket not found") 143 | }; 144 | Err(response) 145 | } 146 | } 147 | 148 | // Update the ticket with the corresponding id 149 | #[put("/tickets/{id}")] 150 | async fn update_ticket(id: web::Path, req: web::Json, data: web::Data) -> Result { 151 | let ticket_id: u32 = *id; 152 | 153 | let new_ticket = Nf { 154 | id: req.id, 155 | author: String::from(&req.author), 156 | }; 157 | 158 | let mut tickets = data.tickets.lock().unwrap(); 159 | 160 | let id_index = tickets.iter() 161 | .position(|x| x.id == ticket_id); 162 | 163 | match id_index { 164 | Some(id) => { 165 | let response = serde_json::to_string(&new_ticket).unwrap(); 166 | tickets[id] = new_ticket; 167 | Ok(HttpResponse::Ok() 168 | .content_type(ContentType::json()) 169 | .body(response) 170 | ) 171 | }, 172 | None => { 173 | let response = ErrNoId { 174 | id: ticket_id, 175 | err: String::from("ticket not found") 176 | }; 177 | Err(response) 178 | } 179 | } 180 | } 181 | 182 | // Delete the ticket with the corresponding id 183 | #[delete("/tickets/{id}")] 184 | async fn delete_ticket(id: web::Path, data: web::Data) -> Result { 185 | let ticket_id: u32 = *id; 186 | let mut tickets = data.tickets.lock().unwrap(); 187 | 188 | let id_index = tickets.iter() 189 | .position(|x| x.id == ticket_id); 190 | 191 | match id_index { 192 | Some(id) => { 193 | let deleted_ticket = tickets.remove(id); 194 | Ok(deleted_ticket) 195 | }, 196 | None => { 197 | let response = ErrNoId { 198 | id: ticket_id, 199 | err: String::from("ticket not found") 200 | }; 201 | Err(response) 202 | } 203 | } 204 | } 205 | 206 | #[actix_web::main] 207 | async fn main() -> std::io::Result<()> { 208 | let app_state = web::Data::new(AppState { 209 | tickets: Mutex::new(vec![ 210 | Nf { 211 | id: 1, 212 | author: String::from("Jane Doe") 213 | }, 214 | Nf { 215 | id: 2, 216 | author: String::from("Patrick Star") 217 | } 218 | ]) 219 | }); 220 | 221 | HttpServer::new(move || { 222 | App::new() 223 | .app_data(app_state.clone()) 224 | .service(post_ticket) 225 | .service(get_ticket) 226 | .service(get_tickets) 227 | .service(update_ticket) 228 | .service(delete_ticket) 229 | }) 230 | .bind(("127.0.0.1", 8000))? 231 | .run() 232 | .await 233 | } 234 | ``` 235 | -------------------------------------------------------------------------------- /Curso/programas/cobrinha.rs: -------------------------------------------------------------------------------- 1 | /// [▶ execute este programa](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=fa5763f6a7e6968c8eb9697980fc8dcb) 2 | 3 | #![allow(dead_code)] 4 | 5 | const L: usize = 17; 6 | const SIZE: usize = L * L; 7 | 8 | fn main() { 9 | 10 | //Este codigo utiliza um vetor unidimensional 11 | let mut board: [i32; SIZE] = [0; SIZE]; 12 | 13 | //Para trabalhar com x, y transforme em uma matriz 14 | // let mut board2: [[i32; SIZE]; SIZE]; 15 | //board2 [2][2] = 1;// 16 | //board2 [2][3] = 1;// 17 | //board2 [2][4] = 1;// 18 | //board2 [2][1] = 1;// 19 | //board2 [4][8] = -1;// 20 | 21 | //cria uma cobrinha ficticia 22 | board [36] = 1; 23 | board [37] = 2; 24 | board [38] = 3; 25 | board [39] = 4; 26 | board [40] = 5; 27 | 28 | //cria uma comida 29 | board [76] = -1; 30 | 31 | //direcao horizontal pra frente (1); pra tras (-1); parado (0); 32 | //direcao vertical pra baixo (1); pra cima (-1); parado (0); 33 | let mut direction: (i32, i32) = (1, 0); 34 | // -1 35 | // ^ 36 | //-1 <-- 0 --> 1 37 | // v 38 | // 1 39 | 40 | loop { 41 | println!(" ⬆ \n w \n <- asd ->\n ⬇ " ); 42 | draw(&board); 43 | let key: char; 44 | leia!(key: char); 45 | match key { 46 | 'w' => { 47 | direction = (0, -1); 48 | next(&mut board, direction); 49 | }, 50 | 'a' => { 51 | direction = (-1, 0); 52 | next(&mut board, direction); 53 | }, 54 | 's' => { 55 | direction = (0, 1); 56 | next(&mut board, direction); 57 | }, 58 | 'd' => { 59 | direction = (1, 0); 60 | next(&mut board, direction); 61 | }, 62 | 'x' => return , 63 | _ => next(&mut board, direction), 64 | } 65 | } 66 | } 67 | 68 | fn next(board: &mut[i32; SIZE], direction: (i32, i32)) { 69 | const FOOD: i32 = -1; 70 | let mut cabeca = -1; //sq 71 | let mut n = -1; //id 1,2...n 72 | 73 | for i in 0..SIZE { 74 | if board[i] > n { 75 | n = board[i]; 76 | cabeca = i as i32; 77 | } 78 | } 79 | 80 | let (x, y) = coord(cabeca); 81 | let (a, b) = direction; 82 | let mut next = (x + a, y + b); 83 | 84 | //Anda pra tras 85 | if (n>1) && (board[square(next)] == n-1) { 86 | let tone = n+1; 87 | for i in 0..SIZE { 88 | if board[i] == 1 { 89 | //Era a cauda, agora vai virar a cabeca 90 | cabeca = i as i32; 91 | //Recalcula o next 92 | let (x, y) = coord(cabeca); 93 | next = (x + b, y + a); 94 | } 95 | } 96 | 97 | //atualiza a direcao 98 | for i in 0..SIZE { 99 | if board[i] > 0 { 100 | board[i] = tone - board[i]; 101 | } 102 | } 103 | } 104 | 105 | //shadowing nao permite mais alterar o next 🔐 106 | let next = next; 107 | 108 | if colide(next) { 109 | board[square(next)] = n; 110 | *board = game_over(board); 111 | } else if embaraca(&board, next) { 112 | board[square(next)] = n; 113 | *board = game_over(board); 114 | } else if board[square(next)] == FOOD { 115 | board[square(next)] = n + 1; 116 | } else { 117 | for i in 0..SIZE { 118 | if board[i] >= 1 { 119 | board[i] = board[i]-1; } 120 | } 121 | board[square(next)] = n; 122 | } 123 | } 124 | 125 | fn colide(destino: (i32, i32)) -> bool { 126 | let z = L as i32; 127 | let (a, b) = destino; 128 | a < 0 || 129 | b < 0 || 130 | a>= z || 131 | b>= z 132 | } 133 | 134 | fn embaraca(board: &[i32; SIZE], destino: (i32, i32)) -> bool { 135 | board[square(destino)] > 1 136 | } 137 | 138 | fn game_over(board: &[i32; SIZE]) -> [i32; SIZE] { 139 | 140 | const GAME_OVER: [usize; 82] = [ 141 | 34, 35, 36, 38, 39, 40, 42, 43, 45, 46, 48, 49, 50, 51, 55, 57, 142 | 59, 61, 63, 65, 66, 67, 68, 70, 71, 72, 73, 74, 76, 78, 80, 82, 143 | 85, 86, 87, 89, 91, 93, 97, 99, 100, 101, 119, 120, 121, 123, 127, 129, 144 | 130, 131, 133, 134, 135, 136, 138, 140, 141, 143, 144, 146, 147, 148, 150, 151, 145 | 152, 153, 155, 158, 159, 160, 163, 167, 168, 170, 171, 172, 176, 180, 181, 182, 146 | 184, 186 147 | ]; 148 | 149 | let mut result = [-2; SIZE]; 150 | for indice in 0..SIZE { 151 | if board[indice] > 0 { 152 | result[indice] = board[indice] 153 | } 154 | } 155 | for indice in GAME_OVER { 156 | result[indice + 34] = -3; 157 | } 158 | result 159 | } 160 | 161 | fn coord(sq: i32) -> (i32, i32) { 162 | let y = sq / L as i32; 163 | let x = sq % L as i32; 164 | (x, y) 165 | } 166 | 167 | fn square(coord: (i32, i32)) -> usize { 168 | let z = L as i32; 169 | let (a, b) = coord; 170 | (b * z + a) as usize 171 | } 172 | 173 | #[test] 174 | fn test_coord () { 175 | assert!(coord(0) == (0,0)); 176 | assert!(coord(1) == (1,0)); 177 | assert!(coord(15) == (15, 0)); 178 | assert!(coord(16) == (0,1)); 179 | assert!(coord(17) == (1,1)); 180 | } 181 | 182 | #[test] 183 | fn test_square () { 184 | assert!(0 == square((0,0))); 185 | assert!(1 == square((0,1))); 186 | assert!(15 == square((0,15))); 187 | assert!(16 == square((1,0))); 188 | assert!(17 == square((1,1))); 189 | } 190 | 191 | fn fm(val: i32) -> char { 192 | match val { 193 | -3 => '🟨', 194 | -2 => '💣', 195 | -1 => '🍎', 196 | 0 => '⬛' , 197 | _ => '🟩', 198 | // x => char(x) 199 | 200 | } 201 | } 202 | 203 | fn char(n: i32) -> char { 204 | if n >= 0 && n <= 9 { 205 | // Convert to char by adding to '0' (ASCII math) 206 | (b'0' + n as u8) as char 207 | } else { 208 | '\0' // Null character (represents "nothing") 209 | } 210 | } 211 | 212 | fn draw(board: &[i32; SIZE]) { 213 | for row in board.chunks(L) { 214 | for sq in row { 215 | print!("{}", fm(*sq)); 216 | } 217 | println!(""); 218 | } 219 | } 220 | 221 | pub mod portugol { 222 | #[macro_export] 223 | macro_rules! leia { 224 | ($var:ident : $t:ty) => { 225 | { 226 | use std::io::{self, Write}; 227 | let mut input = String::new(); 228 | // println!(" informe o campo {}: ", stringify!($var)); 229 | io::stdout().flush().unwrap(); 230 | io::stdin().read_line(&mut input).expect("Falha ao ler entrada"); 231 | input = input.trim().to_string(); 232 | print!("> {}\n", input); 233 | $var = input.parse::<$t>().expect("Falha na conversão do valor"); 234 | } 235 | }; 236 | } 237 | 238 | } 239 | 240 | 241 | -------------------------------------------------------------------------------- /8_cli/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "atty" 7 | version = "0.2.14" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 10 | dependencies = [ 11 | "hermit-abi", 12 | "libc", 13 | "winapi", 14 | ] 15 | 16 | [[package]] 17 | name = "autocfg" 18 | version = "1.1.0" 19 | source = "registry+https://github.com/rust-lang/crates.io-index" 20 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 21 | 22 | [[package]] 23 | name = "bitflags" 24 | version = "1.3.2" 25 | source = "registry+https://github.com/rust-lang/crates.io-index" 26 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 27 | 28 | [[package]] 29 | name = "clap" 30 | version = "3.1.18" 31 | source = "registry+https://github.com/rust-lang/crates.io-index" 32 | checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b" 33 | dependencies = [ 34 | "atty", 35 | "bitflags", 36 | "clap_derive", 37 | "clap_lex", 38 | "indexmap", 39 | "lazy_static", 40 | "strsim", 41 | "termcolor", 42 | "textwrap", 43 | ] 44 | 45 | [[package]] 46 | name = "clap_derive" 47 | version = "3.1.18" 48 | source = "registry+https://github.com/rust-lang/crates.io-index" 49 | checksum = "25320346e922cffe59c0bbc5410c8d8784509efb321488971081313cb1e1a33c" 50 | dependencies = [ 51 | "heck", 52 | "proc-macro-error", 53 | "proc-macro2", 54 | "quote", 55 | "syn", 56 | ] 57 | 58 | [[package]] 59 | name = "clap_lex" 60 | version = "0.2.0" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213" 63 | dependencies = [ 64 | "os_str_bytes", 65 | ] 66 | 67 | [[package]] 68 | name = "cli" 69 | version = "0.1.0" 70 | dependencies = [ 71 | "clap", 72 | "colored", 73 | ] 74 | 75 | [[package]] 76 | name = "colored" 77 | version = "2.0.0" 78 | source = "registry+https://github.com/rust-lang/crates.io-index" 79 | checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" 80 | dependencies = [ 81 | "atty", 82 | "lazy_static", 83 | "winapi", 84 | ] 85 | 86 | [[package]] 87 | name = "hashbrown" 88 | version = "0.11.2" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" 91 | 92 | [[package]] 93 | name = "heck" 94 | version = "0.4.0" 95 | source = "registry+https://github.com/rust-lang/crates.io-index" 96 | checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" 97 | 98 | [[package]] 99 | name = "hermit-abi" 100 | version = "0.1.19" 101 | source = "registry+https://github.com/rust-lang/crates.io-index" 102 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 103 | dependencies = [ 104 | "libc", 105 | ] 106 | 107 | [[package]] 108 | name = "indexmap" 109 | version = "1.8.1" 110 | source = "registry+https://github.com/rust-lang/crates.io-index" 111 | checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" 112 | dependencies = [ 113 | "autocfg", 114 | "hashbrown", 115 | ] 116 | 117 | [[package]] 118 | name = "lazy_static" 119 | version = "1.4.0" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 122 | 123 | [[package]] 124 | name = "libc" 125 | version = "0.2.125" 126 | source = "registry+https://github.com/rust-lang/crates.io-index" 127 | checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" 128 | 129 | [[package]] 130 | name = "os_str_bytes" 131 | version = "6.0.1" 132 | source = "registry+https://github.com/rust-lang/crates.io-index" 133 | checksum = "029d8d0b2f198229de29dca79676f2738ff952edf3fde542eb8bf94d8c21b435" 134 | 135 | [[package]] 136 | name = "proc-macro-error" 137 | version = "1.0.4" 138 | source = "registry+https://github.com/rust-lang/crates.io-index" 139 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 140 | dependencies = [ 141 | "proc-macro-error-attr", 142 | "proc-macro2", 143 | "quote", 144 | "syn", 145 | "version_check", 146 | ] 147 | 148 | [[package]] 149 | name = "proc-macro-error-attr" 150 | version = "1.0.4" 151 | source = "registry+https://github.com/rust-lang/crates.io-index" 152 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 153 | dependencies = [ 154 | "proc-macro2", 155 | "quote", 156 | "version_check", 157 | ] 158 | 159 | [[package]] 160 | name = "proc-macro2" 161 | version = "1.0.38" 162 | source = "registry+https://github.com/rust-lang/crates.io-index" 163 | checksum = "9027b48e9d4c9175fa2218adf3557f91c1137021739951d4932f5f8268ac48aa" 164 | dependencies = [ 165 | "unicode-xid", 166 | ] 167 | 168 | [[package]] 169 | name = "quote" 170 | version = "1.0.18" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" 173 | dependencies = [ 174 | "proc-macro2", 175 | ] 176 | 177 | [[package]] 178 | name = "strsim" 179 | version = "0.10.0" 180 | source = "registry+https://github.com/rust-lang/crates.io-index" 181 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 182 | 183 | [[package]] 184 | name = "syn" 185 | version = "1.0.94" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | checksum = "a07e33e919ebcd69113d5be0e4d70c5707004ff45188910106854f38b960df4a" 188 | dependencies = [ 189 | "proc-macro2", 190 | "quote", 191 | "unicode-xid", 192 | ] 193 | 194 | [[package]] 195 | name = "termcolor" 196 | version = "1.1.3" 197 | source = "registry+https://github.com/rust-lang/crates.io-index" 198 | checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" 199 | dependencies = [ 200 | "winapi-util", 201 | ] 202 | 203 | [[package]] 204 | name = "textwrap" 205 | version = "0.15.0" 206 | source = "registry+https://github.com/rust-lang/crates.io-index" 207 | checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" 208 | 209 | [[package]] 210 | name = "unicode-xid" 211 | version = "0.2.3" 212 | source = "registry+https://github.com/rust-lang/crates.io-index" 213 | checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" 214 | 215 | [[package]] 216 | name = "version_check" 217 | version = "0.9.4" 218 | source = "registry+https://github.com/rust-lang/crates.io-index" 219 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 220 | 221 | [[package]] 222 | name = "winapi" 223 | version = "0.3.9" 224 | source = "registry+https://github.com/rust-lang/crates.io-index" 225 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 226 | dependencies = [ 227 | "winapi-i686-pc-windows-gnu", 228 | "winapi-x86_64-pc-windows-gnu", 229 | ] 230 | 231 | [[package]] 232 | name = "winapi-i686-pc-windows-gnu" 233 | version = "0.4.0" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 236 | 237 | [[package]] 238 | name = "winapi-util" 239 | version = "0.1.5" 240 | source = "registry+https://github.com/rust-lang/crates.io-index" 241 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 242 | dependencies = [ 243 | "winapi", 244 | ] 245 | 246 | [[package]] 247 | name = "winapi-x86_64-pc-windows-gnu" 248 | version = "0.4.0" 249 | source = "registry+https://github.com/rust-lang/crates.io-index" 250 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 251 | -------------------------------------------------------------------------------- /arquitetura/Readme.md: -------------------------------------------------------------------------------- 1 | # Introdução à Arquitetura de Projetos com Rust 2 | 3 | ![](Amazon.PNG) 4 | 5 | Neste repositório eu demonstro como planejar a sua aplicação em diretórios, baseado na funcionalidade e na modularização 6 | 7 | Alguns princípios que você deve estar atento ao elaborar uma Arquitetura de Projeto 8 | 9 | - [x] Modularizção 10 | - [x] Organização e Estrutura de Pastas 11 | - [x] Nomenclaturas claras e Identificação correta 12 | - [x] Aplicação de Design Patterns 13 | 14 | Se você organizar bem o seu código, você terá menos trabalho para encontrar os arquivos, para dar manutenção e reaproveitar as funcionalidades que você criou. 15 | 16 | - [x] Reaproveitamento de código 17 | - [x] Facilidade para encontrar o que deseja 18 | - [x] Alta produtividade 19 | 20 | acesse a minha curadoria de projetos Rust com base na arquitetura 21 | [Projetos Rust](https://github.com/ricardodarocha/Rust/tree/main/Curadoria) 22 | [Design patterns em Rust](https://github.com/ricardodarocha/Rust/tree/main/DesignPattern) 23 | 24 | ## Criando uma estrutura de Projetos 25 | 26 | ![](arquitetura.png) 27 | 28 | Embora não se possa dizer que esta estrutura de pastas seja realmente eficiente em 100% dos casos, eu acho que é um excelente ponto de partida para você começar a estudar Rust e organizar sua aplicação em módulos 29 | Se deseja um estudo mais profundo de como organizar sua própria estrutura, consulte o tópico Analisando minha estrutura de projetos 30 | 31 | ``` 32 | projeto 33 | ├── doc 34 | │ ├── swagger 35 | │ ├── mkdocs-material 36 | │ └── docs # Rust Generated Docs 37 | ├── examples 38 | ├── src 39 | │ ├── bin.rs 40 | │ ├── main.rs 41 | │ ├── api 42 | │ │ ├── 43 | │ │── app 44 | │ │ ├── 45 | │ └── shared 46 | │ ├── 47 | ├── target 48 | └── tests 49 | ``` 50 | 51 | ## Aplicação em camadas 52 | 53 | Uma aplicação em camadas é a maneira mais simples de compartilhar código 54 | Imagine que você queira formar uma startup possuindo uma aplicação MVP (Miminum Value Product) que é o menor modelo de negócios que você possa criar para atender a um problema específico. 55 | É bem comum que você possua uma divisão em camadas, com uma aplicação na nuvem (api) e outras aplicações (aplicativos, apps) que vão rodar no computador dos clientes, no browser ou no celular. 56 | 57 | Um ponto importante é que muito provavelmente **há aspcetos compartilhados** tanto da regra de negócios como dos models. 58 | Vamos esclarecer estes termos 59 | 60 | ### Regra de Negócios / Core 61 | 62 | Muitas vezes chamado **Core** da aplicação, a regra de negócios utiliza a **linguagem ubíqua** para representar o problema no mundo real. 63 | 64 | ``` 65 | with user do 66 | select * from users as user where username = ?username 67 | then 68 | if user.contais > 1 then error('Vários usuáros com o mesmo login') 69 | else if user.contais = 0 then error('Usuário não encontrado') 70 | else if user.password = ?password then 71 | return logged 72 | else 73 | return 'invalid password' 74 | ``` 75 | Esta lógica pode ser encapsulada em várias classes (POO) ou Structs e Functions, vai depender do paradigma de programação que você está usando. 76 | O Ponto importante é que muitas vezes uma regra de negócios poderá ser compartilhada entre vários aplicativos, neste caso é recomendável colocar estas regras de negócio em um módulo compartilhado (pasta shared) 77 | 78 | ### Models 79 | 80 | Quando temos dados armazenados em arquivos ou no banco de dados, ou quando criamos entidades para representar os dados da aplicação, podemos criar structs que ficam em um módulo especial chamado Models 81 | 82 | Models representa as entidades e os atributos destas entidades. 83 | 84 | ```Rust 85 | pub struct User { 86 | pub id: i32, 87 | pub nome: String, 88 | pub email: String, 89 | pub senha: String 90 | } 91 | ``` 92 | Os models também podem ser compartilhados com várias aplicações, (pasta shared) 93 | Embora em alguns casos seja recomendado escrever models específicos para cada aplicação (pastas específicas de cada aplicação) 94 | 95 | Observe o conteúdo da pasta **src** abaixo 96 | 97 | ```shell 98 | └── src 99 | ├── api 100 | │ ├── 101 | │── app 102 | │ ├── 103 | └── shared 104 | ├── 105 | ``` 106 | 107 | ![](Diretorios.png) 108 | 109 | ## Pastas padrões 110 | 111 | **src** é a pasta gerado pelo Rust cargo, onde contém todo o código fonte do seu projeto 112 | **target** é a pasta padrão onde cargo irá gerar os binários 113 | 114 | 115 | ## Outras pastas 116 | 117 | ### Infra 118 | 119 | Infra normalmente é uma pasta onde implementamos algums recursos concretos da aplicação 120 | Imagina que nossa aplicação possua um serviço de autenticação, mas com o passar do tempo podemos mudar de ideia e encontrar uma lib de autenticação mais eficinte, mais rápida ou menos vulnerável a falhas de segurança. 121 | Neste caso podemos subsituir este componente sem reescrever toda a aplicação, apenas a parte de importar o componente e escrever um adaptador específico será repada, o core da aplicação continuará funcionando com o mesmo comportamento (regra de negócios) 122 | 123 | ### Testes 124 | 125 | Uma maneira de garantir que aplicação irá continuar funcionando adequadamente é escrevendo testes. Uma programação orientada a testes **tdd** é cada vez mais empregada e os testes podem ser facilmente escritos em rust. 126 | 127 | Você pode criar testes no próprio código fonte, no entanto um diretório de testes centralizados é altamente recomendável. 128 | A camada de testes irá ajudar que a camada de infra sofra alterações de manutenção por exemplo, sem quebrar o comportamento padrão esperado. 129 | Também irá garantir que determinadas atualizações das libs não afetem a aplicação, e quando for o caso poderão rapidamente ser detectadas e revertidas para a versão estável. 130 | 131 | # Arquiteturas complexas 132 | 133 | Com o tempo você irá compreender melhor a estrutura dos projetos e escolher a arquitetura mais adequada. Muitas vezes você irá ver a própria arquitetura se modificar, até atingir elementos bem avançados que melhor irão atender as suas expectativas e às necessidades da sua aplicação 134 | 135 | Exemplo de uma arquitetura distribuída na nuvem 136 | Cada lambda poderá ser escrito como um microsserviço, em linguagems diferentes, hospedados em serviços diferentes na nuvem 137 | 138 | ![](distribuida.png) 139 | 140 | # Cargo modules 141 | 142 | ## Analisando minha estrutura de projetos 143 | 144 | O primeiro passo para analisar a sua estrutura de projetos atual é instalando o pacote de análise cargo-modules 145 | 146 | ```Rust 147 | cargo install cargo-modules 148 | cargo modules generate tree 149 | ``` 150 | 151 | O comando `generate tree` irá produzir uma estrutura de pastas do seu projeto, como no exemplo 152 | ``` 153 | crate apipg 154 | ├── mod api: pub(crate) 155 | │ ├── mod customer: pub 156 | │ ├── mod routes: pub 157 | │ └── mod user: pub 158 | └── mod model: pub(crate) 159 | ├── mod models: pub 160 | ├── mod usermodel: pub 161 | └── mod customermodel: pub 162 | ``` 163 | 164 | o comando `cargo modules generate tree —with-types` **--with-types** irá gerar uma árvore mais detalhada, incluindo as Struct públicas e privadas da sua aplicação 165 | 166 | ```Rust 167 | cargo modules generate tree —with-types 168 | //output> 169 | ``` 170 | 171 | ``` 172 | crate sqlxpg 173 | ├── mod api: pub(crate) 174 | │ ├── mod book: pub 175 | │ │ └── fn sample: pub(self) 176 | │ ├── mod routes: pub 177 | │ │ ├── fn ping: pub 178 | │ │ ├── fn pong: pub 179 | │ │ └── fn user: pub 180 | │ └── mod user: pub 181 | │ ├── fn create_user: pub 182 | │ ├── fn delete_user: pub 183 | │ └── fn update_user: pub 184 | ├── fn main: pub(crate) 185 | └── mod model: pub(crate) 186 | ├── mod models: pub 187 | │ └── struct Bookstore: pub 188 | └── mod usermodel: pub 189 | └── struct User: pub 190 | ``` 191 | 192 | ## Gerando Grafos 193 | 194 | Esta funcionalidade vai revolucionar a sua visão de arquitetura de projetos com Rust (E também com outras linguagens) 195 | Instale a aplicação para visualizar grafos [**Graphviz**](https://graphviz.org/download/) (Open Source, Free to download) 196 | ![Grapho](Grapho.PNG) 197 | 198 | Após instalar você poderá executar o verificador utilizando o parametro 199 | 200 | ```Rust 201 | cargo-modules generate graph --with-types --with-tests --with-orphans | "d:/programas/graphviz/dot.exe" -Tsvg > diagrama.svg 202 | ``` 203 | Observe que você precisa informar o local onde foi instalado o executável "dot.exe" e passar o parametro -Tsvg 204 | o parâmetro `> diagrama.svg` exporta o resultado para um arquivo .svg, que voce pode visualizar utilizando o Browser 205 | 206 | Dica instale a extensão [**svg Viewer**](https://marketplace.visualstudio.com/items?itemName=cssho.vscode-svgviewer) para visualizar o grafo no VSCode. 207 | 208 | ![Diagrama](diagrama.svg) 209 | 210 | -------------------------------------------------------------------------------- /DesignPattern/Readme.md: -------------------------------------------------------------------------------- 1 | # Um guia de Design Patterns com Rust 2 | 3 | Neste repositório eu explico e mostro exemplos de design pattern com RUST. 4 | Antes de sair por aí implementando design patterns, é recomendável entender [quando não fazê-lo](https://rust-unofficial.github.io/patterns/patterns/index.html) 5 | ## O Padrão Builder e o Dialeto Fluent 6 | 7 | 💬 Utilizar a linguagem ubíqua é a forma mais recomendada para você escrever o ponto de entrada para a sua aplicação `main.rs` `lib.rs` 8 | 9 | ```Rust 10 | fn main() { 11 | HttpServer::new( move || { 12 | let logger = Logger::default(); 13 | App::new() 14 | .data( pool.clone() ) 15 | .wrap(logger) 16 | .service(ping) 17 | .service(pong) 18 | } 19 | ``` 20 | 21 | Este formato é possível na linguagem funcional se você escrever implementações como funções que retornam a si mesmo (Self) 22 | 23 | ✨ **Rust possui suporte nativo** ao padrão Builder por meio da macro **derive_builder** 24 | 25 | 26 | ```Rust 27 | #[macro_use] 28 | extern crate derive_builder; 29 | 30 | #[derive(Default, Builder)] 31 | #[builder(setter(build))] 32 | struct pub struct Server { 33 | host: String, 34 | port: u16, 35 | timeout: Option, 36 | } 37 | } 38 | ``` 39 | ✨ Esta simples expansão irá permitir construir uma nova instância de Server assim 40 | 41 | ```Rust 42 | let serv = ServerBuilder::default() 43 | .host("localhost".to_owned), 44 | .port(9090), 45 | .timeout(3000): 46 | .build() 47 | .unwrap(); 48 | ``` 49 | 50 | 👶 No entanto se você é iniciante eu recomendo implementar este design patter com as suas próprias mãos: 51 | 52 | ```Rust 53 | impl App{ 54 | fn atribuir(&mut self, valor: any) --> &mut Self { 55 | self.any = any; 56 | return self 57 | } 58 | ``` 59 | 60 | 🎯 Idiomaticamente é recomendável escrever estruturas com responsabilidades específicas, criando um struct específico para construir (Builder) uma estrutura Comportamental (Business) 61 | 62 | ```Rust 63 | pub struct Server { 64 | host: String, 65 | port: u16, 66 | timeout: Option, 67 | } 68 | 69 | impl Server { 70 | fn index() -> HttpResponse { 71 | return Ok('
Olá Mundo
'.to_owned()) 72 | } 73 | 74 | ------------- 75 | 76 | pub struct ServerBuilder { 77 | host: String, 78 | port: u16, 79 | timeout: Option, 80 | } 81 | 82 | 83 | impl ServerBuilder { 84 | fn host(&mut self, host: String) -> &mut Self { 85 | self.host = host; 86 | return self 87 | } 88 | fn port(&mut self, port: u16) -> &mut Self { 89 | self.port = port; 90 | return self 91 | } 92 | fn timeout(&mut self, value: i32) -> &mut Self { 93 | self.timeout = ms(value); 94 | return self 95 | } 96 | fn build(&mut self2) -> Server { 97 | return Server {self.host, self.port, self.timeout} 98 | } 99 | } 100 | 101 | ``` 102 | 103 | https://www.youtube.com/watch?v=5DWU-56mjmg&t=419s _em inglês_ 104 | 105 | ## Iterator 106 | 107 | Iterar é uma das habilidades mais importantes das linguagens de programação 108 | Vamos revisar as estruturas de looping disponíveis pela linguagem Rust 109 | 110 | ``` 111 | loop { 112 | }; 113 | 114 | for _ in 0..10 { } 115 | ``` 116 | 117 | o _Design Pattern_ **iterator** é uma expansão deste conceito que utiliza alguns recursos mais avançados para ampliar as possibilidades de programação, a segurança e a performance. 118 | Observe o código Rust para separar uma string simples 119 | 120 | ```Rust 121 | let todos_meses_do_ano = "Janeiro, Fevereiro, Março, Abril, Maio, Junho, Julho, Agosto, Setembro, Outubro, Novembro, Dezembro"; 122 | let meses: Vec<&str> = 123 | todos_meses_do_ano.split(',') 124 | .map(str::trim) 125 | .collect(); 126 | ``` 127 | 128 | Observe que o método map é chamado para cada elemento do iterador _split_ 129 | Split é um iterador porque implementa o `trait Iterator` que possui a seguinte estrutura 130 | 131 | ```Rust 132 | trait Iterator { 133 | fn next(&mut self) -> Option; 134 | fn current(&self) -> Option; 135 | fn has_next(&self) -> bool; 136 | fn reset(&mut self); 137 | } 138 | ``` 139 | 140 | Saiba mais em https://github.com/lpxxn/rust-design-pattern/blob/master/behavioral/iterator.rs 141 | 142 | ## Observer 143 | 144 | Observer utiliza uma estrutura de Notificadores e Assinantes 145 | Um Notificador é um detentor de uma informação ou um Agente capaz de informar um ou mais assinante quando houver uma novidade, ou após a modificação do estado de uma aplicação. 146 | 147 | Podemos exemplificar o Observer como um banco de dados REDIS que irá disparar uma notificação para as aplicações CLIENT quando for inserido um novo item no banco de dados, por exemplo. No entanto este design pattern será implementado inteiramente numa mesma camada da aplicação. 148 | 149 | ### Caso prático 150 | 151 | Imagine que uma aplicação que monitore o preço das ações na Bolsa de Valores 152 | Sempre que uma ação da Bolsa de valores cair ou subir, irá notificar os clientes que possuem aquela ação na sua carteira. 153 | No entanto para não ter problemas de tráfego, a aplicação irá notificar apenas as 100 ações com alterações mais relevantes 154 | 155 | A representação deste aplicativo ficaria assim 156 | 157 | ```Rust 158 | impl Notificador { 159 | 160 | fn Notificar(assinantes Vec) { 161 | for acao in acoes 162 | assinantes(acao).notify(acao) 163 | } 164 | 165 | fn Assinar(assinante, acao) { 166 | Self.assinantes(acao).push(assinante) 167 | } 168 | } 169 | ``` 170 | 171 | ```Rust 172 | impl Assinante { 173 | 174 | fn Assinar(notificador: Notificador; acoes: Acao) 175 | for acao in acoes 176 | notificador.assinar(Self, acao) 177 | } 178 | ``` 179 | 180 | 181 | ```Rust 182 | use std::rc::Weak; 183 | 184 | struct Event; 185 | 186 | trait Observable { 187 | fn register(&mut self, observer: Weak); 188 | } 189 | 190 | trait Observer { 191 | fn notify(&self, event: &Event); 192 | } 193 | ``` 194 | --- 195 | ## State 196 | 197 | State é um design pattern que admite que um determinado objeto possua uma variável de estado que representa diferentes estados em que o objeto se encontra. 198 | Também admite que há um fluxo predefinido onde um objeto que está em um determinado estado irá percorrer uma sequência lógica, e que esta sequência contém algumas regras específicos sobre quais estados são permitidos no próximo estágio, e quais não. 199 | 200 | 🚩 Por exemplo, uma invoice pode representar o estado padrão de uma operação de compra de uma mercadoria. Podemos ilustrar o fluxo assim 201 | 202 | ```mermaid 203 | graph LR; 204 | request-->order; 205 | order-->complete; 206 | ``` 207 | Note que não é possível uma **request** passar diretamente para o estado de **complete** 208 | Primeiro é necessário receber aprovação, que é representado pelo estado **order** 209 | 210 | 🦀 Implementar o design pattern State em Rust exatamente como é recomendado para Programação Orientada a Objetos (POO) não irá tirar proveito dos recursos Rust, em vez disso é recomendada uma abordagem mais rustácea: 211 | 212 | ```Rust 213 | pub struct Request { 214 | product_id: String, 215 | quant: u16 } 216 | 217 | pub struct Order { 218 | product_id: String, 219 | quant: u16 } 220 | 221 | pub struct Invoice { 222 | product_id: String, 223 | quant: u16 } 224 | price: f16, 225 | tax: f16} 226 | 227 | impl Request { 228 | fn new(id: String, quant: u16) -> Request { 229 | Request{ 230 | product_id: id, 231 | quant: quant, 232 | } 233 | } 234 | fn approve(self, quant: u16) -> Order { 235 | Order{ 236 | product_id: self.id, 237 | quant: quant, 238 | } 239 | } 240 | 241 | impl Order { 242 | fn complete(&mut ord: Order, price: f16, tax: f16) -> Invoice { 243 | Invoice{ 244 | product_id: ord.id, 245 | quant: ord.quant, 246 | price: price, 247 | tax: tax 248 | } 249 | } 250 | } 251 | ``` 252 | 253 | 🧐 Eu também preparei esta abordagem utilizando Enum. A implementação fica assim 254 | 255 | ```Rust 256 | enum Invoice { 257 | Request(String, u16, ), 258 | Order(String, u16, ), 259 | Invoice(String, u16, f32, f32, ), 260 | } 261 | 262 | impl Invoice { 263 | 264 | fn approve(self, quant: u16,) -> Invoice { 265 | match self { 266 | Invoice::Request(product_id, _) => return Invoice::Order(product_id.to_string(), quant), 267 | _ => return self 268 | } 269 | } 270 | 271 | fn complete(self, price: f32, tax: f32) -> Invoice { 272 | match self { 273 | Invoice::Order(product_id, quant) => return Invoice::Invoice(product_id.to_string(), quant, price, tax), 274 | _ => return self 275 | } 276 | } 277 | } 278 | 279 | fn main() { 280 | let request = Invoice::Request("031ac51c".to_owned(), 2_000); 281 | let order = request.approve(1_500); 282 | let _invoice = order.complete(19.90, 127.00); 283 | 284 | } 285 | ``` 286 | -------------------------------------------------------------------------------- /arquitetura/diagrama.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | sqlxpg 12 | 13 | 14 | sqlxpg 15 | 16 | crate 17 | 18 | sqlxpg 19 | 20 | 21 | 22 | sqlxpg::api 23 | 24 | pub(crate) mod 25 | 26 | api 27 | 28 | 29 | 30 | sqlxpg->sqlxpg::api 31 | 32 | 33 | owns 34 | 35 | 36 | 37 | sqlxpg::model 38 | 39 | pub(crate) mod 40 | 41 | model 42 | 43 | 44 | 45 | sqlxpg->sqlxpg::model 46 | 47 | 48 | owns 49 | 50 | 51 | 52 | sqlxpg::models 53 | 54 | orphan mod 55 | 56 | models 57 | 58 | 59 | 60 | sqlxpg->sqlxpg::models 61 | 62 | 63 | owns 64 | 65 | 66 | 67 | sqlxpg::api::routes 68 | 69 | pub mod 70 | 71 | api::routes 72 | 73 | 74 | 75 | sqlxpg::api->sqlxpg::api::routes 76 | 77 | 78 | owns 79 | 80 | 81 | 82 | sqlxpg::api::user 83 | 84 | pub mod 85 | 86 | api::user 87 | 88 | 89 | 90 | sqlxpg::api->sqlxpg::api::user 91 | 92 | 93 | owns 94 | 95 | 96 | 97 | sqlxpg::api::book 98 | 99 | pub mod 100 | 101 | api::book 102 | 103 | 104 | 105 | sqlxpg::api->sqlxpg::api::book 106 | 107 | 108 | owns 109 | 110 | 111 | 112 | sqlxpg::model::models 113 | 114 | pub mod 115 | 116 | model::models 117 | 118 | 119 | 120 | sqlxpg::model->sqlxpg::model::models 121 | 122 | 123 | owns 124 | 125 | 126 | 127 | sqlxpg::model::usermodel 128 | 129 | pub mod 130 | 131 | model::usermodel 132 | 133 | 134 | 135 | sqlxpg::model->sqlxpg::model::usermodel 136 | 137 | 138 | owns 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /Curso/Rust.md: -------------------------------------------------------------------------------- 1 | # Introdução aos Algoritmos com Rust 2 | 3 | *instrutor Ricardo da Rocha Vitor ricardodarocha@outlook.com 4 | Atividade Complementar - Curso de Rust 5 | UNIFAGOC - https://unifagoc.edu.br/ 6 | 7 | Este curso é baseado na página _Stanford's course on programming language theory and design_ [^1] 8 | Adaptado por Ricardo da Rocha Vitor em 2025-I, com base nos exercícios de Manzano, Lógica para desenvolvimento de programação de computadores. 9 | 10 | ## Introdução 11 | 12 | Rust é uma linguagem de programação moderna, focada em segurança e desempenho. Neste material, aprenderemos os conceitos básicos de lógica de programação utilizando Rust, incluindo blocos principais de código, tomadas de decisão, loops, tipos primitivos e fluxos de controle, como atividades complementares das disciplinas de "Raciocínio Lógico" e "Algoritmos e Estruturas de Dados". 13 | 14 | Para ver um exemplo de programa em Rust rodando no browser acesse o notebook do [🦀 Rust PlayGround](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=45ab44ec75b840c149467729adfe822a) 15 | 16 | ## 1. Estrutura Básica de um Programa em Rust 17 | 18 | Um programa em Rust sempre começa pela função `main`: 19 | 20 | ```rust 21 | fn main() { 22 | println!("Olá, mundo!"); 23 | } 24 | ``` 25 | 26 | A função `main` é o ponto de entrada do programa. A macro `println!` imprime uma mensagem na tela. 27 | 28 | > Neste curso eu preparei duas macros que permitirão usar `leia!()` e `imprima!()` em vez de `read` e `println!`, dois comandos nativos essenciais em Rust. O objetivo é aproximá-los da didática apresentada pelos autores Manzano e Dantas 29 | > O uso de `read` em Rust é um conteúdo mais avançado, porém o uso de `println!` é bem comum e é importante o seu conhecimento. 30 | 31 | ## 2. Tipos Primitivos 32 | 33 | Rust possui diversos tipos de dados primitivos: 34 | 35 | - **Inteiros** (`i8`, `i16`, `i32`, `i64`, `u8`, `u16`, `u32`, `u64`) 36 | - **Ponto flutuante** (`f32`, `f64`) 37 | - **Booleano** (`bool`) 38 | - **Caracteres** (`char`) 39 | 40 | Exemplo: 41 | 42 | ```rust 43 | let inteiro: i32 = 10; 44 | let flutuante: f64 = 3.14; 45 | let booleano: bool = true; 46 | let caractere: char = 'A'; 47 | ``` 48 | 49 | --- 50 | 51 | > Algumas linguagens possuem tipos com nomes diferentes 52 | > Para renomear os tipos usando os nomes que você já tem familiaridade use o comando `type`; 53 | > ```rust 54 | > type int = i32; 55 | > type logico = bool; 56 | > ``` 57 | 58 | ### 2.a) declaração de variáveis 59 | 60 | Declare variáveis com o comando **let** 61 | ```rust 62 | let nome = "Santos Dummont"; 63 | let nascimento = 1873; 64 | ``` 65 | 66 | > 🔥🔥 **Variáveis mutáveis** 67 | > Se pretende alterar o valor de uma variável ao longo do processo, lembre de adicionar o prefixo **mut** (mutável) 68 | > ```rust 69 | > let mut idade = 18; 70 | > idade += 1; 71 | > ``` 72 | 73 | 74 | ### 2.b) atribuição de valores 75 | 76 | $idade \leftarrow 18$ 77 | Simbologia adotada por Manzano [^2] 78 | 79 | ```rust 80 | let idade = 18; 81 | ``` 82 | 83 | > **Outras formas de atribuição** 84 | > ```rust 85 | > let mut idade: i32; //a variável poderá ser modificada 86 | > idade = 1; 87 | > idade += 10; //incrementa 88 | > idade -= 1; //decremento 89 | > asserteq!(idade == 10); //✅ 90 | > idade *= 3; //multiplicando por ele mesmo 91 | > asserteq!(idade == 30); //✅ 92 | > idade /= 2; //dividindo ele mesmo por 2 93 | > asserteq!(idade == 15); //✅ 94 | > ``` 95 | 96 | ### 2.c) comparação lógica 97 | 98 | ``` 99 | == igualdade 100 | >= maior ou igual 101 | <= menor ou igual 102 | > maior 103 | < menor 104 | != diferente 105 | ``` 106 | 107 | ```rust 108 | if x == 42 { 109 | 110 | } 111 | ``` 112 | 113 | ## 3. Blocos de Decisão (Condicionais) 114 | 115 | Usamos `if` para tomar decisões: 116 | 117 | ```rust 118 | fn main() { 119 | let idade = 26; 120 | if idade > 18 { 121 | println!("Maior de idade"); 122 | } else 123 | println!("Menor de idade"); 124 | } 125 | } 126 | ``` 127 | 128 | ### 3. a) Se 129 | 130 | ```rust 131 | if idade > 18 { 132 | 133 | } 134 | ``` 135 | 136 | ### 3. b) Múltiplos Se em sequência 137 | 138 | ![image](https://github.com/user-attachments/assets/edc97107-e5a4-4a40-adae-6701af8eb671) 139 | 140 | ```rust 141 | if numero > m { 142 | m = numero; 143 | } 144 | if numero < n { 145 | n = numero; 146 | } 147 | ``` 148 | 149 | ### 3. c) Se Senão 150 | 151 | ```rust 152 | if numero % 2 == 0 { 153 | print!("É par") 154 | } else { 155 | print!("É ímpar"); 156 | } 157 | ``` 158 | 159 | ### 3. c) Se - Senão Se 160 | 161 | ```rust 162 | if sinal == "vermelho" { 163 | print!("🔴") 164 | } else if sinal == "amarelo"{ 165 | print!("🟠"); 166 | } else { 167 | print!("🟢"); 168 | } 169 | ``` 170 | 171 | ### 3. d) Se aninhados 172 | 173 | ```rust 174 | if numero < 60 { 175 | if numero > 0 { 176 | if numero > 41 { 177 | if numero < 43{ 178 | print!("O número é 42"); 179 | } 180 | } 181 | } 182 | } 183 | ``` 184 | 185 | --- 186 | 187 | Blocos de decisão também podem ter várias condições 188 | Note que, ao resolver a primeira condição, o sistema não irá percorrer as demais 189 | ```rust 190 | let idade = 160; 191 | if idade < 18 { 192 | println!("👶 Menor de idade"); 193 | } else if idade < 100 { 194 | println!("👨 Maior de idade"); 195 | } else { 196 | println!("👴 Ancião"); 197 | } 198 | } 199 | ``` 200 | 🚸 Blocos de decisão com mais de duas condições se tornam complexos, sendo a fonte de muitos bugs em programação de sistemas. Um exemplo ocorre ao deixar certas condições sem tratamento. 201 | 202 | O código abaixo gera alguns bugs por não considerar 203 | corretamente valores entre 40 e 65 204 | 205 | ```rust 206 | // 💣 código contém bug 207 | let idade = 42; 208 | if idade < 18 { 209 | println!("Menor de idade"); 210 | } else if idade < 40 { 211 | println!("Idade Militar"); 212 | } else if idade >= 65 { 213 | println!("Aponsentado"); 214 | } 215 | } 216 | ``` 217 | 218 | O grande problema de códigos deste tipo é que aparentemente não há nada de errado com ele. Como possui uma sintaxe correta, o compilador executa normalmente. 219 | Analise o diagrama de fluxo com cuidado 220 | ```mermaid 221 | flowchart TD 222 | L0@{ shape: circle, label: "inicio"} 223 | L0 --> IDADE; IDADE@{ shape: notch-rect, label: "idade"} 224 | IDADE --> SE; 225 | SE{". . ." } 226 | SE-- Idade < 18 -->MENOR 227 | SE-- Idade < 40 -->IDADEMILITAR 228 | SE-- Idade < 65 -->BUG 229 | SE-- Idade >= 65 -->APOSENTADO 230 | MENOR --> SAIDA 231 | IDADEMILITAR --> SAIDA 232 | APOSENTADO --> SAIDA 233 | MENOR@{ shape: doc, label: "Menor de idade"} 234 | IDADEMILITAR@{ shape: doc, label: "Idade militar"} 235 | APOSENTADO@{ shape: doc, label: "Aposentado"} 236 | style BUG stroke:#f66,stroke-width:2px,stroke-dasharray: 3 5 237 | SAIDA@{ shape: circle, label: "fim"} 238 | 239 | ``` 240 | 241 | Em alguns casos podemos usar `match` para lidar com múltiplas possibilidades, evitando o problema de condições não especificadas: 242 | 243 | ```rust 244 | fn main() { 245 | let opcao = 2; 246 | match opcao { 247 | 1 => println!("Escolheu 1"), 248 | 2 => println!("Escolheu 2"), 249 | _ => println!("Opção desconhecida"), 250 | } 251 | } 252 | ``` 253 | 254 | Este padrão de *pattern matching* do rust utiliza o princípio de análise exaustiva, no qual todas as possibilidades devem ser atendidas. Caso haja alguma condição não explicitamente atendida, o compilador emitirá uma alerta; 255 | 256 | Veja 257 | 258 | ```rust 259 | let idade: usize = 42; 260 | 261 | match idade { 262 | 0..=17 => println!("Menor de idade"), 263 | 18..=39 => println!("Idade Militar"), 264 | 65..=u32::MAX as u32 => println!("Aposentado"), 265 | _ => println!("idade entre 40 e 65, não aposentado"), 266 | } 267 | ``` 268 | 269 | Se omitir o símbolo _ que representa os demais casos, os programa não irá compilar. Isso ajuda a evitar vários bugs e identificar buracos no código 270 | 271 | ``` 272 | match idade { 273 | | ^^^^^ patterns `40..=u32::MAX` not covered 274 | | 275 | ``` 276 | ## 4. Laços de Repetição (Loops) 277 | 278 | Rust possui três tipos principais de loops: 279 | 280 | ### 4.1 `loop` 281 | 282 | Executa indefinidamente até que um `break` seja encontrado: 283 | 284 | ```rust 285 | fn main() { 286 | let mut contador = 0; 287 | loop { 288 | if contador >= 5 { 289 | break; 290 | } 291 | println!("Contador: {}", contador); 292 | contador += 1; 293 | } 294 | } 295 | ``` 296 | 297 | ### 4.2 `while` 298 | 299 | Executa enquanto a condição for verdadeira: 300 | 301 | ```rust 302 | fn main() { 303 | let mut contador = 0; 304 | while contador < 5 { 305 | println!("Contador: {}", contador); 306 | contador += 1; 307 | } 308 | } 309 | ``` 310 | 311 | ### 4.3 `for` 312 | 313 | Itera sobre um intervalo de valores: 314 | 315 | ```rust 316 | fn main() { 317 | for i in 1..=5 { 318 | println!("Número: {}", i); 319 | } 320 | } 321 | ``` 322 | 323 | ## 5. Fluxo de Controle aninhados 324 | 325 | Podemos modificar o fluxo de execução usando `break` e `continue`: 326 | 327 | ```rust 328 | fn main() { 329 | for i in 1..=10 { 330 | if i == 5 { 331 | continue; // Pula o número 5 332 | } 333 | if i == 8 { 334 | break; // Interrompe o loop no número 8 335 | } 336 | println!("{}", i); 337 | } 338 | } 339 | ``` 340 | 341 | ## 6. Revisão 342 | 343 | ```rust 344 | fn main() { 345 | // Variáveis 346 | let n: i32 = 1; 347 | 348 | //Constantes 349 | const pi = 3.14159; 350 | 351 | // Atribuição por inferência 352 | let n = 1; 353 | 354 | // Sombreamento (Shadowing variable) 355 | //🚸Atenção, a técnica de sombreamento inutiliza a variável anterior, criando uma nova variável com novo valor 356 | let n = n + 1; 357 | 358 | // Valores mutáveis 359 | let mut n = 0; 360 | n = n + 1; 361 | 362 | // Ponteiros de &str imutáveis 363 | //🚸Atenção, &str não pode ser mutáveis sem conhecimento de lifetimes (ciclo de vida) 364 | let s: &str = "Hello world"; 365 | 366 | // Strings mutáveis 367 | let mut s: String = String::from("Olá "); 368 | s.push_str("mundo!"); 369 | 370 | // Tuplas 371 | let r = 87; 372 | let g = 13; 373 | let b = 248; 374 | let rgb = (r, g, b); 375 | 376 | // uma tupla representando a cor índigo em RGB 🟣 377 | let indigo = (87, 13, 248); 378 | 379 | // Desestruturação 380 | let (r, g, b) = indigo; 381 | println!("r{}, g{}, b{}", r, g, b); 382 | 383 | // Struct para definir estruturas de dados 384 | struct Coordenada { x: f32, y: f32 }; 385 | 386 | // Construtores nativos 387 | let cc: Coordenada = Coordenada { x: 1.0, y: 2.0 }; 388 | 389 | // Acessando os campos 390 | println!("({}, {})", cc.x, cc.y); 391 | 392 | // Enumerados 393 | enum PontosCardeais { 394 | Norte, 395 | Sul, 396 | Leste, 397 | Oeste 398 | } 399 | 400 | // Genéricos 401 | struct Numero { 402 | valor: T 403 | } 404 | 405 | // Exemplo de uso de genéricos 406 | let inteiro = Numero { 407 | valor: 89 408 | } 409 | 410 | let real = Numero { 411 | valor: 3.14159 412 | } 413 | 414 | // Mônadas 415 | // a) Option 416 | enum Option { None, Some(T) } 417 | 418 | // Mônadas 419 | // b) Result 420 | enum Result { Ok(T), Err(E) } 421 | 422 | // Constructores para tipos enumerados 423 | let valor_opcional: Option = Option::Some(42); 424 | 425 | // Avaliação exaustiva de Mônadas 426 | println!("{}", 427 | match valor_opcional { 428 | Option::Some(valor) => valor, 429 | Option::None => -1 430 | }); 431 | 432 | // Vetores redimensionáveis 433 | let mut vetor: Vec = Vec::new(); 434 | vetor.push(2); 435 | vetor.push(3); 436 | 437 | // Arrays (Vetores de tamanho fixo) 438 | let mut array: [i32; 4] = [0, 2, 4, 8]; 439 | arr[0] = -2; 440 | println!("{}", arr[0] + arr[1]); 441 | 442 | // Slices (fatiando vetores) 443 | let mut slice: &[i32] = &arr[1..]; 444 | println!("{}", slice.iter().sum::()); 445 | 446 | // Iteradores 447 | // Percorrem todos os valores de um vetor ou iterável 448 | for i in v.iter() { 449 | println!("{}", i); 450 | } 451 | 452 | // Loop Infinito (while true). 453 | let mut i = 0; 454 | loop { 455 | i += 1; 456 | if i == 10 { break; } 457 | } 458 | 459 | // Loop enquanto a condição for verdadeira 460 | while i < 20 { 461 | i += 1; 462 | } 463 | } 464 | 465 | // Funções 466 | fn fib(n: i32) -> i32 { 467 | if n <= 1 { n } else { fib(n-1) + fib(n-2) } 468 | } 469 | ``` 470 | 471 | ## Conclusão 472 | 473 | Rust é uma linguagem poderosa para a lógica de programação. Compreender a estrutura do código, decisões condicionais, loops e fluxo de controle é essencial para desenvolver programas eficientes. Aprender Rust desde cedo pode ser um divisor de águas na carreira do programador, pois a forma estruturada e o compilador bastante exigente poderá auxiliar na construção de programas mais sólidos e hábitos mais saudáveis como tipagem estática, ciclo de vida de variáveis, imutabilidade etc. 474 | 475 | # Referências 476 | 477 | [^1]: [Stanford's course on programming language theory and design](https://stanford-cs242.github.io/f19/labs/rust.html) 478 | 479 | [^2]: [MANZANO, Augusto. Algoritmos. Lógica Para Desenvolvimento de Programação](https://www.amazon.com.br/Algoritmos-L%C3%B3gica-Para-Desenvolvimento-Programa%C3%A7%C3%A3o/dp/8536502215) 480 | 481 | [MANZANO, Augusto. **Primeiros passos com a linguagem Rust**](https://www.amazon.com.br/Primeiros-passos-com-linguagem-Rust-ebook/dp/B07DV3CF14) 482 | 483 | [A linguagem de programação Rust](https://rust-br.github.io/rust-book-pt-br/title-page.html) 484 | -------------------------------------------------------------------------------- /6_post/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "autocfg" 7 | version = "1.1.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 10 | 11 | [[package]] 12 | name = "base64" 13 | version = "0.13.0" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" 16 | 17 | [[package]] 18 | name = "bitflags" 19 | version = "1.3.2" 20 | source = "registry+https://github.com/rust-lang/crates.io-index" 21 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 22 | 23 | [[package]] 24 | name = "bumpalo" 25 | version = "3.9.1" 26 | source = "registry+https://github.com/rust-lang/crates.io-index" 27 | checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" 28 | 29 | [[package]] 30 | name = "bytes" 31 | version = "1.1.0" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" 34 | 35 | [[package]] 36 | name = "cc" 37 | version = "1.0.73" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" 40 | 41 | [[package]] 42 | name = "cfg-if" 43 | version = "1.0.0" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 46 | 47 | [[package]] 48 | name = "core-foundation" 49 | version = "0.9.3" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" 52 | dependencies = [ 53 | "core-foundation-sys", 54 | "libc", 55 | ] 56 | 57 | [[package]] 58 | name = "core-foundation-sys" 59 | version = "0.8.3" 60 | source = "registry+https://github.com/rust-lang/crates.io-index" 61 | checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" 62 | 63 | [[package]] 64 | name = "encoding_rs" 65 | version = "0.8.31" 66 | source = "registry+https://github.com/rust-lang/crates.io-index" 67 | checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" 68 | dependencies = [ 69 | "cfg-if", 70 | ] 71 | 72 | [[package]] 73 | name = "fastrand" 74 | version = "1.7.0" 75 | source = "registry+https://github.com/rust-lang/crates.io-index" 76 | checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" 77 | dependencies = [ 78 | "instant", 79 | ] 80 | 81 | [[package]] 82 | name = "fnv" 83 | version = "1.0.7" 84 | source = "registry+https://github.com/rust-lang/crates.io-index" 85 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 86 | 87 | [[package]] 88 | name = "foreign-types" 89 | version = "0.3.2" 90 | source = "registry+https://github.com/rust-lang/crates.io-index" 91 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 92 | dependencies = [ 93 | "foreign-types-shared", 94 | ] 95 | 96 | [[package]] 97 | name = "foreign-types-shared" 98 | version = "0.1.1" 99 | source = "registry+https://github.com/rust-lang/crates.io-index" 100 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 101 | 102 | [[package]] 103 | name = "form_urlencoded" 104 | version = "1.0.1" 105 | source = "registry+https://github.com/rust-lang/crates.io-index" 106 | checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" 107 | dependencies = [ 108 | "matches", 109 | "percent-encoding", 110 | ] 111 | 112 | [[package]] 113 | name = "futures-channel" 114 | version = "0.3.21" 115 | source = "registry+https://github.com/rust-lang/crates.io-index" 116 | checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" 117 | dependencies = [ 118 | "futures-core", 119 | ] 120 | 121 | [[package]] 122 | name = "futures-core" 123 | version = "0.3.21" 124 | source = "registry+https://github.com/rust-lang/crates.io-index" 125 | checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" 126 | 127 | [[package]] 128 | name = "futures-io" 129 | version = "0.3.21" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" 132 | 133 | [[package]] 134 | name = "futures-sink" 135 | version = "0.3.21" 136 | source = "registry+https://github.com/rust-lang/crates.io-index" 137 | checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" 138 | 139 | [[package]] 140 | name = "futures-task" 141 | version = "0.3.21" 142 | source = "registry+https://github.com/rust-lang/crates.io-index" 143 | checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" 144 | 145 | [[package]] 146 | name = "futures-util" 147 | version = "0.3.21" 148 | source = "registry+https://github.com/rust-lang/crates.io-index" 149 | checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" 150 | dependencies = [ 151 | "futures-core", 152 | "futures-io", 153 | "futures-task", 154 | "memchr", 155 | "pin-project-lite", 156 | "pin-utils", 157 | "slab", 158 | ] 159 | 160 | [[package]] 161 | name = "h2" 162 | version = "0.3.13" 163 | source = "registry+https://github.com/rust-lang/crates.io-index" 164 | checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" 165 | dependencies = [ 166 | "bytes", 167 | "fnv", 168 | "futures-core", 169 | "futures-sink", 170 | "futures-util", 171 | "http 0.2.7", 172 | "indexmap", 173 | "slab", 174 | "tokio", 175 | "tokio-util", 176 | "tracing", 177 | ] 178 | 179 | [[package]] 180 | name = "hashbrown" 181 | version = "0.11.2" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" 184 | 185 | [[package]] 186 | name = "hermit-abi" 187 | version = "0.1.19" 188 | source = "registry+https://github.com/rust-lang/crates.io-index" 189 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 190 | dependencies = [ 191 | "libc", 192 | ] 193 | 194 | [[package]] 195 | name = "http" 196 | version = "0.1.0" 197 | dependencies = [ 198 | "reqwest", 199 | ] 200 | 201 | [[package]] 202 | name = "http" 203 | version = "0.2.7" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | checksum = "ff8670570af52249509a86f5e3e18a08c60b177071826898fde8997cf5f6bfbb" 206 | dependencies = [ 207 | "bytes", 208 | "fnv", 209 | "itoa", 210 | ] 211 | 212 | [[package]] 213 | name = "http-body" 214 | version = "0.4.4" 215 | source = "registry+https://github.com/rust-lang/crates.io-index" 216 | checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" 217 | dependencies = [ 218 | "bytes", 219 | "http 0.2.7", 220 | "pin-project-lite", 221 | ] 222 | 223 | [[package]] 224 | name = "httparse" 225 | version = "1.7.1" 226 | source = "registry+https://github.com/rust-lang/crates.io-index" 227 | checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" 228 | 229 | [[package]] 230 | name = "httpdate" 231 | version = "1.0.2" 232 | source = "registry+https://github.com/rust-lang/crates.io-index" 233 | checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" 234 | 235 | [[package]] 236 | name = "hyper" 237 | version = "0.14.18" 238 | source = "registry+https://github.com/rust-lang/crates.io-index" 239 | checksum = "b26ae0a80afebe130861d90abf98e3814a4f28a4c6ffeb5ab8ebb2be311e0ef2" 240 | dependencies = [ 241 | "bytes", 242 | "futures-channel", 243 | "futures-core", 244 | "futures-util", 245 | "h2", 246 | "http 0.2.7", 247 | "http-body", 248 | "httparse", 249 | "httpdate", 250 | "itoa", 251 | "pin-project-lite", 252 | "socket2", 253 | "tokio", 254 | "tower-service", 255 | "tracing", 256 | "want", 257 | ] 258 | 259 | [[package]] 260 | name = "hyper-tls" 261 | version = "0.5.0" 262 | source = "registry+https://github.com/rust-lang/crates.io-index" 263 | checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" 264 | dependencies = [ 265 | "bytes", 266 | "hyper", 267 | "native-tls", 268 | "tokio", 269 | "tokio-native-tls", 270 | ] 271 | 272 | [[package]] 273 | name = "idna" 274 | version = "0.2.3" 275 | source = "registry+https://github.com/rust-lang/crates.io-index" 276 | checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" 277 | dependencies = [ 278 | "matches", 279 | "unicode-bidi", 280 | "unicode-normalization", 281 | ] 282 | 283 | [[package]] 284 | name = "indexmap" 285 | version = "1.8.1" 286 | source = "registry+https://github.com/rust-lang/crates.io-index" 287 | checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" 288 | dependencies = [ 289 | "autocfg", 290 | "hashbrown", 291 | ] 292 | 293 | [[package]] 294 | name = "instant" 295 | version = "0.1.12" 296 | source = "registry+https://github.com/rust-lang/crates.io-index" 297 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 298 | dependencies = [ 299 | "cfg-if", 300 | ] 301 | 302 | [[package]] 303 | name = "ipnet" 304 | version = "2.5.0" 305 | source = "registry+https://github.com/rust-lang/crates.io-index" 306 | checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" 307 | 308 | [[package]] 309 | name = "itoa" 310 | version = "1.0.1" 311 | source = "registry+https://github.com/rust-lang/crates.io-index" 312 | checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" 313 | 314 | [[package]] 315 | name = "js-sys" 316 | version = "0.3.57" 317 | source = "registry+https://github.com/rust-lang/crates.io-index" 318 | checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" 319 | dependencies = [ 320 | "wasm-bindgen", 321 | ] 322 | 323 | [[package]] 324 | name = "lazy_static" 325 | version = "1.4.0" 326 | source = "registry+https://github.com/rust-lang/crates.io-index" 327 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 328 | 329 | [[package]] 330 | name = "libc" 331 | version = "0.2.125" 332 | source = "registry+https://github.com/rust-lang/crates.io-index" 333 | checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" 334 | 335 | [[package]] 336 | name = "log" 337 | version = "0.4.17" 338 | source = "registry+https://github.com/rust-lang/crates.io-index" 339 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" 340 | dependencies = [ 341 | "cfg-if", 342 | ] 343 | 344 | [[package]] 345 | name = "matches" 346 | version = "0.1.9" 347 | source = "registry+https://github.com/rust-lang/crates.io-index" 348 | checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" 349 | 350 | [[package]] 351 | name = "memchr" 352 | version = "2.5.0" 353 | source = "registry+https://github.com/rust-lang/crates.io-index" 354 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 355 | 356 | [[package]] 357 | name = "mime" 358 | version = "0.3.16" 359 | source = "registry+https://github.com/rust-lang/crates.io-index" 360 | checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" 361 | 362 | [[package]] 363 | name = "mio" 364 | version = "0.8.3" 365 | source = "registry+https://github.com/rust-lang/crates.io-index" 366 | checksum = "713d550d9b44d89174e066b7a6217ae06234c10cb47819a88290d2b353c31799" 367 | dependencies = [ 368 | "libc", 369 | "log", 370 | "wasi", 371 | "windows-sys", 372 | ] 373 | 374 | [[package]] 375 | name = "native-tls" 376 | version = "0.2.10" 377 | source = "registry+https://github.com/rust-lang/crates.io-index" 378 | checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9" 379 | dependencies = [ 380 | "lazy_static", 381 | "libc", 382 | "log", 383 | "openssl", 384 | "openssl-probe", 385 | "openssl-sys", 386 | "schannel", 387 | "security-framework", 388 | "security-framework-sys", 389 | "tempfile", 390 | ] 391 | 392 | [[package]] 393 | name = "num_cpus" 394 | version = "1.13.1" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" 397 | dependencies = [ 398 | "hermit-abi", 399 | "libc", 400 | ] 401 | 402 | [[package]] 403 | name = "once_cell" 404 | version = "1.10.0" 405 | source = "registry+https://github.com/rust-lang/crates.io-index" 406 | checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" 407 | 408 | [[package]] 409 | name = "openssl" 410 | version = "0.10.40" 411 | source = "registry+https://github.com/rust-lang/crates.io-index" 412 | checksum = "fb81a6430ac911acb25fe5ac8f1d2af1b4ea8a4fdfda0f1ee4292af2e2d8eb0e" 413 | dependencies = [ 414 | "bitflags", 415 | "cfg-if", 416 | "foreign-types", 417 | "libc", 418 | "once_cell", 419 | "openssl-macros", 420 | "openssl-sys", 421 | ] 422 | 423 | [[package]] 424 | name = "openssl-macros" 425 | version = "0.1.0" 426 | source = "registry+https://github.com/rust-lang/crates.io-index" 427 | checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" 428 | dependencies = [ 429 | "proc-macro2", 430 | "quote", 431 | "syn", 432 | ] 433 | 434 | [[package]] 435 | name = "openssl-probe" 436 | version = "0.1.5" 437 | source = "registry+https://github.com/rust-lang/crates.io-index" 438 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 439 | 440 | [[package]] 441 | name = "openssl-sys" 442 | version = "0.9.73" 443 | source = "registry+https://github.com/rust-lang/crates.io-index" 444 | checksum = "9d5fd19fb3e0a8191c1e34935718976a3e70c112ab9a24af6d7cadccd9d90bc0" 445 | dependencies = [ 446 | "autocfg", 447 | "cc", 448 | "libc", 449 | "pkg-config", 450 | "vcpkg", 451 | ] 452 | 453 | [[package]] 454 | name = "percent-encoding" 455 | version = "2.1.0" 456 | source = "registry+https://github.com/rust-lang/crates.io-index" 457 | checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" 458 | 459 | [[package]] 460 | name = "pin-project-lite" 461 | version = "0.2.9" 462 | source = "registry+https://github.com/rust-lang/crates.io-index" 463 | checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" 464 | 465 | [[package]] 466 | name = "pin-utils" 467 | version = "0.1.0" 468 | source = "registry+https://github.com/rust-lang/crates.io-index" 469 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 470 | 471 | [[package]] 472 | name = "pkg-config" 473 | version = "0.3.25" 474 | source = "registry+https://github.com/rust-lang/crates.io-index" 475 | checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" 476 | 477 | [[package]] 478 | name = "proc-macro2" 479 | version = "1.0.38" 480 | source = "registry+https://github.com/rust-lang/crates.io-index" 481 | checksum = "9027b48e9d4c9175fa2218adf3557f91c1137021739951d4932f5f8268ac48aa" 482 | dependencies = [ 483 | "unicode-xid", 484 | ] 485 | 486 | [[package]] 487 | name = "quote" 488 | version = "1.0.18" 489 | source = "registry+https://github.com/rust-lang/crates.io-index" 490 | checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" 491 | dependencies = [ 492 | "proc-macro2", 493 | ] 494 | 495 | [[package]] 496 | name = "redox_syscall" 497 | version = "0.2.13" 498 | source = "registry+https://github.com/rust-lang/crates.io-index" 499 | checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" 500 | dependencies = [ 501 | "bitflags", 502 | ] 503 | 504 | [[package]] 505 | name = "remove_dir_all" 506 | version = "0.5.3" 507 | source = "registry+https://github.com/rust-lang/crates.io-index" 508 | checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" 509 | dependencies = [ 510 | "winapi", 511 | ] 512 | 513 | [[package]] 514 | name = "reqwest" 515 | version = "0.11.10" 516 | source = "registry+https://github.com/rust-lang/crates.io-index" 517 | checksum = "46a1f7aa4f35e5e8b4160449f51afc758f0ce6454315a9fa7d0d113e958c41eb" 518 | dependencies = [ 519 | "base64", 520 | "bytes", 521 | "encoding_rs", 522 | "futures-core", 523 | "futures-util", 524 | "h2", 525 | "http 0.2.7", 526 | "http-body", 527 | "hyper", 528 | "hyper-tls", 529 | "ipnet", 530 | "js-sys", 531 | "lazy_static", 532 | "log", 533 | "mime", 534 | "native-tls", 535 | "percent-encoding", 536 | "pin-project-lite", 537 | "serde", 538 | "serde_json", 539 | "serde_urlencoded", 540 | "tokio", 541 | "tokio-native-tls", 542 | "url", 543 | "wasm-bindgen", 544 | "wasm-bindgen-futures", 545 | "web-sys", 546 | "winreg", 547 | ] 548 | 549 | [[package]] 550 | name = "ryu" 551 | version = "1.0.9" 552 | source = "registry+https://github.com/rust-lang/crates.io-index" 553 | checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" 554 | 555 | [[package]] 556 | name = "schannel" 557 | version = "0.1.19" 558 | source = "registry+https://github.com/rust-lang/crates.io-index" 559 | checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" 560 | dependencies = [ 561 | "lazy_static", 562 | "winapi", 563 | ] 564 | 565 | [[package]] 566 | name = "security-framework" 567 | version = "2.6.1" 568 | source = "registry+https://github.com/rust-lang/crates.io-index" 569 | checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" 570 | dependencies = [ 571 | "bitflags", 572 | "core-foundation", 573 | "core-foundation-sys", 574 | "libc", 575 | "security-framework-sys", 576 | ] 577 | 578 | [[package]] 579 | name = "security-framework-sys" 580 | version = "2.6.1" 581 | source = "registry+https://github.com/rust-lang/crates.io-index" 582 | checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" 583 | dependencies = [ 584 | "core-foundation-sys", 585 | "libc", 586 | ] 587 | 588 | [[package]] 589 | name = "serde" 590 | version = "1.0.137" 591 | source = "registry+https://github.com/rust-lang/crates.io-index" 592 | checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" 593 | 594 | [[package]] 595 | name = "serde_json" 596 | version = "1.0.81" 597 | source = "registry+https://github.com/rust-lang/crates.io-index" 598 | checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" 599 | dependencies = [ 600 | "itoa", 601 | "ryu", 602 | "serde", 603 | ] 604 | 605 | [[package]] 606 | name = "serde_urlencoded" 607 | version = "0.7.1" 608 | source = "registry+https://github.com/rust-lang/crates.io-index" 609 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 610 | dependencies = [ 611 | "form_urlencoded", 612 | "itoa", 613 | "ryu", 614 | "serde", 615 | ] 616 | 617 | [[package]] 618 | name = "slab" 619 | version = "0.4.6" 620 | source = "registry+https://github.com/rust-lang/crates.io-index" 621 | checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" 622 | 623 | [[package]] 624 | name = "socket2" 625 | version = "0.4.4" 626 | source = "registry+https://github.com/rust-lang/crates.io-index" 627 | checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" 628 | dependencies = [ 629 | "libc", 630 | "winapi", 631 | ] 632 | 633 | [[package]] 634 | name = "syn" 635 | version = "1.0.93" 636 | source = "registry+https://github.com/rust-lang/crates.io-index" 637 | checksum = "04066589568b72ec65f42d65a1a52436e954b168773148893c020269563decf2" 638 | dependencies = [ 639 | "proc-macro2", 640 | "quote", 641 | "unicode-xid", 642 | ] 643 | 644 | [[package]] 645 | name = "tempfile" 646 | version = "3.3.0" 647 | source = "registry+https://github.com/rust-lang/crates.io-index" 648 | checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" 649 | dependencies = [ 650 | "cfg-if", 651 | "fastrand", 652 | "libc", 653 | "redox_syscall", 654 | "remove_dir_all", 655 | "winapi", 656 | ] 657 | 658 | [[package]] 659 | name = "tinyvec" 660 | version = "1.6.0" 661 | source = "registry+https://github.com/rust-lang/crates.io-index" 662 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 663 | dependencies = [ 664 | "tinyvec_macros", 665 | ] 666 | 667 | [[package]] 668 | name = "tinyvec_macros" 669 | version = "0.1.0" 670 | source = "registry+https://github.com/rust-lang/crates.io-index" 671 | checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" 672 | 673 | [[package]] 674 | name = "tokio" 675 | version = "1.18.2" 676 | source = "registry+https://github.com/rust-lang/crates.io-index" 677 | checksum = "4903bf0427cf68dddd5aa6a93220756f8be0c34fcfa9f5e6191e103e15a31395" 678 | dependencies = [ 679 | "bytes", 680 | "libc", 681 | "memchr", 682 | "mio", 683 | "num_cpus", 684 | "once_cell", 685 | "pin-project-lite", 686 | "socket2", 687 | "winapi", 688 | ] 689 | 690 | [[package]] 691 | name = "tokio-native-tls" 692 | version = "0.3.0" 693 | source = "registry+https://github.com/rust-lang/crates.io-index" 694 | checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" 695 | dependencies = [ 696 | "native-tls", 697 | "tokio", 698 | ] 699 | 700 | [[package]] 701 | name = "tokio-util" 702 | version = "0.7.1" 703 | source = "registry+https://github.com/rust-lang/crates.io-index" 704 | checksum = "0edfdeb067411dba2044da6d1cb2df793dd35add7888d73c16e3381ded401764" 705 | dependencies = [ 706 | "bytes", 707 | "futures-core", 708 | "futures-sink", 709 | "pin-project-lite", 710 | "tokio", 711 | "tracing", 712 | ] 713 | 714 | [[package]] 715 | name = "tower-service" 716 | version = "0.3.1" 717 | source = "registry+https://github.com/rust-lang/crates.io-index" 718 | checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" 719 | 720 | [[package]] 721 | name = "tracing" 722 | version = "0.1.34" 723 | source = "registry+https://github.com/rust-lang/crates.io-index" 724 | checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" 725 | dependencies = [ 726 | "cfg-if", 727 | "pin-project-lite", 728 | "tracing-attributes", 729 | "tracing-core", 730 | ] 731 | 732 | [[package]] 733 | name = "tracing-attributes" 734 | version = "0.1.21" 735 | source = "registry+https://github.com/rust-lang/crates.io-index" 736 | checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c" 737 | dependencies = [ 738 | "proc-macro2", 739 | "quote", 740 | "syn", 741 | ] 742 | 743 | [[package]] 744 | name = "tracing-core" 745 | version = "0.1.26" 746 | source = "registry+https://github.com/rust-lang/crates.io-index" 747 | checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f" 748 | dependencies = [ 749 | "lazy_static", 750 | ] 751 | 752 | [[package]] 753 | name = "try-lock" 754 | version = "0.2.3" 755 | source = "registry+https://github.com/rust-lang/crates.io-index" 756 | checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" 757 | 758 | [[package]] 759 | name = "unicode-bidi" 760 | version = "0.3.8" 761 | source = "registry+https://github.com/rust-lang/crates.io-index" 762 | checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" 763 | 764 | [[package]] 765 | name = "unicode-normalization" 766 | version = "0.1.19" 767 | source = "registry+https://github.com/rust-lang/crates.io-index" 768 | checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" 769 | dependencies = [ 770 | "tinyvec", 771 | ] 772 | 773 | [[package]] 774 | name = "unicode-xid" 775 | version = "0.2.3" 776 | source = "registry+https://github.com/rust-lang/crates.io-index" 777 | checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" 778 | 779 | [[package]] 780 | name = "url" 781 | version = "2.2.2" 782 | source = "registry+https://github.com/rust-lang/crates.io-index" 783 | checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" 784 | dependencies = [ 785 | "form_urlencoded", 786 | "idna", 787 | "matches", 788 | "percent-encoding", 789 | ] 790 | 791 | [[package]] 792 | name = "vcpkg" 793 | version = "0.2.15" 794 | source = "registry+https://github.com/rust-lang/crates.io-index" 795 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 796 | 797 | [[package]] 798 | name = "want" 799 | version = "0.3.0" 800 | source = "registry+https://github.com/rust-lang/crates.io-index" 801 | checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" 802 | dependencies = [ 803 | "log", 804 | "try-lock", 805 | ] 806 | 807 | [[package]] 808 | name = "wasi" 809 | version = "0.11.0+wasi-snapshot-preview1" 810 | source = "registry+https://github.com/rust-lang/crates.io-index" 811 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 812 | 813 | [[package]] 814 | name = "wasm-bindgen" 815 | version = "0.2.80" 816 | source = "registry+https://github.com/rust-lang/crates.io-index" 817 | checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" 818 | dependencies = [ 819 | "cfg-if", 820 | "wasm-bindgen-macro", 821 | ] 822 | 823 | [[package]] 824 | name = "wasm-bindgen-backend" 825 | version = "0.2.80" 826 | source = "registry+https://github.com/rust-lang/crates.io-index" 827 | checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" 828 | dependencies = [ 829 | "bumpalo", 830 | "lazy_static", 831 | "log", 832 | "proc-macro2", 833 | "quote", 834 | "syn", 835 | "wasm-bindgen-shared", 836 | ] 837 | 838 | [[package]] 839 | name = "wasm-bindgen-futures" 840 | version = "0.4.30" 841 | source = "registry+https://github.com/rust-lang/crates.io-index" 842 | checksum = "6f741de44b75e14c35df886aff5f1eb73aa114fa5d4d00dcd37b5e01259bf3b2" 843 | dependencies = [ 844 | "cfg-if", 845 | "js-sys", 846 | "wasm-bindgen", 847 | "web-sys", 848 | ] 849 | 850 | [[package]] 851 | name = "wasm-bindgen-macro" 852 | version = "0.2.80" 853 | source = "registry+https://github.com/rust-lang/crates.io-index" 854 | checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" 855 | dependencies = [ 856 | "quote", 857 | "wasm-bindgen-macro-support", 858 | ] 859 | 860 | [[package]] 861 | name = "wasm-bindgen-macro-support" 862 | version = "0.2.80" 863 | source = "registry+https://github.com/rust-lang/crates.io-index" 864 | checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" 865 | dependencies = [ 866 | "proc-macro2", 867 | "quote", 868 | "syn", 869 | "wasm-bindgen-backend", 870 | "wasm-bindgen-shared", 871 | ] 872 | 873 | [[package]] 874 | name = "wasm-bindgen-shared" 875 | version = "0.2.80" 876 | source = "registry+https://github.com/rust-lang/crates.io-index" 877 | checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" 878 | 879 | [[package]] 880 | name = "web-sys" 881 | version = "0.3.57" 882 | source = "registry+https://github.com/rust-lang/crates.io-index" 883 | checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" 884 | dependencies = [ 885 | "js-sys", 886 | "wasm-bindgen", 887 | ] 888 | 889 | [[package]] 890 | name = "winapi" 891 | version = "0.3.9" 892 | source = "registry+https://github.com/rust-lang/crates.io-index" 893 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 894 | dependencies = [ 895 | "winapi-i686-pc-windows-gnu", 896 | "winapi-x86_64-pc-windows-gnu", 897 | ] 898 | 899 | [[package]] 900 | name = "winapi-i686-pc-windows-gnu" 901 | version = "0.4.0" 902 | source = "registry+https://github.com/rust-lang/crates.io-index" 903 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 904 | 905 | [[package]] 906 | name = "winapi-x86_64-pc-windows-gnu" 907 | version = "0.4.0" 908 | source = "registry+https://github.com/rust-lang/crates.io-index" 909 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 910 | 911 | [[package]] 912 | name = "windows-sys" 913 | version = "0.36.1" 914 | source = "registry+https://github.com/rust-lang/crates.io-index" 915 | checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" 916 | dependencies = [ 917 | "windows_aarch64_msvc", 918 | "windows_i686_gnu", 919 | "windows_i686_msvc", 920 | "windows_x86_64_gnu", 921 | "windows_x86_64_msvc", 922 | ] 923 | 924 | [[package]] 925 | name = "windows_aarch64_msvc" 926 | version = "0.36.1" 927 | source = "registry+https://github.com/rust-lang/crates.io-index" 928 | checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" 929 | 930 | [[package]] 931 | name = "windows_i686_gnu" 932 | version = "0.36.1" 933 | source = "registry+https://github.com/rust-lang/crates.io-index" 934 | checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" 935 | 936 | [[package]] 937 | name = "windows_i686_msvc" 938 | version = "0.36.1" 939 | source = "registry+https://github.com/rust-lang/crates.io-index" 940 | checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" 941 | 942 | [[package]] 943 | name = "windows_x86_64_gnu" 944 | version = "0.36.1" 945 | source = "registry+https://github.com/rust-lang/crates.io-index" 946 | checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" 947 | 948 | [[package]] 949 | name = "windows_x86_64_msvc" 950 | version = "0.36.1" 951 | source = "registry+https://github.com/rust-lang/crates.io-index" 952 | checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" 953 | 954 | [[package]] 955 | name = "winreg" 956 | version = "0.10.1" 957 | source = "registry+https://github.com/rust-lang/crates.io-index" 958 | checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" 959 | dependencies = [ 960 | "winapi", 961 | ] 962 | --------------------------------------------------------------------------------