RIIR
This commit is contained in:
parent
996f4db048
commit
f661ef1fcf
15 changed files with 63437 additions and 367 deletions
3
.cargo/config.toml
Normal file
3
.cargo/config.toml
Normal file
|
@ -0,0 +1,3 @@
|
|||
[target.x86_64-unknown-linux-gnu]
|
||||
linker = "clang"
|
||||
rustflags = ["-C", "link-arg=-fuse-ld=/usr/bin/mold"]
|
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
style.css text eol=style.css
|
170
.gitignore
vendored
170
.gitignore
vendored
|
@ -1,169 +1,3 @@
|
|||
# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
|
||||
# Added by cargo
|
||||
|
||||
# Logs
|
||||
|
||||
logs
|
||||
_.log
|
||||
npm-debug.log_
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
|
||||
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
||||
|
||||
# Runtime data
|
||||
|
||||
pids
|
||||
_.pid
|
||||
_.seed
|
||||
\*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
|
||||
coverage
|
||||
\*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
|
||||
\*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
|
||||
\*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variable files
|
||||
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
|
||||
.cache/
|
||||
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
|
||||
.vuepress/dist
|
||||
|
||||
# vuepress v2.x temp and cache directory
|
||||
|
||||
.temp
|
||||
.cache
|
||||
|
||||
# Docusaurus cache and generated files
|
||||
|
||||
.docusaurus
|
||||
|
||||
# Serverless directories
|
||||
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.\*
|
||||
/target
|
||||
|
|
671
Cargo.lock
generated
Normal file
671
Cargo.lock
generated
Normal file
|
@ -0,0 +1,671 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.27.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e"
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.3.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"http",
|
||||
"indexmap",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
"itoa",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http-body"
|
||||
version = "1.0.0-rc.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "951dfc2e32ac02d67c90c0d65bd27009a635dc9b381a2cc7d284ab01e3a0150d"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"http",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http-body-util"
|
||||
version = "0.1.0-rc.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92445bc9cc14bfa0a3ce56817dc3b5bcc227a168781a356b702410789cec0d10"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http-body",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
|
||||
|
||||
[[package]]
|
||||
name = "httpdate"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "1.0.0-rc.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b75264b2003a3913f118d35c586e535293b3e22e41f074930762929d071e092"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http-body",
|
||||
"httparse",
|
||||
"httpdate",
|
||||
"itoa",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"want",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
|
||||
dependencies = [
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "minesweeper-nojs"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"tokio",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.31.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2efbeae7acf4eabd6bcdcbd11c92f45231ddda7539edc7806bd1a04a03b24616"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.29.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"backtrace",
|
||||
"bytes",
|
||||
"libc",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"parking_lot",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"pin-project-lite",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "try-lock"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "want"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
|
||||
dependencies = [
|
||||
"try-lock",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
|
38
Cargo.toml
Normal file
38
Cargo.toml
Normal file
|
@ -0,0 +1,38 @@
|
|||
[package]
|
||||
name = "minesweeper-nojs"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[profile.release]
|
||||
strip = "symbols"
|
||||
lto = "thin"
|
||||
opt-level = 3
|
||||
codegen-units = 1
|
||||
|
||||
[profile.dev.package."*"]
|
||||
opt-level = 3
|
||||
codegen-units = 1
|
||||
[profile.release.package."*"]
|
||||
opt-level = 3
|
||||
codegen-units = 1
|
||||
[profile.dev.build-override]
|
||||
opt-level = 3
|
||||
codegen-units = 1
|
||||
|
||||
[dependencies]
|
||||
url = "2.4.0"
|
||||
|
||||
[dependencies.hyper]
|
||||
version = "1.0.0-rc.3"
|
||||
features = ["full"]
|
||||
|
||||
[dependencies.tokio]
|
||||
version = "1"
|
||||
features = ["full"]
|
||||
|
||||
[dependencies.http-body-util]
|
||||
version = "0.1.0-rc.2"
|
||||
|
||||
[profile.release.build-override]
|
||||
opt-level = 3
|
||||
codegen-units = 1
|
1
build.sh
Executable file
1
build.sh
Executable file
|
@ -0,0 +1 @@
|
|||
RUSTFLAGS="-C target-cpu=native" cargo build --release
|
BIN
bun.lockb
BIN
bun.lockb
Binary file not shown.
16809
inputs.json
Normal file
16809
inputs.json
Normal file
File diff suppressed because it is too large
Load diff
14
justfile
14
justfile
|
@ -1,14 +0,0 @@
|
|||
#!/usr/bin/just --justfile
|
||||
|
||||
# Lists all recipes
|
||||
list:
|
||||
{{ just_executable() }} --list
|
||||
|
||||
# Run a dev server anad recompile on file change
|
||||
dev:
|
||||
bun --port=55782 --watch ./server.ts
|
||||
|
||||
# Run a production server
|
||||
run:
|
||||
NODE_ENV="production" bun run --port=55782 ./server.ts
|
||||
|
132
server.ts
132
server.ts
|
@ -1,132 +0,0 @@
|
|||
const PORT = 55782;
|
||||
const HEADERS_BOARD = {
|
||||
headers: {
|
||||
"Content-Type": "text/html",
|
||||
"Cache-Control": "no-store",
|
||||
},
|
||||
};
|
||||
const HEADERS_STYLESHEET = {
|
||||
headers: {
|
||||
"Content-Type": "text/css",
|
||||
},
|
||||
};
|
||||
const HEADERS_FAVICON = {
|
||||
headers: {
|
||||
"Content-Type": "image/x-icon",
|
||||
},
|
||||
};
|
||||
|
||||
async function htmlDoc(body: string, head: string): Promise<string> {
|
||||
return `<!DOCTYPE html><html><head><link rel=stylesheet href=style.css><link rel=icon type="image/x-icon" href=favicon.ico>${head}</head><body>${body}</body></html>`
|
||||
}
|
||||
|
||||
async function createBoard(width: number, height: number, mines: number): Promise<string> {
|
||||
console.debug("width", width, "height", height, "mines", mines);
|
||||
if (width <= 0 || height <= 0 || mines <= 0) {
|
||||
return await htmlDoc("NO 0 VALUES ALLOWED", "");
|
||||
}
|
||||
if (width > 50 || height > 50) {
|
||||
return await htmlDoc("NO FIELDS LARGER THAN 50 IN EITHER DIMENSION", "");
|
||||
}
|
||||
if (mines >= width * height) {
|
||||
return await htmlDoc("TOO MANY MINES", "");
|
||||
}
|
||||
|
||||
const board = new Array(width * height).fill(false);
|
||||
let safeIdx = board.map((_, idx) => idx);
|
||||
|
||||
for (let placedMines = 0; placedMines < mines; placedMines++) {
|
||||
const mineIdx = safeIdx.splice(Math.floor(Math.random() * safeIdx.length), 1)[0];
|
||||
|
||||
board[mineIdx] = true;
|
||||
}
|
||||
|
||||
function getNeighbors(idx: number): number {
|
||||
let count = 0;
|
||||
const leftEdge = (idx % width) === 0;
|
||||
const topEdge = idx < width;
|
||||
const bottomEdge = idx > (height * (width - 1));
|
||||
const rightEdge = (idx % width) === (width - 1);
|
||||
|
||||
if (!leftEdge && board[idx - 1]) {
|
||||
count++;
|
||||
}
|
||||
if (!leftEdge && !topEdge && board[idx - 1 - width]) {
|
||||
count++;
|
||||
}
|
||||
if (!leftEdge && !bottomEdge && board[idx - 1 + width]) {
|
||||
count++;
|
||||
}
|
||||
|
||||
if (!rightEdge && board[idx + 1]) {
|
||||
count++;
|
||||
}
|
||||
if (!rightEdge && !topEdge && board[idx + 1 - width]) {
|
||||
count++;
|
||||
}
|
||||
if (!rightEdge && !bottomEdge && board[idx + 1 + width]) {
|
||||
count++;
|
||||
}
|
||||
|
||||
if (!topEdge && board[idx - width]) {
|
||||
count++;
|
||||
}
|
||||
|
||||
if (!bottomEdge && board[idx + width]) {
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
let table = "<table><tbody><tr>";
|
||||
let inputs = "";
|
||||
let style = "<style>";
|
||||
for (const [idx, fieldIsMine] of board.entries()) {
|
||||
table += `<td><label for=input_${idx}></label></td>`;
|
||||
|
||||
if ((idx % width) === (width - 1)) {
|
||||
table += "</tr><tr>"
|
||||
}
|
||||
inputs += `<input id=input_${idx} type=checkbox ${fieldIsMine ? "data-mine" : "data-safe"}></input>`;
|
||||
style += `#input_${idx}:checked ~ main label[for="input_${idx}"]::before { content: "${fieldIsMine ? "X" : getNeighbors(idx)}"; }\n`
|
||||
+ `#input_${idx}:checked ~ main label[for="input_${idx}"] { pointer-events: none; }\n`;
|
||||
}
|
||||
table += "</tr></tbody></table>"
|
||||
style += "</style>"
|
||||
|
||||
return await htmlDoc(`${inputs}<main>${table}</main><footer><span id=lost>HAHA you lost >:)</span><span id=won>YAY, you WON!!!</span></footer>`, style)
|
||||
}
|
||||
|
||||
Bun.serve({
|
||||
PORT,
|
||||
async fetch(request) {
|
||||
const url = new URL(request.url);
|
||||
|
||||
if (url.pathname === "/favicon.ico") {
|
||||
return new Response(await Bun.file("favicon.ico").arrayBuffer(), FAVICON_STYLESHEET);
|
||||
}
|
||||
|
||||
if (url.pathname === "/style.css") {
|
||||
return new Response(await Bun.file("style.css").text(), HEADERS_STYLESHEET);
|
||||
}
|
||||
|
||||
if (url.pathname !== "/") {
|
||||
return new Response("Not found", { status: 404, statusText: "Not found" });
|
||||
}
|
||||
|
||||
let height = Number.parseInt(url.searchParams.get("height") ?? "NaN");
|
||||
if (Number.isNaN(height)) {
|
||||
height = 10;
|
||||
}
|
||||
let width = Number.parseInt(url.searchParams.get("width") ?? "NaN");
|
||||
if (Number.isNaN(width)) {
|
||||
width = 10;
|
||||
}
|
||||
let mines = Number.parseInt(url.searchParams.get("mines") ?? "NaN");
|
||||
if (Number.isNaN(mines)) {
|
||||
mines = 10;
|
||||
}
|
||||
|
||||
return new Response(await createBoard(width, height, mines), HEADERS_BOARD);
|
||||
}
|
||||
})
|
12033
src/html_prealloc_sizes.rs
Normal file
12033
src/html_prealloc_sizes.rs
Normal file
File diff suppressed because it is too large
Load diff
253
src/main.rs
Normal file
253
src/main.rs
Normal file
|
@ -0,0 +1,253 @@
|
|||
mod html_prealloc_sizes;
|
||||
|
||||
const MAX_SIZE: usize = 50;
|
||||
const PORT: u16 = 55782;
|
||||
const STYLESHEET: &[u8; 776] = include_bytes!("../style.css");
|
||||
const FAVICON: &[u8; 111468] = include_bytes!("../favicon.ico");
|
||||
|
||||
use http_body_util::Full;
|
||||
use hyper::{
|
||||
body::{Bytes, Incoming},
|
||||
server::conn::http1,
|
||||
service::service_fn,
|
||||
Method, Request, Response, StatusCode,
|
||||
};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
convert::Infallible,
|
||||
net::SocketAddr,
|
||||
time::{Duration, SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
// Pseudorandom number generator from the "Xorshift RNGs" paper by George Marsaglia.
|
||||
//
|
||||
// https://github.com/rust-lang/rust/blob/1.55.0/library/core/src/slice/sort.rs#L559-L573
|
||||
pub fn random_numbers() -> impl Iterator<Item = usize> {
|
||||
let mut random = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap_or(Duration::new(0, 0))
|
||||
.as_nanos() as usize;
|
||||
std::iter::repeat_with(move || {
|
||||
random ^= random << 13;
|
||||
random ^= random >> 17;
|
||||
random ^= random << 5;
|
||||
random
|
||||
})
|
||||
}
|
||||
fn not_found() -> Response<Full<Bytes>> {
|
||||
Response::builder()
|
||||
.status(StatusCode::NOT_FOUND)
|
||||
.body(Full::new(Bytes::from_static(b"Not found")))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn invalid_method() -> Response<Full<Bytes>> {
|
||||
Response::builder()
|
||||
.status(StatusCode::METHOD_NOT_ALLOWED)
|
||||
.body(Full::new(Bytes::from_static(b"Method not allowed")))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn stylesheet() -> Response<Full<Bytes>> {
|
||||
Response::builder()
|
||||
.status(StatusCode::OK)
|
||||
.header("Content-Type", "text/css")
|
||||
.body(Full::new(Bytes::from_static(STYLESHEET)))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn favicon() -> Response<Full<Bytes>> {
|
||||
Response::builder()
|
||||
.status(StatusCode::OK)
|
||||
.header("Content-Type", "image/x-icon")
|
||||
.body(Full::new(Bytes::from_static(FAVICON)))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn create_board(width: usize, height: usize, mines: usize) -> Response<Full<Bytes>> {
|
||||
if width == 0 || height == 0 || mines == 0 {
|
||||
Response::builder()
|
||||
.status(StatusCode::RANGE_NOT_SATISFIABLE)
|
||||
.header("Cache-Control", "no-store")
|
||||
.body(Full::new(Bytes::from_static(b"NO 0 VALUES ALLOWED")))
|
||||
.unwrap()
|
||||
} else if width > MAX_SIZE || height > MAX_SIZE {
|
||||
Response::builder()
|
||||
.status(StatusCode::RANGE_NOT_SATISFIABLE)
|
||||
.header("Cache-Control", "no-store")
|
||||
.body(Full::new(Bytes::from_static(b"FIELD TOO BIG")))
|
||||
.unwrap()
|
||||
} else if mines >= width * height {
|
||||
Response::builder()
|
||||
.status(StatusCode::RANGE_NOT_SATISFIABLE)
|
||||
.header("Cache-Control", "no-store")
|
||||
.body(Full::new(Bytes::from_static(
|
||||
b"MUST BE LESS MINES THAN FIELDS",
|
||||
)))
|
||||
.unwrap()
|
||||
} else {
|
||||
let mut fields = vec![false; width * height];
|
||||
let mut safe_indices = (0..width * height).collect::<Vec<_>>();
|
||||
|
||||
for (placed_mines, random) in (0..mines).zip(random_numbers()) {
|
||||
let mine_index = safe_indices.swap_remove(random % ((width * height) - placed_mines));
|
||||
|
||||
fields[mine_index] = true;
|
||||
}
|
||||
|
||||
let get_neighbors = |idx: usize| -> u8 {
|
||||
let mut neighbor_count = 0;
|
||||
let left_edge = (idx % width) == 0;
|
||||
let top_edge = idx < width;
|
||||
let bottom_edge = idx >= ((height - 1) * width);
|
||||
let right_edge = (idx % width) == (width - 1);
|
||||
|
||||
if !left_edge && fields[idx - 1] {
|
||||
neighbor_count += 1;
|
||||
}
|
||||
if !left_edge && !top_edge && fields[idx - 1 - width] {
|
||||
neighbor_count += 1;
|
||||
}
|
||||
if !left_edge && !bottom_edge && fields[idx - 1 + width] {
|
||||
neighbor_count += 1;
|
||||
}
|
||||
|
||||
if !right_edge && fields[idx + 1] {
|
||||
neighbor_count += 1;
|
||||
}
|
||||
if !right_edge && !top_edge && fields[idx + 1 - width] {
|
||||
neighbor_count += 1;
|
||||
}
|
||||
if !right_edge && !bottom_edge && fields[idx + 1 + width] {
|
||||
neighbor_count += 1;
|
||||
}
|
||||
|
||||
if !top_edge && fields[idx - width] {
|
||||
neighbor_count += 1;
|
||||
}
|
||||
|
||||
if !bottom_edge && fields[idx + width] {
|
||||
neighbor_count += 1;
|
||||
}
|
||||
neighbor_count
|
||||
};
|
||||
|
||||
// Can't figure out how to do regression, otherwise I'd make these into functions to calculate the
|
||||
// allocated size based on width and height
|
||||
let sizes = html_prealloc_sizes::get_sizes(width, height);
|
||||
|
||||
let mut style_string = String::with_capacity(sizes.style);
|
||||
let mut inputs_string = String::with_capacity(sizes.inputs);
|
||||
let mut table_string = String::with_capacity(sizes.table);
|
||||
|
||||
for (field_index, &field_is_mine) in fields.iter().enumerate() {
|
||||
table_string += format!("<td><label for=input_{field_index}></label></td>").as_str();
|
||||
if (field_index % width) == (width - 1) && field_index != width * height - 1 {
|
||||
table_string += "</tr><tr>";
|
||||
}
|
||||
|
||||
inputs_string += format!(
|
||||
"<input id=input_{field_index} type=checkbox data-{}></input>",
|
||||
if field_is_mine { "mine" } else { "safe" }
|
||||
)
|
||||
.as_str();
|
||||
|
||||
style_string += format!(
|
||||
"#input_{field_index}:checked ~ main label[for=\"input_{field_index}\"]::before {{ content: \"{}\"; }}\n#input_{field_index}:checked ~ main label[for=\"input_{field_index}\"] {{ pointer-events: none; }}",
|
||||
if field_is_mine { "X".into() } else { get_neighbors(field_index).to_string() })
|
||||
.as_str();
|
||||
}
|
||||
|
||||
if style_string.capacity() > sizes.style {
|
||||
dbg!(style_string.capacity(), style_string.len(), sizes.style);
|
||||
}
|
||||
if inputs_string.capacity() > sizes.inputs {
|
||||
dbg!(inputs_string.capacity(), inputs_string.len(), sizes.inputs);
|
||||
}
|
||||
if table_string.capacity() > sizes.table {
|
||||
dbg!(table_string.capacity(), table_string.len(), sizes.table);
|
||||
}
|
||||
|
||||
let response_string = format!(
|
||||
"<!DOCTYPE html><html><head><link rel=stylesheet href=style.css><link rel=icon type=\"image/x-icon\" href=favicon.ico><style>{}</style></head><body>{}<main><table><tbody><tr>{}</tr></tbody></table></main><footer><span id=lost>HAHA you lost >:)</span><span id=won>YAY, you WON!!!</span></footer></body></html>",
|
||||
style_string,
|
||||
inputs_string,
|
||||
table_string
|
||||
);
|
||||
|
||||
// To debug sizes for allocation
|
||||
// let response_string = format!(
|
||||
// "{{\"style\":{},\"inputs\":{},\"table\":{}}}",
|
||||
// style_string.len(),
|
||||
// inputs_string.len(),
|
||||
// table_string.len()
|
||||
// );
|
||||
|
||||
Response::builder()
|
||||
.status(StatusCode::OK)
|
||||
.header("Cache-Control", "no-store")
|
||||
.body(Full::from(response_string))
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
async fn respond(req: Request<Incoming>) -> Result<Response<Full<Bytes>>, Infallible> {
|
||||
if !matches!(req.method(), &Method::GET) {
|
||||
Ok(invalid_method())
|
||||
} else {
|
||||
let (width, height, mines) = match req.uri().query() {
|
||||
Some(query) => {
|
||||
let options_map = url::form_urlencoded::parse(query.as_bytes())
|
||||
.into_owned()
|
||||
.collect::<HashMap<String, String>>();
|
||||
let height = options_map
|
||||
.get("height")
|
||||
.unwrap_or(&"NaN".to_string())
|
||||
.parse()
|
||||
.unwrap_or(10);
|
||||
let width = options_map
|
||||
.get("width")
|
||||
.unwrap_or(&"NaN".to_string())
|
||||
.parse()
|
||||
.unwrap_or(10);
|
||||
let mines = options_map
|
||||
.get("mines")
|
||||
.unwrap_or(&"NaN".to_string())
|
||||
.parse()
|
||||
.unwrap_or(10);
|
||||
|
||||
(width, height, mines)
|
||||
}
|
||||
None => (10, 10, 10),
|
||||
};
|
||||
|
||||
Ok(match req.uri().path() {
|
||||
"/style.css" => stylesheet().await,
|
||||
"/favicon.ico" => favicon().await,
|
||||
"/" => create_board(width, height, mines).await,
|
||||
_ => not_found(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
let addr = SocketAddr::from(([0, 0, 0, 0], PORT));
|
||||
let listener = TcpListener::bind(addr).await?;
|
||||
loop {
|
||||
let (stream, _) = listener.accept().await?;
|
||||
|
||||
// Spawn a tokio task to serve multiple connections concurrently
|
||||
tokio::task::spawn(async move {
|
||||
// Finally, we bind the incoming connection to our `hello` service
|
||||
if let Err(err) = http1::Builder::new()
|
||||
// `service_fn` converts our function in a `Service`
|
||||
.serve_connection(stream, service_fn(respond))
|
||||
.await
|
||||
{
|
||||
println!("Error serving connection: {err:?}");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
54
style.css
54
style.css
|
@ -1,53 +1 @@
|
|||
html {
|
||||
height: 100%;
|
||||
background: black;
|
||||
color: white;
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
label, label::before {
|
||||
display: block;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
label::before {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
body {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
main {
|
||||
margin: auto;
|
||||
color: white;
|
||||
}
|
||||
|
||||
input { display:none; label: pointer-events: none; }
|
||||
|
||||
label { pointer-events: none; }
|
||||
|
||||
input ~ main label::before { content: "O"; }
|
||||
#won { display: initial; user-select: none; }
|
||||
input[data-safe]:not(:checked) ~ footer #won { display: none; }
|
||||
input[data-safe]:not(:checked) ~ main label { pointer-events: initial; }
|
||||
|
||||
#lost { display: none; user-select: none ; }
|
||||
input[data-mine]:checked ~ footer #lost { display: initial; }
|
||||
input[data-mine]:checked ~ main label { pointer-events: none; }
|
||||
|
||||
footer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#lost, #won {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
}
|
||||
html{height:100%;background:black;color:white;font-size:40px}label,label::before{display:block;width:50px;height:50px;cursor:pointer}label::before{text-align:center}body{height:100%;display:flex;justify-content:center;align-items:center;flex-direction:column}main{margin:auto;color:white}input{display:none;pointer-events:none}label{pointer-events:none}input~main label::before{content:"?"}#won{display:initial;user-select:none}input[data-safe]:not(:checked)~footer #won{display:none}input[data-safe]:not(:checked)~main label{pointer-events:initial}#lost{display:none;user-select:none}input[data-mine]:checked~footer #lost{display:initial}input[data-mine]:checked~main label{pointer-events:none}footer{display:flex;justify-content:center}#lost,#won{position:absolute;top:10px}
|
16816
style.json
Normal file
16816
style.json
Normal file
File diff suppressed because it is too large
Load diff
16809
table.json
Normal file
16809
table.json
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue