~ntietz/isabella-db

4fe042d06530af01956bca4f04e4432821caadd1 — Nicholas Tietz-Sokolsky 24 days ago 88f38f8
Create very basic opening tree web service.

This adds in a new bin target (`web`) and serves a few routes for that
service. Basically, it lets you see a board position and the legal moves
from there, then click through to the legal moves and see it evolve.

This doesn't do anything particularly useful yet, but is the foundation
that displaying win/loss/draw percents for openings will be based on.
M Cargo.lock => Cargo.lock +1018 -0
@@ 3,12 3,303 @@
version = 3

[[package]]
name = "actix-codec"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57a7559404a7f3573127aab53c08ce37a6c6a315c374a31070f3c91cd1b4a7fe"
dependencies = [
 "bitflags",
 "bytes",
 "futures-core",
 "futures-sink",
 "log",
 "memchr",
 "pin-project-lite",
 "tokio",
 "tokio-util",
]

[[package]]
name = "actix-files"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d832782fac6ca7369a70c9ee9a20554623c5e51c76e190ad151780ebea1cf689"
dependencies = [
 "actix-http",
 "actix-service",
 "actix-utils",
 "actix-web",
 "askama_escape",
 "bitflags",
 "bytes",
 "derive_more",
 "futures-core",
 "http-range",
 "log",
 "mime",
 "mime_guess",
 "percent-encoding",
 "pin-project-lite",
]

[[package]]
name = "actix-http"
version = "3.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c83abf9903e1f0ad9973cc4f7b9767fd5a03a583f51a5b7a339e07987cd2724"
dependencies = [
 "actix-codec",
 "actix-rt",
 "actix-service",
 "actix-utils",
 "ahash",
 "base64",
 "bitflags",
 "brotli",
 "bytes",
 "bytestring",
 "derive_more",
 "encoding_rs",
 "flate2",
 "futures-core",
 "h2",
 "http",
 "httparse",
 "httpdate",
 "itoa",
 "language-tags",
 "local-channel",
 "mime",
 "percent-encoding",
 "pin-project-lite",
 "rand",
 "sha1",
 "smallvec",
 "tracing",
 "zstd",
]

[[package]]
name = "actix-macros"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "465a6172cf69b960917811022d8f29bc0b7fa1398bc4f78b3c466673db1213b6"
dependencies = [
 "quote",
 "syn",
]

[[package]]
name = "actix-router"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d66ff4d247d2b160861fa2866457e85706833527840e4133f8f49aa423a38799"
dependencies = [
 "bytestring",
 "http",
 "regex",
 "serde",
 "tracing",
]

[[package]]
name = "actix-rt"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ea16c295198e958ef31930a6ef37d0fb64e9ca3b6116e6b93a8bdae96ee1000"
dependencies = [
 "futures-core",
 "tokio",
]

[[package]]
name = "actix-server"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0da34f8e659ea1b077bb4637948b815cd3768ad5a188fdcd74ff4d84240cd824"
dependencies = [
 "actix-rt",
 "actix-service",
 "actix-utils",
 "futures-core",
 "futures-util",
 "mio",
 "num_cpus",
 "socket2",
 "tokio",
 "tracing",
]

[[package]]
name = "actix-service"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a"
dependencies = [
 "futures-core",
 "paste",
 "pin-project-lite",
]

[[package]]
name = "actix-utils"
version = "3.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8"
dependencies = [
 "local-waker",
 "pin-project-lite",
]

[[package]]
name = "actix-web"
version = "4.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d48f7b6534e06c7bfc72ee91db7917d4af6afe23e7d223b51e68fffbb21e96b9"
dependencies = [
 "actix-codec",
 "actix-http",
 "actix-macros",
 "actix-router",
 "actix-rt",
 "actix-server",
 "actix-service",
 "actix-utils",
 "actix-web-codegen",
 "ahash",
 "bytes",
 "bytestring",
 "cfg-if",
 "cookie",
 "derive_more",
 "encoding_rs",
 "futures-core",
 "futures-util",
 "http",
 "itoa",
 "language-tags",
 "log",
 "mime",
 "once_cell",
 "pin-project-lite",
 "regex",
 "serde",
 "serde_json",
 "serde_urlencoded",
 "smallvec",
 "socket2",
 "time",
 "url",
]

[[package]]
name = "actix-web-codegen"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fa9362663c8643d67b2d5eafba49e4cb2c8a053a29ed00a0bea121f17c76b13"
dependencies = [
 "actix-router",
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"

[[package]]
name = "ahash"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
dependencies = [
 "getrandom",
 "once_cell",
 "version_check",
]

[[package]]
name = "aho-corasick"
version = "0.7.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
dependencies = [
 "memchr",
]

[[package]]
name = "alloc-no-stdlib"
version = "2.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3"

[[package]]
name = "alloc-stdlib"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece"
dependencies = [
 "alloc-no-stdlib",
]

[[package]]
name = "arrayvec"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"

[[package]]
name = "askama"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb98f10f371286b177db5eeb9a6e5396609555686a35e1d4f7b9a9c6d8af0139"
dependencies = [
 "askama_derive",
 "askama_escape",
 "askama_shared",
]

[[package]]
name = "askama_derive"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87bf87e6e8b47264efa9bde63d6225c6276a52e05e91bf37eaa8afd0032d6b71"
dependencies = [
 "askama_shared",
 "proc-macro2",
 "syn",
]

[[package]]
name = "askama_escape"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341"

[[package]]
name = "askama_shared"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf722b94118a07fcbc6640190f247334027685d4e218b794dbfe17c32bf38ed0"
dependencies = [
 "askama_escape",
 "humansize",
 "mime",
 "mime_guess",
 "nom",
 "num-traits",
 "percent-encoding",
 "proc-macro2",
 "quote",
 "serde",
 "syn",
 "toml",
]

[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 26,6 317,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"

[[package]]
name = "base64"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"

[[package]]
name = "bincode"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 49,6 346,36 @@ dependencies = [
]

[[package]]
name = "block-buffer"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e"
dependencies = [
 "generic-array",
]

[[package]]
name = "brotli"
version = "3.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68"
dependencies = [
 "alloc-no-stdlib",
 "alloc-stdlib",
 "brotli-decompressor",
]

[[package]]
name = "brotli-decompressor"
version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ad2d4653bf5ca36ae797b1f4bb4dbddb60ce49ca4aed8a2ce4829f60425b80"
dependencies = [
 "alloc-no-stdlib",
 "alloc-stdlib",
]

[[package]]
name = "btoi"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 64,6 391,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"

[[package]]
name = "bytes"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db"

[[package]]
name = "bytestring"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7f83e57d9154148e355404702e2694463241880b939570d7c97c014da7a69a1"
dependencies = [
 "bytes",
]

[[package]]
name = "cc"
version = "1.0.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76a284da2e6fe2092f2353e51713435363112dfd60030e22add80be333fb928f"
dependencies = [
 "jobserver",
]

[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 107,6 458,148 @@ dependencies = [
]

[[package]]
name = "convert_case"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"

[[package]]
name = "cookie"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "344adc371239ef32293cb1c4fe519592fcf21206c79c02854320afcdf3ab4917"
dependencies = [
 "percent-encoding",
 "time",
 "version_check",
]

[[package]]
name = "cpufeatures"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
dependencies = [
 "libc",
]

[[package]]
name = "crc32fast"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
dependencies = [
 "cfg-if",
]

[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
 "generic-array",
 "typenum",
]

[[package]]
name = "derive_more"
version = "0.99.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
dependencies = [
 "convert_case",
 "proc-macro2",
 "quote",
 "rustc_version",
 "syn",
]

[[package]]
name = "digest"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c"
dependencies = [
 "block-buffer",
 "crypto-common",
]

[[package]]
name = "encoding_rs"
version = "0.8.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b"
dependencies = [
 "cfg-if",
]

[[package]]
name = "flate2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6"
dependencies = [
 "crc32fast",
 "miniz_oxide",
]

[[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.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
dependencies = [
 "percent-encoding",
]

[[package]]
name = "futures-core"
version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"

[[package]]
name = "futures-sink"
version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"

[[package]]
name = "futures-task"
version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea"

[[package]]
name = "futures-util"
version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6"
dependencies = [
 "futures-core",
 "futures-task",
 "pin-project-lite",
 "pin-utils",
]

[[package]]
name = "generic-array"
version = "0.14.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
dependencies = [
 "typenum",
 "version_check",
]

[[package]]
name = "getrandom"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 118,6 611,31 @@ dependencies = [
]

[[package]]
name = "h2"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4"
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 = "heck"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 133,9 651,67 @@ dependencies = [
]

[[package]]
name = "http"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
dependencies = [
 "bytes",
 "fnv",
 "itoa",
]

[[package]]
name = "http-range"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573"

[[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 = "humansize"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02296996cb8796d7c6e3bc2d9211b7802812d36999a51bb754123ead7d37d026"

[[package]]
name = "idna"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
dependencies = [
 "unicode-bidi",
 "unicode-normalization",
]

[[package]]
name = "indexmap"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
dependencies = [
 "autocfg",
 "hashbrown",
]

[[package]]
name = "isabella-db"
version = "0.1.0"
dependencies = [
 "actix-files",
 "actix-web",
 "askama",
 "bincode",
 "bitmap",
 "clap",


@@ 150,6 726,27 @@ dependencies = [
]

[[package]]
name = "itoa"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"

[[package]]
name = "jobserver"
version = "0.1.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b"
dependencies = [
 "libc",
]

[[package]]
name = "language-tags"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388"

[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 162,6 759,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"

[[package]]
name = "local-channel"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f303ec0e94c6c54447f84f3b0ef7af769858a9c4ef56ef2a986d3dcd4c3fc9c"
dependencies = [
 "futures-core",
 "futures-sink",
 "futures-util",
 "local-waker",
]

[[package]]
name = "local-waker"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1"

[[package]]
name = "lock_api"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
dependencies = [
 "autocfg",
 "scopeguard",
]

[[package]]
name = "log"
version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 195,12 820,49 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"

[[package]]
name = "mime"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"

[[package]]
name = "mime_guess"
version = "2.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
dependencies = [
 "mime",
 "unicase",
]

[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"

[[package]]
name = "miniz_oxide"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34"
dependencies = [
 "adler",
]

[[package]]
name = "mio"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de"
dependencies = [
 "libc",
 "log",
 "wasi",
 "windows-sys",
]

[[package]]
name = "nom"
version = "7.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 230,6 892,16 @@ dependencies = [
]

[[package]]
name = "num_cpus"
version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5"
dependencies = [
 "hermit-abi",
 "libc",
]

[[package]]
name = "once_cell"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 248,12 920,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"

[[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.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0"
dependencies = [
 "cfg-if",
 "libc",
 "redox_syscall",
 "smallvec",
 "windows-sys",
]

[[package]]
name = "paste"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1"

[[package]]
name = "percent-encoding"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"

[[package]]
name = "pgn"
version = "0.1.0"
dependencies = [


@@ 285,6 986,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"

[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"

[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 363,11 1070,22 @@ dependencies = [
]

[[package]]
name = "redox_syscall"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
dependencies = [
 "bitflags",
]

[[package]]
name = "regex"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
dependencies = [
 "aho-corasick",
 "memchr",
 "regex-syntax",
]



@@ 409,6 1127,33 @@ dependencies = [
]

[[package]]
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
 "semver",
]

[[package]]
name = "ryu"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"

[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"

[[package]]
name = "semver"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4"

[[package]]
name = "serde"
version = "1.0.147"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 429,6 1174,40 @@ dependencies = [
]

[[package]]
name = "serde_json"
version = "1.0.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45"
dependencies = [
 "itoa",
 "ryu",
 "serde",
]

[[package]]
name = "serde_urlencoded"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
dependencies = [
 "form_urlencoded",
 "itoa",
 "ryu",
 "serde",
]

[[package]]
name = "sha1"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
dependencies = [
 "cfg-if",
 "cpufeatures",
 "digest",
]

[[package]]
name = "shakmaty"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 449,6 1228,24 @@ dependencies = [
]

[[package]]
name = "signal-hook-registry"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
dependencies = [
 "libc",
]

[[package]]
name = "slab"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
dependencies = [
 "autocfg",
]

[[package]]
name = "slice-deque"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 477,6 1274,16 @@ dependencies = [
]

[[package]]
name = "socket2"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd"
dependencies = [
 "libc",
 "winapi",
]

[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 538,12 1345,96 @@ dependencies = [
]

[[package]]
name = "time"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376"
dependencies = [
 "itoa",
 "serde",
 "time-core",
 "time-macros",
]

[[package]]
name = "time-core"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"

[[package]]
name = "time-macros"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2"
dependencies = [
 "time-core",
]

[[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.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"

[[package]]
name = "tokio"
version = "1.21.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099"
dependencies = [
 "autocfg",
 "bytes",
 "libc",
 "memchr",
 "mio",
 "parking_lot",
 "pin-project-lite",
 "signal-hook-registry",
 "socket2",
 "winapi",
]

[[package]]
name = "tokio-util"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740"
dependencies = [
 "bytes",
 "futures-core",
 "futures-sink",
 "pin-project-lite",
 "tokio",
 "tracing",
]

[[package]]
name = "toml"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
dependencies = [
 "serde",
]

[[package]]
name = "tracing"
version = "0.1.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
dependencies = [
 "cfg-if",
 "log",
 "pin-project-lite",
 "tracing-attributes",
 "tracing-core",


@@ 600,12 1491,53 @@ dependencies = [
]

[[package]]
name = "typenum"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"

[[package]]
name = "unicase"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
dependencies = [
 "version_check",
]

[[package]]
name = "unicode-bidi"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"

[[package]]
name = "unicode-ident"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"

[[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.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
dependencies = [
 "form_urlencoded",
 "idna",
 "percent-encoding",
]

[[package]]
name = "valuable"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 653,3 1585,89 @@ 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.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
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.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"

[[package]]
name = "windows_aarch64_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"

[[package]]
name = "windows_i686_gnu"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"

[[package]]
name = "windows_i686_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"

[[package]]
name = "windows_x86_64_gnu"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"

[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"

[[package]]
name = "windows_x86_64_msvc"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"

[[package]]
name = "zstd"
version = "0.11.2+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4"
dependencies = [
 "zstd-safe",
]

[[package]]
name = "zstd-safe"
version = "5.0.2+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db"
dependencies = [
 "libc",
 "zstd-sys",
]

[[package]]
name = "zstd-sys"
version = "2.0.1+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fd07cbbc53846d9145dbffdf6dd09a7a0aa52be46741825f5c97bdd4f73f12b"
dependencies = [
 "cc",
 "libc",
]

M isabella/Cargo.toml => isabella/Cargo.toml +4 -0
@@ 22,3 22,7 @@ serde = { workspace = true }
shakmaty = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }

actix-web = "4.2.1"
actix-files = "0.6.2"
askama = "0.11.1"

A isabella/src/bin/web.rs => isabella/src/bin/web.rs +22 -0
@@ 0,0 1,22 @@
use actix_web::{middleware::Logger, App, HttpServer};
use isabella_db::web::routes::add_routes;
use tracing_subscriber::{fmt::format::FmtSpan, EnvFilter};

#[actix_web::main]
pub async fn main() -> std::io::Result<()> {
    tracing_subscriber::fmt()
        .with_env_filter(EnvFilter::from_default_env())
        .with_span_events(FmtSpan::ACTIVE)
        .init();

    tracing::info!("Starting server");

    // TODO: request logging
    //
    HttpServer::new(|| App::new().configure(add_routes).wrap(Logger::default()))
        .bind(("0.0.0.0", 11311))?
        .run()
        .await?;

    Ok(())
}

M isabella/src/lib.rs => isabella/src/lib.rs +1 -0
@@ 2,3 2,4 @@ pub mod db;
pub mod game;
pub mod index;
pub mod strings;
pub mod web;

A isabella/src/web/mod.rs => isabella/src/web/mod.rs +3 -0
@@ 0,0 1,3 @@
pub mod routes;
pub mod templates;
pub mod views;

A isabella/src/web/routes.rs => isabella/src/web/routes.rs +10 -0
@@ 0,0 1,10 @@
use actix_files::Files;
use actix_web::web;

use super::views;

pub fn add_routes(cfg: &mut web::ServiceConfig) {
    cfg.service(Files::new("/static", "./static"))
        .service(views::home)
        .service(views::position);
}

A isabella/src/web/templates.rs => isabella/src/web/templates.rs +121 -0
@@ 0,0 1,121 @@
use askama::Template;
use shakmaty::fen::Fen;
use shakmaty::san::SanPlus;
use shakmaty::{Chess, Color, Piece, Position, Role, Square};

#[derive(Template)]
#[template(path = "home.html")]
pub struct HomeTemplate;

#[derive(Default, Template)]
#[template(path = "board.html")]
pub struct BoardTemplate {
    pub board: Option<Chess>,
    pub error: Option<&'static str>,
    pub to_move: String,
}

#[derive(Debug)]
pub struct AvailableMove {
    pub san: String,

    /// the url for the following board position
    pub url: String,
}

const INVALID_FEN: &str = "Invalid FEN string";

impl BoardTemplate {
    pub fn new() -> BoardTemplate {
        let default_board = Chess::new();
        let to_move = default_board.turn().to_string();
        let board = Some(default_board);
        let error = None;
        BoardTemplate {
            board,
            error,
            to_move,
        }
    }

    pub fn from_fen(fen: &[u8]) -> BoardTemplate {
        let mut error = None;
        let mut board = None;
        let mut to_move: String = "".into();

        let fen_setup = Fen::from_ascii(fen);
        if let Ok(fen_setup) = fen_setup {
            let fen_setup: Result<Chess, _> =
                fen_setup.into_position(shakmaty::CastlingMode::Standard);
            if let Ok(board_from_fen) = fen_setup {
                to_move = board_from_fen.turn().to_string();
                board = Some(board_from_fen);
            } else {
                error = Some(INVALID_FEN);
            }
        } else {
            error = Some(INVALID_FEN);
        }

        BoardTemplate {
            board,
            error,
            to_move,
        }
    }

    pub fn available_moves(&self) -> Vec<AvailableMove> {
        let mut available_moves: Vec<AvailableMove> = vec![];

        if let Some(board) = &self.board {
            for m in board.legal_moves() {
                let mut next_board = board.clone();

                let san = SanPlus::from_move_and_play_unchecked(&mut next_board, &m);
                let fen =
                    Fen::from_position(next_board, shakmaty::EnPassantMode::Legal).to_string();

                available_moves.push(AvailableMove {
                    san: san.to_string(),
                    url: format!("/position/?fen={fen}"),
                })
            }
        }

        available_moves
    }

    pub fn render_piece_on(&self, rank: &u8, file: &u8) -> String {
        let square_idx = (file + rank * 8) as u32;

        if let Some(board) = &self.board {
            let piece = board.board().piece_at(Square::new(square_idx));
            html_display_piece(piece)
        } else {
            html_display_piece(None)
        }
    }
}

pub fn html_display_piece(piece: Option<Piece>) -> String {
    if let Some(piece) = piece {
        let s = match (piece.color, piece.role) {
            (Color::White, Role::Pawn) => "wP",
            (Color::White, Role::Knight) => "wN",
            (Color::White, Role::Bishop) => "wB",
            (Color::White, Role::Rook) => "wR",
            (Color::White, Role::Queen) => "wQ",
            (Color::White, Role::King) => "wK",
            (Color::Black, Role::Pawn) => "bP",
            (Color::Black, Role::Knight) => "bN",
            (Color::Black, Role::Bishop) => "bB",
            (Color::Black, Role::Rook) => "bR",
            (Color::Black, Role::Queen) => "bQ",
            (Color::Black, Role::King) => "bK",
        };

        format!("<img src=\"/static/images/chess/wikipedia/{}.png\" />", s)
    } else {
        "&nbsp;".into()
    }
}

A isabella/src/web/views.rs => isabella/src/web/views.rs +29 -0
@@ 0,0 1,29 @@
use actix_web::{route, web, HttpResponse, Responder};
use askama::Template;
use serde::Deserialize;

use super::templates::{BoardTemplate, HomeTemplate};

#[route("/", method = "GET")]
pub async fn home() -> impl Responder {
    let s = HomeTemplate.render().expect("HomeTemplate should render");
    HttpResponse::Ok().content_type("text/html").body(s)
}

#[derive(Deserialize, Debug)]
pub struct FenQuery {
    fen: String,
}

#[route("/position/", method = "GET")]
pub async fn position(fen: Option<web::Query<FenQuery>>) -> impl Responder {
    tracing::info!(fen=?fen, "position query-string");

    let template = match fen {
        Some(fen) => BoardTemplate::from_fen(fen.0.fen.as_bytes()),
        None => BoardTemplate::new(),
    };

    let s = template.render().expect("BoardTemplate should render");
    HttpResponse::Ok().content_type("text/html").body(s)
}

A isabella/templates/board.html => isabella/templates/board.html +41 -0
@@ 0,0 1,41 @@
<html>
    <head>
        <link rel="stylesheet" href="/static/style.css" />
    </head>

    <body>
        <h1>Position</h1>
        {% match error %}
            {% when Some with (error_msg) %}
                <p class="error">
                {{ error_msg }}
                </p>
            {% when None %}
        {% endmatch %}

        <div class="opening-tree-layout">
            <div class="chess-board-container">
                <div class="chess-board">
                    {% for rank in (0..8).rev() %}
                    <div class="row">
                        {% for file in 0..8 %}
                        <div class="cell">
                                {{ Self::render_piece_on(self, rank, file)|safe }}
                        </div>
                        {% endfor %}
                    </div>
                    {% endfor %}
                </div>
            </div>
            <div class="move-list">
                <h3>Moves ({{ to_move }})</h3>
                {% for m in Self::available_moves(self) %}
                <p>
                    <a href="{{ m.url }}">{{ m.san }}</a>
                </p>
                {% endfor %}
            </div>
        </div>

    </body>
</html>

A isabella/templates/home.html => isabella/templates/home.html +8 -0
@@ 0,0 1,8 @@
<html>
    <head>
    </head>
    <body>
        <h1>Hello, world.</h1>
        <p>This is the template.</p>
    </body>
</html>

A static/images/chess/wikipedia/bB.png => static/images/chess/wikipedia/bB.png +0 -0
A static/images/chess/wikipedia/bK.png => static/images/chess/wikipedia/bK.png +0 -0
A static/images/chess/wikipedia/bN.png => static/images/chess/wikipedia/bN.png +0 -0
A static/images/chess/wikipedia/bP.png => static/images/chess/wikipedia/bP.png +0 -0
A static/images/chess/wikipedia/bQ.png => static/images/chess/wikipedia/bQ.png +0 -0
A static/images/chess/wikipedia/bR.png => static/images/chess/wikipedia/bR.png +0 -0
A static/images/chess/wikipedia/wB.png => static/images/chess/wikipedia/wB.png +0 -0
A static/images/chess/wikipedia/wK.png => static/images/chess/wikipedia/wK.png +0 -0
A static/images/chess/wikipedia/wN.png => static/images/chess/wikipedia/wN.png +0 -0
A static/images/chess/wikipedia/wP.png => static/images/chess/wikipedia/wP.png +0 -0
A static/images/chess/wikipedia/wQ.png => static/images/chess/wikipedia/wQ.png +0 -0
A static/images/chess/wikipedia/wR.png => static/images/chess/wikipedia/wR.png +0 -0
A static/style.css => static/style.css +60 -0
@@ 0,0 1,60 @@

.opening-tree-layout {
    display: flex;
    flex-direction: row;
}

.chess-board-container {
    padding: 2em;
}

.chess-board {
    aspect-ratio: 1 / 1;
    min-width: 240px;
    max-width: 800px;
    width: 100%;

    border: 1px solid;

    display: grid;
    grid-template-rows: repeat(8, minmax(0, 1fr));
}

.chess-board div.row {
    display: grid;
    grid-template-columns: repeat(8, minmax(0, 1fr));
}

.chess-board div.cell {
    padding: 10%;
    display: grid;
    place-content: center;
    aspect-ratio: 1 / 1;

}

.chess-board img {
    display: block;
    width: 100%;
    object-fit: contain;
}

.chess-board .row:nth-child(even) .cell:nth-child(odd) {
    background-color: #4b7399;
}

.chess-board .row:nth-child(even) .cell:nth-child(even) {
    background-color: #eae9d2;
}

.chess-board .row:nth-child(odd) .cell:nth-child(even) {
    background-color: #4b7399;
}

.chess-board .row:nth-child(odd) .cell:nth-child(odd) {
    background-color: #eae9d2;
}

p.error {
    color: darkred;
}