begin day 7

This commit is contained in:
Michael Zhang 2022-12-07 22:02:28 -06:00
parent c32331168d
commit a5f4a054b3
Signed by: michael
GPG Key ID: BDA47A31A3C8EE6B
14 changed files with 2272 additions and 0 deletions

1
.envrc Normal file
View File

@ -0,0 +1 @@
use flake

2
.gitignore vendored
View File

@ -1 +1,3 @@
node_modules
.direnv
result

2
07/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
target
output.log

673
07/Cargo.lock generated Normal file
View File

@ -0,0 +1,673 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "anyhow"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6"
[[package]]
name = "aoc07"
version = "0.1.0"
dependencies = [
"anyhow",
"chrono",
"clap",
"ctrlc",
"fern",
"fuse",
"indexmap",
"log 0.4.17",
"time",
]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bumpalo"
version = "3.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
[[package]]
name = "cc"
version = "1.0.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f"
dependencies = [
"iana-time-zone",
"js-sys",
"num-integer",
"num-traits",
"time",
"wasm-bindgen",
"winapi",
]
[[package]]
name = "clap"
version = "4.0.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d63b9e9c07271b9957ad22c173bae2a4d9a81127680962039296abcd2f8251d"
dependencies = [
"bitflags",
"clap_derive",
"clap_lex",
"is-terminal",
"once_cell",
"strsim",
"termcolor",
]
[[package]]
name = "clap_derive"
version = "4.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014"
dependencies = [
"heck",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8"
dependencies = [
"os_str_bytes",
]
[[package]]
name = "codespan-reporting"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
dependencies = [
"termcolor",
"unicode-width",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
[[package]]
name = "ctrlc"
version = "3.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d91974fbbe88ec1df0c24a4f00f99583667a7e2e6272b2b92d294d81e462173"
dependencies = [
"nix",
"winapi",
]
[[package]]
name = "cxx"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdf07d07d6531bfcdbe9b8b739b104610c6508dcc4d63b410585faf338241daf"
dependencies = [
"cc",
"cxxbridge-flags",
"cxxbridge-macro",
"link-cplusplus",
]
[[package]]
name = "cxx-build"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2eb5b96ecdc99f72657332953d4d9c50135af1bac34277801cc3937906ebd39"
dependencies = [
"cc",
"codespan-reporting",
"once_cell",
"proc-macro2",
"quote",
"scratch",
"syn",
]
[[package]]
name = "cxxbridge-flags"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac040a39517fd1674e0f32177648334b0f4074625b5588a64519804ba0553b12"
[[package]]
name = "cxxbridge-macro"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1362b0ddcfc4eb0a1f57b68bd77dd99f0e826958a96abd0ae9bd092e114ffed6"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "errno"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
dependencies = [
"errno-dragonfly",
"libc",
"winapi",
]
[[package]]
name = "errno-dragonfly"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
dependencies = [
"cc",
"libc",
]
[[package]]
name = "fern"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3bdd7b0849075e79ee9a1836df22c717d1eba30451796fdc631b04565dd11e2a"
dependencies = [
"log 0.4.17",
]
[[package]]
name = "fuse"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80e57070510966bfef93662a81cb8aa2b1c7db0964354fa9921434f04b9e8660"
dependencies = [
"libc",
"log 0.3.9",
"pkg-config",
"thread-scoped",
"time",
]
[[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"
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
[[package]]
name = "hermit-abi"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
dependencies = [
"libc",
]
[[package]]
name = "iana-time-zone"
version = "0.1.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
"winapi",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca"
dependencies = [
"cxx",
"cxx-build",
]
[[package]]
name = "indexmap"
version = "1.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
dependencies = [
"autocfg",
"hashbrown",
]
[[package]]
name = "io-lifetimes"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c"
dependencies = [
"libc",
"windows-sys",
]
[[package]]
name = "is-terminal"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "927609f78c2913a6f6ac3c27a4fe87f43e2a35367c0c4b0f8265e8f49a104330"
dependencies = [
"hermit-abi",
"io-lifetimes",
"rustix",
"windows-sys",
]
[[package]]
name = "js-sys"
version = "0.3.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "libc"
version = "0.2.138"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
[[package]]
name = "link-cplusplus"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369"
dependencies = [
"cc",
]
[[package]]
name = "linux-raw-sys"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f9f08d8963a6c613f4b1a78f4f4a4dbfadf8e6545b2d72861731e4858b8b47f"
[[package]]
name = "log"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
dependencies = [
"log 0.4.17",
]
[[package]]
name = "log"
version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
"cfg-if",
]
[[package]]
name = "nix"
version = "0.25.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4"
dependencies = [
"autocfg",
"bitflags",
"cfg-if",
"libc",
]
[[package]]
name = "num-integer"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
[[package]]
name = "os_str_bytes"
version = "6.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
[[package]]
name = "pkg-config"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]]
name = "proc-macro2"
version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rustix"
version = "0.36.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3807b5d10909833d3e9acd1eb5fb988f79376ff10fce42937de71a449c4c588"
dependencies = [
"bitflags",
"errno",
"io-lifetimes",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]]
name = "scratch"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898"
[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "syn"
version = "1.0.105"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "termcolor"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
dependencies = [
"winapi-util",
]
[[package]]
name = "thread-scoped"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcbb6aa301e5d3b0b5ef639c9a9c7e2f1c944f177b460c04dc24c69b1fa2bd99"
[[package]]
name = "time"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
dependencies = [
"libc",
"wasi",
"winapi",
]
[[package]]
name = "unicode-ident"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
[[package]]
name = "unicode-width"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasi"
version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]]
name = "wasm-bindgen"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
dependencies = [
"bumpalo",
"log 0.4.17",
"once_cell",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
[[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-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]
[[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.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"

15
07/Cargo.toml Normal file
View File

@ -0,0 +1,15 @@
[package]
name = "aoc07"
version = "0.1.0"
edition = "2021"
[dependencies]
anyhow = "1.0.66"
chrono = "0.4.23"
clap = { version = "4.0.29", features = ["derive"] }
ctrlc = "3.2.3"
fern = "0.6.1"
fuse = "0.3.1"
indexmap = "1.9.2"
log = "0.4.17"
time = "0.1"

1010
07/data.txt Normal file

File diff suppressed because it is too large Load Diff

23
07/ex.txt Normal file
View File

@ -0,0 +1,23 @@
$ cd /
$ ls
dir a
14848514 b.txt
8504156 c.dat
dir d
$ cd a
$ ls
dir e
29116 f
2557 g
62596 h.lst
$ cd e
$ ls
584 i
$ cd ..
$ cd ..
$ cd d
$ ls
4060174 j
8033020 d.log
5626152 d.ext
7214296 k

296
07/src/fs.rs Normal file
View File

@ -0,0 +1,296 @@
use std::collections::HashMap;
use std::ffi::OsStr;
use std::path::{Component, Path};
use std::sync::atomic::{AtomicU64, Ordering};
use anyhow::Result;
use fuse::{
FileAttr, FileType, Filesystem, ReplyAttr, ReplyData, ReplyDirectory,
ReplyEmpty, ReplyEntry, ReplyOpen, Request,
};
use indexmap::IndexMap;
use time::Timespec;
type Ino = u64;
#[derive(Debug)]
pub enum FakeFile {
Dir {
ino: Ino,
children: IndexMap<String, Ino>,
},
File {
ino: Ino,
size: u64,
},
}
impl FakeFile {
fn ino(&self) -> Ino {
match self {
FakeFile::Dir { ino, .. } | FakeFile::File { ino, .. } => *ino,
}
}
fn size(&self) -> u64 {
match self {
FakeFile::Dir { .. } => 0,
FakeFile::File { size, .. } => *size,
}
}
fn ty(&self) -> FileType {
match self {
FakeFile::Dir { .. } => FileType::Directory,
FakeFile::File { .. } => FileType::RegularFile,
}
}
fn attr(&self) -> FileAttr {
let time = Timespec::new(0, 0);
FileAttr {
ino: self.ino(),
size: self.size(),
blocks: 0,
atime: time,
mtime: time,
ctime: time,
crtime: time,
kind: self.ty(),
perm: 0o777,
nlink: 0,
uid: 0,
gid: 0,
rdev: 0,
flags: 0,
}
}
}
#[derive(Debug)]
pub struct FakeFs {
root: Ino,
ctr: AtomicU64,
info: HashMap<Ino, FakeFile>,
handles: HashMap<Ino, Ino>,
}
impl FakeFs {
pub fn new() -> Self {
let ctr = AtomicU64::new(0);
let root = ctr.fetch_add(1, Ordering::SeqCst);
let mut info = HashMap::new();
info.insert(
root,
FakeFile::Dir {
ino: root,
children: IndexMap::new(),
},
);
let handles = HashMap::new();
FakeFs {
root,
ctr,
info,
handles,
}
}
fn inc(&self) -> u64 {
self.ctr.fetch_add(1, Ordering::SeqCst)
}
pub fn set_size(&mut self, ino: Ino, new_size: u64) {
let info = self.info.get_mut(&ino).unwrap();
match info {
FakeFile::File { size, .. } => *size = new_size,
_ => {}
}
}
pub fn ensure_path(
&mut self,
path: impl AsRef<Path>,
ty: FileType,
) -> Result<Ino> {
let path = path.as_ref();
let parent_path = path.parent().unwrap();
let filename = path.file_name().unwrap().to_str().unwrap().to_owned();
let mut curr_ino = self.root;
for component in parent_path.components() {
let curr = self.info.get_mut(&curr_ino).unwrap();
let name = match component {
Component::RootDir => continue,
Component::Normal(name) => name.to_str().unwrap().to_owned(),
_ => continue,
};
let children = match curr {
FakeFile::Dir { children, .. } => children,
FakeFile::File { .. } => bail!("Trying to add children to file."),
};
if let Some(ino) = children.get(&name) {
curr_ino = *ino;
} else {
let ino = self.ctr.fetch_add(1, Ordering::SeqCst);
children.insert(name.clone(), ino);
self.info.insert(
ino,
FakeFile::Dir {
children: IndexMap::new(),
ino,
},
);
}
}
let curr = self.info.get_mut(&curr_ino).unwrap();
let children = match curr {
FakeFile::Dir { children, .. } => children,
FakeFile::File { .. } => bail!("Trying to add children to file."),
};
let ino = self.ctr.fetch_add(1, Ordering::SeqCst);
children.insert(filename.clone(), ino);
let new = match ty {
FileType::Directory => FakeFile::Dir {
children: IndexMap::new(),
ino,
},
FileType::RegularFile => FakeFile::File { size: 0, ino },
_ => unreachable!(),
};
self.info.insert(ino, new);
Ok(ino)
}
}
impl Filesystem for FakeFs {
fn access(
&mut self,
_req: &Request,
_ino: u64,
_mask: u32,
reply: ReplyEmpty,
) {
reply.ok();
}
fn getattr(&mut self, req: &Request, ino: Ino, reply: ReplyAttr) {
info!("Requested attributes: {req:?}");
info!("for inode {ino}");
let file_info = match self.info.get(&ino) {
Some(v) => v,
None => {
error!("No file at ino {ino}");
return reply.error(2);
}
};
info!("File info: {file_info:?}");
let time = Timespec::new(0, 0);
let attr = file_info.attr();
reply.attr(&time, &attr);
}
fn read(
&mut self,
_req: &Request,
_ino: u64,
_fh: u64,
_offset: i64,
_size: u32,
reply: ReplyData,
) {
info!("ASFIJPWEOIMV");
}
fn lookup(
&mut self,
_req: &Request,
parent: u64,
name: &OsStr,
reply: ReplyEntry,
) {
let name = name.to_str().unwrap().to_owned();
info!("Asked for opendir for parent {parent} and name {name}.");
let file_info = match self.info.get(&parent) {
Some(v) => v,
None => return reply.error(2),
};
let children = match file_info {
FakeFile::Dir { children, .. } => children,
FakeFile::File { .. } => return reply.error(20),
};
match children.get(&name) {
Some(v) => {
let info = self.info.get(&v).unwrap();
let time = Timespec::new(0, 0);
reply.entry(&time, &info.attr(), self.inc())
}
None => return reply.error(2),
}
}
fn opendir(
&mut self,
_req: &Request,
ino: u64,
flags: u32,
reply: ReplyOpen,
) {
info!("Asked for opendir for inode {ino}.");
let fh = self.inc();
self.handles.insert(fh, ino);
reply.opened(fh, flags);
}
fn readdir(
&mut self,
_req: &Request,
ino: u64,
fh: u64,
offset: i64,
mut reply: ReplyDirectory,
) {
let offset = offset as usize;
info!("Asked for readdir for inode {ino} @ offset {offset}.");
let file_info = match self.info.get(&ino) {
Some(v) => v,
None => return reply.error(2),
};
info!("File info: {file_info:?}");
let children = match file_info {
FakeFile::Dir { children, .. } => children,
FakeFile::File { .. } => return reply.error(20),
};
if offset < children.len() {
for (i, (child_name, child_ino)) in
children.iter().skip(offset).enumerate()
{
let child = self.info.get(&child_ino).unwrap();
reply.add(ino, (i + 1) as i64, child.ty(), child_name);
println!("Returned {child_name}");
}
}
reply.ok();
}
}
#[derive(Debug)]
pub struct FsNode {
ino: Ino,
}

134
07/src/main.rs Normal file
View File

@ -0,0 +1,134 @@
#[macro_use]
extern crate anyhow;
#[macro_use]
extern crate log;
mod fs;
mod utils;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use anyhow::Result;
use clap::Parser;
use fuse::{BackgroundSession, FileType};
use crate::fs::FakeFs;
#[derive(Debug, Parser)]
struct Opt {
input: PathBuf,
mountpoint: PathBuf,
}
fn main() -> Result<()> {
let opt = Opt::parse();
setup_logger()?;
let fs = read_input(&opt.input)?;
run_with_ctrlc(move || -> Result<BackgroundSession> {
let x = unsafe { fuse::spawn_mount(fs, &opt.mountpoint, &[])? };
Ok(x)
})?;
Ok(())
}
fn read_input(input: impl AsRef<Path>) -> Result<FakeFs> {
let mut fs = FakeFs::new();
// Read input
{
let file = File::open(input.as_ref())?;
let reader = BufReader::new(file);
let mut it = reader.lines().peekable();
let mut current_dir = PathBuf::from("/");
loop {
let line = match it.next() {
Some(Ok(v)) => v,
Some(Err(e)) => return Err(e.into()),
None => break,
};
// Assume line starts with $
let line = line.strip_prefix("$ ").unwrap();
let parts = line.split(" ").collect::<Vec<_>>();
let command = parts[0];
match command {
"cd" => {
let move_path = PathBuf::from(parts[1]);
let dst_path = utils::into_absolute(&move_path, &current_dir);
info!("Moving to {dst_path:?}");
current_dir = dst_path;
}
"ls" => loop {
let line = match it.peek() {
Some(Ok(v)) if !v.starts_with("$") => it.next().unwrap()?,
_ => break,
};
let parts = line.split(" ").collect::<Vec<_>>();
let filename = parts[1];
let (ty, size) = match parts[0] {
"dir" => (FileType::Directory, 0),
s => (FileType::RegularFile, s.parse::<u64>().unwrap()),
};
let ino = fs.ensure_path(current_dir.join(filename), ty)?;
if size > 0 {
fs.set_size(ino, size);
}
},
_ => panic!("Don't know command {command}"),
}
}
}
debug!("Fs contents: {fs:?}");
Ok(fs)
}
fn run_with_ctrlc<F, R>(f: F) -> R
where
F: FnOnce() -> R,
{
let running = Arc::new(AtomicBool::new(true));
let r = running.clone();
ctrlc::set_handler(move || {
r.store(false, Ordering::SeqCst);
})
.expect("Error setting Ctrl-C handler");
debug!("Waiting for Ctrl-C...");
let res = f();
while running.load(Ordering::SeqCst) {}
debug!("Got it! Exiting...");
res
}
fn setup_logger() -> Result<()> {
fern::Dispatch::new()
.format(|out, message, record| {
out.finish(format_args!(
"{}[{}][{}] {}",
chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"),
record.target(),
record.level(),
message
))
})
.level(log::LevelFilter::Debug)
.chain(std::io::stdout())
.chain(fern::log_file("output.log")?)
.apply()
.map_err(|e| e.into())
}

31
07/src/utils.rs Normal file
View File

@ -0,0 +1,31 @@
use std::path::{Component, Path, PathBuf};
/// Converts a path to its absolute form WITHOUT resolving symlinks.
pub fn into_absolute(
path: impl AsRef<Path>,
relative_from: impl AsRef<Path>,
) -> PathBuf {
let path = path.as_ref();
let mut new_path = if !path.is_absolute() {
relative_from.as_ref().to_path_buf()
} else {
path.to_path_buf()
};
for component in path.components() {
match component {
Component::Prefix(_) => unimplemented!("windows lol"),
Component::RootDir => return path.to_path_buf(),
Component::CurDir => {}
Component::ParentDir => {
new_path.pop();
}
Component::Normal(s) => {
new_path.push(s);
}
}
}
new_path
}

19
README.md Normal file
View File

@ -0,0 +1,19 @@
AOC 2022
========
- Day 1: Ruby
- Day 2: Python
- Day 3: BASIC
- Day 4: Prolog
- Day 5: TypeScript Type System
Future ideas:
- Agda
- Brainfuck?
- CUDA
- Emojicode?? (Need to package for Nix)
- Forth
- Rust
- Verilog??? (Or another HDL)
- Silver (for any DSLs)

40
flake.lock Normal file
View File

@ -0,0 +1,40 @@
{
"nodes": {
"flake-utils": {
"locked": {
"lastModified": 1667395993,
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
"type": "github"
},
"original": {
"id": "flake-utils",
"type": "indirect"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1667629849,
"narHash": "sha256-P+v+nDOFWicM4wziFK9S/ajF2lc0N2Rg9p6Y35uMoZI=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "3bacde6273b09a21a8ccfba15586fb165078fb62",
"type": "github"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

24
flake.nix Normal file
View File

@ -0,0 +1,24 @@
{
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let pkgs = import nixpkgs { inherit system; };
in {
legacyPackages = pkgs;
devShell = pkgs.mkShell {
packages = with pkgs; [
python3
ruby
swiProlog
yabasic
rustc
rustfmt
cargo
fuse
pkg-config
];
PKG_CONFIG_PATH = "${pkgs.fuse}/lib/pkgconfig";
};
});
}

2
rustfmt.toml Normal file
View File

@ -0,0 +1,2 @@
max_width = 80
tab_spaces = 2