├── .gitattributes ├── .gitignore ├── codecrafters.yml ├── your_server.sh ├── README.md ├── Cargo.toml ├── src └── main.rs └── Cargo.lock /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | debug/ 4 | target/ 5 | 6 | # These are backup files generated by rustfmt 7 | **/*.rs.bk 8 | 9 | # MSVC Windows builds of rustc generate these, which store debugging information 10 | *.pdb 11 | -------------------------------------------------------------------------------- /codecrafters.yml: -------------------------------------------------------------------------------- 1 | # Set this to true if you want debug logs. 2 | # 3 | # These can be VERY verbose, so we suggest turning them off 4 | # unless you really need them. 5 | debug: false 6 | 7 | # Use this to change the Rust version used to run your code 8 | # on Codecrafters. 9 | # 10 | # Available versions: rust-1.70 11 | language_pack: rust-1.70 12 | -------------------------------------------------------------------------------- /your_server.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # DON'T EDIT THIS! 4 | # 5 | # CodeCrafters uses this file to test your code. Don't make any changes here! 6 | # 7 | # DON'T EDIT THIS! 8 | exec cargo run \ 9 | --quiet \ 10 | --release \ 11 | --target-dir=/tmp/codecrafters-http-server-target \ 12 | --manifest-path $(dirname $0)/Cargo.toml -- "$@" 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![progress-banner](https://backend.codecrafters.io/progress/http-server/826cd895-6426-46f6-9ad8-2b0abb52b8d6)](https://app.codecrafters.io/users/codecrafters-bot?r=2qF) 2 | 3 | This is a starting point for Rust solutions to the 4 | ["Build Your Own HTTP server" Challenge](https://app.codecrafters.io/courses/http-server/overview). 5 | 6 | [HTTP](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol) is the 7 | protocol that powers the web. In this challenge, you'll build a HTTP/1.1 server 8 | that is capable of serving multiple clients. 9 | 10 | Along the way you'll learn about TCP servers, 11 | [HTTP request syntax](https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html), 12 | and more. 13 | 14 | **Note**: If you're viewing this repo on GitHub, head over to 15 | [codecrafters.io](https://codecrafters.io) to try the challenge. 16 | 17 | # Note 18 | 19 | This is a complete solution to the codecrafters challenge but is definitely not ready for use in production. The code is also neither `clean` or the most `idiomatic rust`. Use at your own risk. 20 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | # DON'T EDIT THIS! 2 | # 3 | # Codecrafters relies on this file being intact to run tests successfully. Any changes 4 | # here will not reflect when CodeCrafters tests your code, and might even cause build 5 | # failures. 6 | # 7 | # DON'T EDIT THIS! 8 | [package] 9 | name = "http-server-starter-rust" 10 | version = "0.1.0" 11 | authors = ["Codecrafters "] 12 | edition = "2021" 13 | 14 | # DON'T EDIT THIS! 15 | # 16 | # Codecrafters relies on this file being intact to run tests successfully. Any changes 17 | # here will not reflect when CodeCrafters tests your code, and might even cause build 18 | # failures. 19 | # 20 | # DON'T EDIT THIS! 21 | [dependencies] 22 | anyhow = "1.0.59" # error handling 23 | bytes = "1.3.0" # helps manage buffers 24 | thiserror = "1.0.38" # error handling 25 | tokio = { version = "1.23.0", features = ["full"] } # async networking 26 | nom = "7.1.3" # parser combinators 27 | itertools = "0.11.0" # General iterator helpers 28 | 29 | [dev-dependencies] 30 | pretty_assertions = "1.3.0" # nicer looking assertions 31 | 32 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | // Uncomment this block to pass the first stage 2 | use std::io::{Read, Write}; 3 | use std::net::{TcpListener, TcpStream}; 4 | use std::path::Path; 5 | use std::{fs, thread}; 6 | 7 | fn handle_client(mut stream: TcpStream, file_directory_path: Option) { 8 | println!("accepted new connection"); 9 | 10 | let mut request_data = String::new(); 11 | 12 | let mut request_buffer = [0; 1024]; 13 | 14 | match stream.read(&mut request_buffer) { 15 | Ok(read_bytes) => { 16 | println!("read_bytes {read_bytes}"); 17 | request_data.extend(String::from_utf8_lossy(&request_buffer[0..read_bytes]).chars()); 18 | } 19 | Err(err) => { 20 | eprintln!("failed to read request {err}"); 21 | } 22 | } 23 | 24 | println!("request-data {request_data}"); 25 | 26 | let mut lines = request_data.split("\r\n").into_iter(); 27 | let startline = lines.next().expect("Missing start line"); 28 | 29 | println!("startline -->|{startline}"); 30 | 31 | let mut segments = startline.split_whitespace(); 32 | let method = segments.next().unwrap(); 33 | let path = segments.next().unwrap(); 34 | 35 | println!("path -> {path}"); 36 | 37 | match path { 38 | "/" => { 39 | let _ = stream 40 | .write("HTTP/1.1 200 OK\r\n\r\n".as_bytes()) 41 | .map_err(|err| eprintln!("failed to write to stream {err}")); 42 | } 43 | _ => { 44 | if path.starts_with("/echo/") { 45 | let random_string = path.strip_prefix("/echo/").expect("failed to strip /echo/"); 46 | 47 | println!("random-string {random_string}"); 48 | 49 | let content_length = random_string.len(); 50 | 51 | let response = format!("HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: {content_length}\r\n\r\n{random_string}\r\n"); 52 | 53 | let _ = stream 54 | .write(response.as_bytes()) 55 | .map_err(|err| eprintln!("failed to write to stream {err}")); 56 | } else if path == "/user-agent" { 57 | let _ = lines.next(); 58 | let user_agent_line = lines.next().expect("missing user agent line"); 59 | let user_agent = user_agent_line 60 | .split(": ") 61 | .skip(1) 62 | .next() 63 | .expect("missing user-agent"); 64 | 65 | let content_length = user_agent.len(); 66 | 67 | let response = format!("HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: {content_length}\r\n\r\n{user_agent}\r\n"); 68 | 69 | let _ = stream 70 | .write(response.as_bytes()) 71 | .map_err(|err| eprintln!("failed to write to stream {err}")); 72 | } else if path.starts_with("/files/") { 73 | let file_name = path 74 | .strip_prefix("/files/") 75 | .expect("failed to strip /files/"); 76 | 77 | match (file_directory_path, method) { 78 | (Some(dir_path), "GET") => { 79 | let file_path = Path::new(&dir_path).join(file_name); 80 | match fs::read(file_path) { 81 | Ok(file) => { 82 | let content_length = file.len(); 83 | let response = format!("HTTP/1.1 200 OK\r\nContent-Type: application/octet-stream\r\nContent-Length: {content_length}\r\n\r\n"); 84 | 85 | let _ = stream 86 | .write(response.as_bytes()) 87 | .map_err(|err| eprintln!("failed to write to stream {err}")); 88 | 89 | let _ = stream.write_all(&file).map_err(|err| { 90 | eprintln!("failed to write file to stream {err}") 91 | }); 92 | } 93 | Err(_) => { 94 | let _ = stream 95 | .write("HTTP/1.1 404 Not Found\r\n\r\n".as_bytes()) 96 | .map_err(|err| eprintln!("failed to write to stream {err}")); 97 | } 98 | } 99 | } 100 | (Some(dir_path), "POST") => { 101 | while lines.next().is_some_and(|l| !l.is_empty()) {} 102 | 103 | let mut file: Vec = Vec::new(); 104 | 105 | for line in lines { 106 | file.extend(line.as_bytes()) 107 | } 108 | 109 | let file_path = Path::new(&dir_path).join(file_name); 110 | match fs::write(file_path, file) { 111 | Ok(_) => { 112 | let response = format!("HTTP/1.1 201 Created\r\n\r\n"); 113 | 114 | let _ = stream 115 | .write(response.as_bytes()) 116 | .map_err(|err| eprintln!("failed to write to stream {err}")); 117 | } 118 | Err(_) => { 119 | let _ = stream 120 | .write("HTTP/1.1 404 Not Found\r\n\r\n".as_bytes()) 121 | .map_err(|err| eprintln!("failed to write to stream {err}")); 122 | } 123 | } 124 | } 125 | _ => { 126 | let _ = stream 127 | .write("HTTP/1.1 404 Not Found\r\n\r\n".as_bytes()) 128 | .map_err(|err| eprintln!("failed to write to stream {err}")); 129 | } 130 | } 131 | } else { 132 | let _ = stream 133 | .write("HTTP/1.1 404 Not Found\r\n\r\n".as_bytes()) 134 | .map_err(|err| eprintln!("failed to write to stream {err}")); 135 | } 136 | } 137 | } 138 | 139 | let _ = stream 140 | .shutdown(std::net::Shutdown::Both) 141 | .map_err(|err| eprintln!("failed to shutdown connection {err}")); 142 | } 143 | 144 | fn main() { 145 | let listener = TcpListener::bind("127.0.0.1:4221").unwrap(); 146 | 147 | let mut file_directory: Option = None; 148 | let args: Vec = std::env::args().collect(); 149 | 150 | match args.len() { 151 | 3 => { 152 | let command = &args[1]; 153 | if command == "--directory" { 154 | file_directory = Some(args[2].clone()); 155 | } 156 | } 157 | _ => {} 158 | } 159 | 160 | for stream in listener.incoming() { 161 | match stream { 162 | Ok(stream) => { 163 | let file_directory = file_directory.clone(); 164 | let _handle = thread::spawn(move || { 165 | handle_client(stream, file_directory); 166 | }); 167 | } 168 | Err(e) => { 169 | println!("error: {}", e); 170 | } 171 | } 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /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 = "addr2line" 7 | version = "0.20.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler" 16 | version = "1.0.2" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 19 | 20 | [[package]] 21 | name = "anyhow" 22 | version = "1.0.68" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" 25 | 26 | [[package]] 27 | name = "autocfg" 28 | version = "1.1.0" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 31 | 32 | [[package]] 33 | name = "backtrace" 34 | version = "0.3.68" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" 37 | dependencies = [ 38 | "addr2line", 39 | "cc", 40 | "cfg-if", 41 | "libc", 42 | "miniz_oxide", 43 | "object", 44 | "rustc-demangle", 45 | ] 46 | 47 | [[package]] 48 | name = "bitflags" 49 | version = "1.3.2" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 52 | 53 | [[package]] 54 | name = "bytes" 55 | version = "1.3.0" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" 58 | 59 | [[package]] 60 | name = "cc" 61 | version = "1.0.79" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" 64 | 65 | [[package]] 66 | name = "cfg-if" 67 | version = "1.0.0" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 70 | 71 | [[package]] 72 | name = "diff" 73 | version = "0.1.13" 74 | source = "registry+https://github.com/rust-lang/crates.io-index" 75 | checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" 76 | 77 | [[package]] 78 | name = "either" 79 | version = "1.9.0" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" 82 | 83 | [[package]] 84 | name = "gimli" 85 | version = "0.27.3" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" 88 | 89 | [[package]] 90 | name = "hermit-abi" 91 | version = "0.3.2" 92 | source = "registry+https://github.com/rust-lang/crates.io-index" 93 | checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" 94 | 95 | [[package]] 96 | name = "http-server-starter-rust" 97 | version = "0.1.0" 98 | dependencies = [ 99 | "anyhow", 100 | "bytes", 101 | "itertools", 102 | "nom", 103 | "pretty_assertions", 104 | "thiserror", 105 | "tokio", 106 | ] 107 | 108 | [[package]] 109 | name = "itertools" 110 | version = "0.11.0" 111 | source = "registry+https://github.com/rust-lang/crates.io-index" 112 | checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" 113 | dependencies = [ 114 | "either", 115 | ] 116 | 117 | [[package]] 118 | name = "libc" 119 | version = "0.2.147" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" 122 | 123 | [[package]] 124 | name = "lock_api" 125 | version = "0.4.10" 126 | source = "registry+https://github.com/rust-lang/crates.io-index" 127 | checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" 128 | dependencies = [ 129 | "autocfg", 130 | "scopeguard", 131 | ] 132 | 133 | [[package]] 134 | name = "memchr" 135 | version = "2.5.0" 136 | source = "registry+https://github.com/rust-lang/crates.io-index" 137 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 138 | 139 | [[package]] 140 | name = "minimal-lexical" 141 | version = "0.2.1" 142 | source = "registry+https://github.com/rust-lang/crates.io-index" 143 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 144 | 145 | [[package]] 146 | name = "miniz_oxide" 147 | version = "0.7.1" 148 | source = "registry+https://github.com/rust-lang/crates.io-index" 149 | checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" 150 | dependencies = [ 151 | "adler", 152 | ] 153 | 154 | [[package]] 155 | name = "mio" 156 | version = "0.8.8" 157 | source = "registry+https://github.com/rust-lang/crates.io-index" 158 | checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" 159 | dependencies = [ 160 | "libc", 161 | "wasi", 162 | "windows-sys", 163 | ] 164 | 165 | [[package]] 166 | name = "nom" 167 | version = "7.1.3" 168 | source = "registry+https://github.com/rust-lang/crates.io-index" 169 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 170 | dependencies = [ 171 | "memchr", 172 | "minimal-lexical", 173 | ] 174 | 175 | [[package]] 176 | name = "num_cpus" 177 | version = "1.16.0" 178 | source = "registry+https://github.com/rust-lang/crates.io-index" 179 | checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" 180 | dependencies = [ 181 | "hermit-abi", 182 | "libc", 183 | ] 184 | 185 | [[package]] 186 | name = "object" 187 | version = "0.31.1" 188 | source = "registry+https://github.com/rust-lang/crates.io-index" 189 | checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" 190 | dependencies = [ 191 | "memchr", 192 | ] 193 | 194 | [[package]] 195 | name = "parking_lot" 196 | version = "0.12.1" 197 | source = "registry+https://github.com/rust-lang/crates.io-index" 198 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 199 | dependencies = [ 200 | "lock_api", 201 | "parking_lot_core", 202 | ] 203 | 204 | [[package]] 205 | name = "parking_lot_core" 206 | version = "0.9.8" 207 | source = "registry+https://github.com/rust-lang/crates.io-index" 208 | checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" 209 | dependencies = [ 210 | "cfg-if", 211 | "libc", 212 | "redox_syscall", 213 | "smallvec", 214 | "windows-targets", 215 | ] 216 | 217 | [[package]] 218 | name = "pin-project-lite" 219 | version = "0.2.10" 220 | source = "registry+https://github.com/rust-lang/crates.io-index" 221 | checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" 222 | 223 | [[package]] 224 | name = "pretty_assertions" 225 | version = "1.4.0" 226 | source = "registry+https://github.com/rust-lang/crates.io-index" 227 | checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" 228 | dependencies = [ 229 | "diff", 230 | "yansi", 231 | ] 232 | 233 | [[package]] 234 | name = "proc-macro2" 235 | version = "1.0.66" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" 238 | dependencies = [ 239 | "unicode-ident", 240 | ] 241 | 242 | [[package]] 243 | name = "quote" 244 | version = "1.0.32" 245 | source = "registry+https://github.com/rust-lang/crates.io-index" 246 | checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" 247 | dependencies = [ 248 | "proc-macro2", 249 | ] 250 | 251 | [[package]] 252 | name = "redox_syscall" 253 | version = "0.3.5" 254 | source = "registry+https://github.com/rust-lang/crates.io-index" 255 | checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" 256 | dependencies = [ 257 | "bitflags", 258 | ] 259 | 260 | [[package]] 261 | name = "rustc-demangle" 262 | version = "0.1.23" 263 | source = "registry+https://github.com/rust-lang/crates.io-index" 264 | checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" 265 | 266 | [[package]] 267 | name = "scopeguard" 268 | version = "1.2.0" 269 | source = "registry+https://github.com/rust-lang/crates.io-index" 270 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 271 | 272 | [[package]] 273 | name = "signal-hook-registry" 274 | version = "1.4.1" 275 | source = "registry+https://github.com/rust-lang/crates.io-index" 276 | checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" 277 | dependencies = [ 278 | "libc", 279 | ] 280 | 281 | [[package]] 282 | name = "smallvec" 283 | version = "1.11.0" 284 | source = "registry+https://github.com/rust-lang/crates.io-index" 285 | checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" 286 | 287 | [[package]] 288 | name = "socket2" 289 | version = "0.4.9" 290 | source = "registry+https://github.com/rust-lang/crates.io-index" 291 | checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" 292 | dependencies = [ 293 | "libc", 294 | "winapi", 295 | ] 296 | 297 | [[package]] 298 | name = "syn" 299 | version = "1.0.48" 300 | source = "registry+https://github.com/rust-lang/crates.io-index" 301 | checksum = "cc371affeffc477f42a221a1e4297aedcea33d47d19b61455588bd9d8f6b19ac" 302 | dependencies = [ 303 | "proc-macro2", 304 | "quote", 305 | "unicode-xid", 306 | ] 307 | 308 | [[package]] 309 | name = "syn" 310 | version = "2.0.27" 311 | source = "registry+https://github.com/rust-lang/crates.io-index" 312 | checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" 313 | dependencies = [ 314 | "proc-macro2", 315 | "quote", 316 | "unicode-ident", 317 | ] 318 | 319 | [[package]] 320 | name = "thiserror" 321 | version = "1.0.38" 322 | source = "registry+https://github.com/rust-lang/crates.io-index" 323 | checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" 324 | dependencies = [ 325 | "thiserror-impl", 326 | ] 327 | 328 | [[package]] 329 | name = "thiserror-impl" 330 | version = "1.0.38" 331 | source = "registry+https://github.com/rust-lang/crates.io-index" 332 | checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" 333 | dependencies = [ 334 | "proc-macro2", 335 | "quote", 336 | "syn 1.0.48", 337 | ] 338 | 339 | [[package]] 340 | name = "tokio" 341 | version = "1.29.1" 342 | source = "registry+https://github.com/rust-lang/crates.io-index" 343 | checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" 344 | dependencies = [ 345 | "autocfg", 346 | "backtrace", 347 | "bytes", 348 | "libc", 349 | "mio", 350 | "num_cpus", 351 | "parking_lot", 352 | "pin-project-lite", 353 | "signal-hook-registry", 354 | "socket2", 355 | "tokio-macros", 356 | "windows-sys", 357 | ] 358 | 359 | [[package]] 360 | name = "tokio-macros" 361 | version = "2.1.0" 362 | source = "registry+https://github.com/rust-lang/crates.io-index" 363 | checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" 364 | dependencies = [ 365 | "proc-macro2", 366 | "quote", 367 | "syn 2.0.27", 368 | ] 369 | 370 | [[package]] 371 | name = "unicode-ident" 372 | version = "1.0.11" 373 | source = "registry+https://github.com/rust-lang/crates.io-index" 374 | checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" 375 | 376 | [[package]] 377 | name = "unicode-xid" 378 | version = "0.2.1" 379 | source = "registry+https://github.com/rust-lang/crates.io-index" 380 | checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" 381 | 382 | [[package]] 383 | name = "wasi" 384 | version = "0.11.0+wasi-snapshot-preview1" 385 | source = "registry+https://github.com/rust-lang/crates.io-index" 386 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 387 | 388 | [[package]] 389 | name = "winapi" 390 | version = "0.3.9" 391 | source = "registry+https://github.com/rust-lang/crates.io-index" 392 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 393 | dependencies = [ 394 | "winapi-i686-pc-windows-gnu", 395 | "winapi-x86_64-pc-windows-gnu", 396 | ] 397 | 398 | [[package]] 399 | name = "winapi-i686-pc-windows-gnu" 400 | version = "0.4.0" 401 | source = "registry+https://github.com/rust-lang/crates.io-index" 402 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 403 | 404 | [[package]] 405 | name = "winapi-x86_64-pc-windows-gnu" 406 | version = "0.4.0" 407 | source = "registry+https://github.com/rust-lang/crates.io-index" 408 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 409 | 410 | [[package]] 411 | name = "windows-sys" 412 | version = "0.48.0" 413 | source = "registry+https://github.com/rust-lang/crates.io-index" 414 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 415 | dependencies = [ 416 | "windows-targets", 417 | ] 418 | 419 | [[package]] 420 | name = "windows-targets" 421 | version = "0.48.1" 422 | source = "registry+https://github.com/rust-lang/crates.io-index" 423 | checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" 424 | dependencies = [ 425 | "windows_aarch64_gnullvm", 426 | "windows_aarch64_msvc", 427 | "windows_i686_gnu", 428 | "windows_i686_msvc", 429 | "windows_x86_64_gnu", 430 | "windows_x86_64_gnullvm", 431 | "windows_x86_64_msvc", 432 | ] 433 | 434 | [[package]] 435 | name = "windows_aarch64_gnullvm" 436 | version = "0.48.0" 437 | source = "registry+https://github.com/rust-lang/crates.io-index" 438 | checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" 439 | 440 | [[package]] 441 | name = "windows_aarch64_msvc" 442 | version = "0.48.0" 443 | source = "registry+https://github.com/rust-lang/crates.io-index" 444 | checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" 445 | 446 | [[package]] 447 | name = "windows_i686_gnu" 448 | version = "0.48.0" 449 | source = "registry+https://github.com/rust-lang/crates.io-index" 450 | checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" 451 | 452 | [[package]] 453 | name = "windows_i686_msvc" 454 | version = "0.48.0" 455 | source = "registry+https://github.com/rust-lang/crates.io-index" 456 | checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" 457 | 458 | [[package]] 459 | name = "windows_x86_64_gnu" 460 | version = "0.48.0" 461 | source = "registry+https://github.com/rust-lang/crates.io-index" 462 | checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" 463 | 464 | [[package]] 465 | name = "windows_x86_64_gnullvm" 466 | version = "0.48.0" 467 | source = "registry+https://github.com/rust-lang/crates.io-index" 468 | checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" 469 | 470 | [[package]] 471 | name = "windows_x86_64_msvc" 472 | version = "0.48.0" 473 | source = "registry+https://github.com/rust-lang/crates.io-index" 474 | checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" 475 | 476 | [[package]] 477 | name = "yansi" 478 | version = "0.5.1" 479 | source = "registry+https://github.com/rust-lang/crates.io-index" 480 | checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" 481 | --------------------------------------------------------------------------------