fuse-overlayfs

This commit is contained in:
Rowan 2025-03-03 12:45:04 -06:00
parent 002a981071
commit cd0a1527f2
11 changed files with 1395 additions and 111 deletions

828
Cargo.lock generated
View file

@ -2,6 +2,101 @@
# It is not intended for manual editing.
version = 4
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[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 = "autocfg"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "bindgen"
version = "0.68.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078"
dependencies = [
"bitflags",
"cexpr",
"clang-sys",
"lazy_static",
"lazycell",
"log",
"peeking_take_while",
"prettyplease",
"proc-macro2",
"quote",
"regex",
"rustc-hash",
"shlex",
"syn",
"which",
]
[[package]]
name = "bitflags"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
[[package]]
name = "bumpalo"
version = "3.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
[[package]]
name = "bytemuck"
version = "1.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3"
[[package]]
name = "cc"
version = "1.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c"
dependencies = [
"shlex",
]
[[package]]
name = "cexpr"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
dependencies = [
"nom",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "char_enum"
version = "0.1.0"
@ -18,6 +113,36 @@ dependencies = [
"syn",
]
[[package]]
name = "chrono"
version = "0.4.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c"
dependencies = [
"android-tzdata",
"iana-time-zone",
"num-traits",
"serde",
"windows-link",
]
[[package]]
name = "clang-sys"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
dependencies = [
"glob",
"libc",
"libloading",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "either"
version = "1.13.0"
@ -44,6 +169,143 @@ dependencies = [
"syn",
]
[[package]]
name = "errno"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
dependencies = [
"libc",
"windows-sys",
]
[[package]]
name = "futures"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-channel"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]]
name = "futures-core"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
[[package]]
name = "futures-executor"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-io"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
[[package]]
name = "futures-macro"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "futures-sink"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
[[package]]
name = "futures-task"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
[[package]]
name = "futures-util"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-macro",
"futures-sink",
"futures-task",
"memchr",
"pin-project-lite",
"pin-utils",
"slab",
]
[[package]]
name = "glob"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
[[package]]
name = "home"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf"
dependencies = [
"windows-sys",
]
[[package]]
name = "iana-time-zone"
version = "0.1.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
"windows-core 0.52.0",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "itertools"
version = "0.14.0"
@ -53,6 +315,127 @@ dependencies = [
"either",
]
[[package]]
name = "js-sys"
version = "0.3.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
dependencies = [
"once_cell",
"wasm-bindgen",
]
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "lazycell"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.170"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828"
[[package]]
name = "libloading"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
dependencies = [
"cfg-if",
"windows-targets",
]
[[package]]
name = "linux-raw-sys"
version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]]
name = "log"
version = "0.4.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e"
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
[[package]]
name = "paste"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "peeking_take_while"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]]
name = "pin-project-lite"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "prettyplease"
version = "0.2.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6924ced06e1f7dfe3fa48d57b9f74f55d8915f5036121bef647ef4b204895fac"
dependencies = [
"proc-macro2",
"syn",
]
[[package]]
name = "proc-macro2"
version = "1.0.93"
@ -71,6 +454,101 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "regex"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustix"
version = "0.38.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
dependencies = [
"bitflags",
"errno",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]]
name = "rustversion"
version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
[[package]]
name = "serde"
version = "1.0.218"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.218"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "slab"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
dependencies = [
"autocfg",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "syn"
version = "2.0.98"
@ -82,6 +560,46 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "thiserror"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
"thiserror-impl 1.0.69",
]
[[package]]
name = "thiserror"
version = "2.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc"
dependencies = [
"thiserror-impl 2.0.11",
]
[[package]]
name = "thiserror-impl"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "thiserror-impl"
version = "2.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-ident"
version = "1.0.17"
@ -95,4 +613,314 @@ dependencies = [
"char_enum",
"enumflags2",
"itertools",
"winfsp",
"wmi",
]
[[package]]
name = "wasm-bindgen"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
dependencies = [
"cfg-if",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
dependencies = [
"bumpalo",
"log",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
dependencies = [
"unicode-ident",
]
[[package]]
name = "which"
version = "4.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
dependencies = [
"either",
"home",
"once_cell",
"rustix",
]
[[package]]
name = "widestring"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311"
[[package]]
name = "windows"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be"
dependencies = [
"windows-core 0.52.0",
"windows-targets",
]
[[package]]
name = "windows"
version = "0.60.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddf874e74c7a99773e62b1c671427abf01a425e77c3d3fb9fb1e4883ea934529"
dependencies = [
"windows-collections",
"windows-core 0.60.1",
"windows-future",
"windows-link",
"windows-numerics",
]
[[package]]
name = "windows-collections"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5467f79cc1ba3f52ebb2ed41dbb459b8e7db636cc3429458d9a852e15bc24dec"
dependencies = [
"windows-core 0.60.1",
]
[[package]]
name = "windows-core"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-core"
version = "0.60.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca21a92a9cae9bf4ccae5cf8368dce0837100ddf6e6d57936749e85f152f6247"
dependencies = [
"windows-implement",
"windows-interface",
"windows-link",
"windows-result",
"windows-strings",
]
[[package]]
name = "windows-future"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a787db4595e7eb80239b74ce8babfb1363d8e343ab072f2ffe901400c03349f0"
dependencies = [
"windows-core 0.60.1",
"windows-link",
]
[[package]]
name = "windows-implement"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83577b051e2f49a058c308f17f273b570a6a758386fc291b5f6a934dd84e48c1"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-interface"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb26fd936d991781ea39e87c3a27285081e3c0da5ca0fcbc02d368cc6f52ff01"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-link"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3"
[[package]]
name = "windows-numerics"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "005dea54e2f6499f2cee279b8f703b3cf3b5734a2d8d21867c8f44003182eeed"
dependencies = [
"windows-core 0.60.1",
"windows-link",
]
[[package]]
name = "windows-result"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06374efe858fab7e4f881500e6e86ec8bc28f9462c47e5a9941a0142ad86b189"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-strings"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winfsp"
version = "0.11.3+winfsp-2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "583f578b24fce35aedd77408b096d78740bd9bddf213f7859dc3571b2f3ff828"
dependencies = [
"bytemuck",
"paste",
"static_assertions",
"thiserror 1.0.69",
"widestring",
"windows 0.52.0",
"winfsp-sys",
]
[[package]]
name = "winfsp-sys"
version = "0.2.2+winfsp-2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbabd94628121ac484d3ab764430e1ded8d5fdf5f940e1f0d08971c394dbd59f"
dependencies = [
"bindgen",
]
[[package]]
name = "wmi"
version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae33d16f05f9b4b819abe7a9472bad4acb17f5b5d52d3f422762ebec613c65a6"
dependencies = [
"chrono",
"futures",
"log",
"serde",
"thiserror 2.0.11",
"windows 0.60.0",
"windows-core 0.60.1",
]

View file

@ -7,3 +7,7 @@ edition = "2021"
char_enum = { version = "0.1.0", path = "crates/char_enum", features = ["derive"] }
enumflags2 = "0.7.11"
itertools = "0.14.0"
[target.'cfg(windows)'.dependencies]
winfsp = "0.11.3"
wmi = "0.15.1"

View file

@ -4,38 +4,22 @@ pub use char_enum_derive;
use std::{error::Error, fmt::Display};
#[derive(Debug, Clone, PartialEq)]
pub struct FromCharError {
message: String,
}
impl FromCharError {
pub fn new(message: String) -> Self {
Self { message }
}
}
pub struct FromCharError(pub char);
impl Display for FromCharError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.message)
write!(f, "invalid char: {}", self.0)
}
}
impl Error for FromCharError {}
#[derive(Debug, Clone, PartialEq)]
pub struct FromStrError {
message: String,
}
impl FromStrError {
pub fn new(message: String) -> Self {
Self { message }
}
}
pub struct FromStrError(pub String);
impl Display for FromStrError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.message)
write!(f, "invalid string: {}", self.0)
}
}
@ -43,7 +27,7 @@ impl Error for FromStrError {}
impl From<FromCharError> for FromStrError {
fn from(value: FromCharError) -> Self {
Self::new(value.to_string())
Self(value.to_string())
}
}

View file

@ -135,7 +135,7 @@ impl From<TypedIdRange> for UntypedIdRange {
}
}
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ParseIdRangeError(String);
impl Display for ParseIdRangeError {

View file

@ -70,34 +70,52 @@ impl Display for KeyValuePair {
}
}
#[derive(Debug, Default)]
pub struct MountOptions(Vec<MountOption>);
#[derive(Debug)]
pub struct MountOptions<T>(pub Vec<T>);
impl Deref for MountOptions {
type Target = Vec<MountOption>;
impl<T: Clone> Clone for MountOptions<T> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<T> Default for MountOptions<T> {
fn default() -> Self {
Self(Vec::new())
}
}
impl<T> Deref for MountOptions<T> {
type Target = Vec<T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for MountOptions {
impl<T> DerefMut for MountOptions<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl FromStr for MountOptions {
type Err = ParseMountOptionError;
impl<T> FromIterator<T> for MountOptions<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
Self(iter.into_iter().collect())
}
}
impl<T: FromStr> FromStr for MountOptions<T> {
type Err = T::Err;
fn from_str(s: &str) -> Result<Self, Self::Err> {
s.split(',')
.map(MountOption::from_str)
.map(T::from_str)
.process_results(|it| MountOptions(it.collect()))
}
}
impl Display for MountOptions {
impl<T: Display> Display for MountOptions<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let options = self.0.iter().map(|x| x.to_string()).join(" ");
write!(f, "{options}")
@ -850,18 +868,18 @@ impl Display for MountOperation {
}
}
#[derive(Debug)]
#[derive(Clone, Debug)]
pub struct Mount {
source: DeviceId,
target: PathBuf,
options: MountOptions,
options: MountOptions<MountOption>,
}
impl Mount {
pub fn new(
src: impl Into<DeviceId>,
target: impl Into<PathBuf>,
options: impl Into<MountOptions>,
options: impl Into<MountOptions<MountOption>>,
) -> Self {
Self {
source: src.into(),
@ -870,7 +888,7 @@ impl Mount {
}
}
pub fn exec(&self) -> std::io::Result<std::process::Output> {
pub fn mount(&self) -> std::io::Result<std::process::Output> {
Command::new("mount")
.arg(self.options.to_string())
.arg(self.source.to_string())
@ -901,7 +919,7 @@ mod tests {
use crate::fs::{
id_mapping::UntypedIdRange,
mount::{ParseDeviceIdTypeError, ParseOptionsSourceError},
permission::{OctalPermissions, Permissions},
permission::Permissions,
};
use super::{
@ -1248,7 +1266,7 @@ mod tests {
}
#[test]
fn it_works() {
fn mount() {
let mut options = MountOptions::default();
options.push(MountOption::FsType(vec!["overlay"].into()));
options.push(MountOption::MakeDir(Some(Permissions::Octal(

View file

@ -466,6 +466,19 @@ mod tests {
);
}
#[test]
fn modes() {
let sym_modes = Modes::<SymbolicMode>::from_str("rwx").unwrap();
let ids = Modes::<GroupId>::from_str("ugo").unwrap();
assert_eq!(
sym_modes.0,
SymbolicMode::Read | SymbolicMode::Write | SymbolicMode::Execute
);
assert_eq!(ids.0, GroupId::User | GroupId::Group | GroupId::Other);
}
#[test]
fn symbolic_permissions() {
let sym = Permissions::from_str("ug+w").unwrap();

View file

@ -1,65 +1,471 @@
use std::fmt::Display;
use std::{
convert::Infallible,
error::Error,
fmt::Display,
num::ParseIntError,
ops::Deref,
path::{Path, PathBuf},
process::Command,
str::FromStr,
};
use crate::fs::{id_mapping::IdMapping, AsIter, FileSystem, Mountpoint};
use crate::fs::{
id_mapping::{IdMapping, ParseIdRangeError},
mount::MountOptions,
AsIter, FileSystem, Mountpoint,
};
use crate::macros::*;
use super::{Stack, Stackable};
use super::Stack;
macro_rules! impl_wrapper {
($name:ident($inner:ty), $err:ty, $from_str:block) => {
impl Deref for $name {
type Target = $inner;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl FromStr for $name {
type Err = $err;
fn from_str(s: &str) -> Result<Self, Self::Err> {
$from_str
//Ok(Self($target::from_str(s)?))
}
}
impl Display for $name {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
};
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Test(usize);
impl_wrapper!(Test(usize), ParseIntError, {
Ok(Test(usize::from_str(s)?))
});
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ParseMaxIdleThreadsError(ParseIntError);
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ParseMaxThreadsError(ParseIntError);
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ParseSquashToIdError(ParseIntError);
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ParseSquashToUidError(ParseSquashToIdError);
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ParseSquashToGidError(ParseSquashToIdError);
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ParseUidMappingError(ParseIdRangeError);
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ParseGidMappingError(ParseIdRangeError);
impl_wrapper_err_for!(
ParseMaxIdleThreadsError(ParseIntError),
"invalid max idle threads"
);
impl_wrapper_err_for!(ParseMaxThreadsError(ParseIntError), "invalid max threads");
impl_wrapper_err_for!(ParseSquashToIdError(ParseIntError), "invalid id");
impl_wrapper_err_for!(ParseSquashToUidError(ParseSquashToIdError), "invalid uid");
impl_wrapper_err_for!(ParseSquashToGidError(ParseSquashToIdError), "invalid gid");
impl_wrapper_err_for!(ParseUidMappingError(ParseIdRangeError), "invalid uid");
impl_wrapper_err_for!(ParseGidMappingError(ParseIdRangeError), "invalid gid");
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct LowerDirs(Vec<PathBuf>);
impl Deref for LowerDirs {
type Target = Vec<PathBuf>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Display for LowerDirs {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
self.0
.iter()
.map(|v| v.to_string_lossy())
.fold(String::new(), |a, b| a + &b)
)
}
}
impl FromStr for LowerDirs {
type Err = Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(s.split(',').map(Into::into).collect()))
}
}
impl From<Vec<&str>> for LowerDirs {
fn from(value: Vec<&str>) -> Self {
Self(value.into_iter().map(PathBuf::from).collect())
}
}
impl From<Vec<String>> for LowerDirs {
fn from(value: Vec<String>) -> Self {
Self(value.into_iter().map(PathBuf::from).collect())
}
}
impl From<Vec<&Path>> for LowerDirs {
fn from(value: Vec<&Path>) -> Self {
Self(value.into_iter().map(Path::to_path_buf).collect())
}
}
impl From<Vec<PathBuf>> for LowerDirs {
fn from(value: Vec<PathBuf>) -> Self {
Self(value)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct MaxIdleThreads(Option<usize>);
impl Default for MaxIdleThreads {
fn default() -> Self {
Self(None)
}
}
impl FromStr for MaxIdleThreads {
type Err = ParseMaxIdleThreadsError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"-1" => Ok(Self(None)),
s => Ok(usize::from_str_radix(s, 10).map(Some).map(Self)?),
}
}
}
impl Display for MaxIdleThreads {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self.0 {
Some(n) => write!(f, "{n}"),
None => write!(f, "-1"),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct MaxThreads(usize);
impl Default for MaxThreads {
fn default() -> Self {
Self(10)
}
}
impl FromStr for MaxThreads {
type Err = ParseMaxThreadsError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(usize::from_str_radix(s, 10).map(Self)?)
}
}
impl Display for MaxThreads {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct SquashToId(usize);
impl FromStr for SquashToId {
type Err = ParseSquashToIdError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(usize::from_str_radix(s, 10).map(Self)?)
}
}
impl Display for SquashToId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct SquashToUid(SquashToId);
impl Deref for SquashToUid {
type Target = SquashToId;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl FromStr for SquashToUid {
type Err = ParseSquashToUidError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(SquashToId::from_str(s)?))
}
}
impl Display for SquashToUid {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct SquashToGid(SquashToId);
impl Deref for SquashToGid {
type Target = SquashToId;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl FromStr for SquashToGid {
type Err = ParseSquashToGidError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(SquashToId::from_str(s)?))
}
}
impl Display for SquashToGid {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct GidMapping(IdMapping);
impl Deref for GidMapping {
type Target = IdMapping;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl FromStr for GidMapping {
type Err = ParseGidMappingError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(IdMapping::from_str(s)?))
}
}
impl Display for GidMapping {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct GidMapping(IdMapping);
impl Deref for GidMapping {
type Target = IdMapping;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl FromStr for GidMapping {
type Err = ParseGidMappingError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(IdMapping::from_str(s)?))
}
}
impl Display for GidMapping {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ParseFuseOverlayOptionError {
MaxIdleThreads(ParseMaxIdleThreadsError),
MaxThreads(ParseMaxThreadsError),
SquashToUid(ParseSquashToUidError),
SquashToGid(ParseSquashToGidError),
UidMapping(ParseUidMappingError),
GidMapping(ParseGidMappingError),
}
impl Display for ParseFuseOverlayOptionError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::MaxIdleThreads(e) => write!(f, "{e}"),
Self::MaxThreads(e) => write!(f, "{e}"),
Self::SquashToUid(e) => write!(f, "{e}"),
Self::SquashToGid(e) => write!(f, "{e}"),
Self::UidMapping(e) => write!(f, "{e}"),
Self::GidMapping(e) => write!(f, "{e}"),
}
}
}
impl Error for ParseFuseOverlayOptionError {}
impl_from_variants!(
ParseFuseOverlayOptionError,
MaxIdleThreads(ParseMaxIdleThreadsError),
MaxThreads(ParseMaxThreadsError)
);
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum FuseOverlayOption {
LowerDir(LowerDirs),
UpperDir(PathBuf),
WorkDir(PathBuf),
CloneFd,
MaxIdleThreads(isize),
MaxThreads(usize),
MaxIdleThreads(MaxIdleThreads),
MaxThreads(MaxThreads),
AllowOther,
AllowRoot,
SquashToRoot,
SquashToUid(usize),
SquashToGid(usize),
SquashToUid(SquashToUid),
SquashToGid(SquashToGid),
StaticNLink,
NoAcl,
UidMapping(IdMapping),
GidMapping(IdMapping),
}
impl_from_variants!(
FuseOverlayOption,
LowerDir(LowerDirs),
MaxIdleThreads(MaxIdleThreads),
MaxThreads(MaxThreads),
SquashToUid(SquashToUid),
SquashToGid(SquashToGid)
);
impl FromStr for FuseOverlayOption {
type Err = ParseFuseOverlayOptionError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let s = s.trim().trim_start_matches('-');
let option = match s.split_once(|delim| delim == ' ' || delim == '=') {
Some((option, value)) => (option, Some(value)),
None => (s, None),
};
match option {
("lowerdir", Some(args)) => Ok(LowerDirs::from_str(args).unwrap().into()),
("upperdir", Some(args)) => Ok(Self::UpperDir(PathBuf::from(args))),
("workdir", Some(args)) => Ok(Self::WorkDir(PathBuf::from(args))),
("clonefd", None) => Ok(Self::CloneFd),
("max_idle_threads", Some(args)) => Ok(MaxIdleThreads::from_str(args).into()?),
("max_threads", Some(args)) => Ok(MaxThreads::from_str(args).into()?),
("allow_other", None) => Ok(Self::AllowOther),
("allow_root", None) => Ok(Self::AllowRoot),
("squash_to_root", None) => Ok(Self::SquashToRoot),
("squash_to_uid", Some(uid)) => Ok(SquashToUid::from_str(uid).into()?),
("squash_to_gid", Some(gid)) => Ok(SquashToGid::from_str(gid).into()?),
("static_nlink", None) => Ok(Self::StaticNLink),
("noacl", None) => Ok(Self::NoAcl),
("uidmapping", Some(ids)) => Ok(Self::UidMapping(IdMapping::from_str(ids)?)),
("gidmapping", Some(ids)) => Ok(Self::GidMapping(IdMapping::from_str(ids)?)),
}
}
}
impl Display for FuseOverlayOption {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
write!(f, "-o ")?;
match self {
FuseOverlayOption::CloneFd => "clone_fd".to_string(),
FuseOverlayOption::MaxIdleThreads(n) => format!("max_idle_threads={n}"),
FuseOverlayOption::MaxThreads(n) => format!("max_threads={n}"),
FuseOverlayOption::AllowOther => "allow_other".to_string(),
FuseOverlayOption::AllowRoot => "allow_root".to_string(),
FuseOverlayOption::SquashToRoot => "squash_to_root".to_string(),
FuseOverlayOption::SquashToUid(uid) => format!("squash_to_uid={uid}"),
FuseOverlayOption::SquashToGid(gid) => format!("squash_to_gid={gid}"),
FuseOverlayOption::StaticNLink => "static_nlink".to_string(),
FuseOverlayOption::NoAcl => "noacl".to_string(),
FuseOverlayOption::UidMapping(map) => format!("uidmapping={map}"),
FuseOverlayOption::GidMapping(map) => format!("gidmapping={map}"),
FuseOverlayOption::LowerDir(lower) => write!(f, "{lower}"),
FuseOverlayOption::UpperDir(path) => write!(f, "{}", path.to_string_lossy()),
FuseOverlayOption::WorkDir(path) => write!(f, "{}", path.to_string_lossy()),
FuseOverlayOption::CloneFd => write!(f, "clone_fd"),
FuseOverlayOption::MaxIdleThreads(n) => write!(f, "max_idle_threads={n}"),
FuseOverlayOption::MaxThreads(n) => write!(f, "max_threads={n}"),
FuseOverlayOption::AllowOther => write!(f, "allow_other"),
FuseOverlayOption::AllowRoot => write!(f, "allow_root"),
FuseOverlayOption::SquashToRoot => write!(f, "squash_to_root"),
FuseOverlayOption::SquashToUid(uid) => write!(f, "squash_to_uid={uid}"),
FuseOverlayOption::SquashToGid(gid) => write!(f, "squash_to_gid={gid}"),
FuseOverlayOption::StaticNLink => write!(f, "static_nlink"),
FuseOverlayOption::NoAcl => write!(f, "noacl"),
FuseOverlayOption::UidMapping(map) => write!(f, "uidmapping={map}"),
FuseOverlayOption::GidMapping(map) => write!(f, "gidmapping={map}"),
}
)
}
}
#[derive(Debug)]
pub struct FuseOverlay {
fs: Stackable,
options: Vec<FuseOverlayOption>,
lower_dir: usize,
upper_dir: Option<usize>,
work_dir: Option<usize>,
options: MountOptions<FuseOverlayOption>,
}
impl FuseOverlay {
pub fn new(lowerdir: impl Into<LowerDirs>) -> Self {
Self {
lower_dir: 0,
upper_dir: None,
work_dir: None,
options: MountOptions(vec![FuseOverlayOption::LowerDir(lowerdir.into())]),
}
}
}
impl Stack for FuseOverlay {
fn lower_dirs(&self) -> impl Iterator<Item = &std::path::Path> {
self.fs.lower_dirs()
match self.options.get(self.lower_dir) {
Some(FuseOverlayOption::LowerDir(lower)) => lower.as_iter().map(AsRef::as_ref),
_ => panic!("invalid lowerdir option"),
}
}
fn upper_dir(&self) -> Option<&std::path::Path> {
self.fs.upper_dir()
let upper = self.upper_dir.and_then(|i| self.options.get(i));
match upper {
Some(FuseOverlayOption::UpperDir(upper)) => Some(upper),
_ => None,
}
}
fn work_dir(&self) -> Option<&std::path::Path> {
self.fs.work_dir()
let work = self.work_dir.and_then(|i| self.options.get(i));
match work {
Some(FuseOverlayOption::WorkDir(work)) => Some(work),
_ => None,
}
}
}
@ -71,10 +477,36 @@ impl Mountpoint for FuseOverlay {
impl FileSystem for FuseOverlay {
fn mount(&mut self) -> std::io::Result<()> {
todo!()
let mut cmd = Command::new("fuse-overlayfs").arg(self.options.to_string());
if self.fs.lower.len() > 0 {
cmd.arg(format!("-o lowerdir={}", self.fs.lower));
};
if let Some(upper) = &self.fs.upper {
cmd.arg(format!("-o upperdir={}", upper.to_string_lossy()));
};
if let Some(work) = &self.fs.work {
cmd.arg(format!("-o workdir={}", work.to_string_lossy()));
};
cmd.output()?;
Ok(())
}
fn unmount(&mut self) -> std::io::Result<()> {
todo!()
if let Some(upper) = &self.fs.upper {
Command::new("fusermount").arg("-u").arg(upper).output()?;
}
Ok(())
}
}
impl Display for FuseOverlay {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "fuse-overlayfs")
}
}

View file

@ -1,51 +1,10 @@
pub mod fuse_overlay;
pub mod overlay;
use std::path::{Path, PathBuf};
use std::path::Path;
pub trait Stack {
fn lower_dirs(&self) -> impl Iterator<Item = &Path>;
fn upper_dir(&self) -> Option<&Path>;
fn work_dir(&self) -> Option<&Path>;
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Stackable {
lower: Vec<PathBuf>,
upper: Option<PathBuf>,
work: Option<PathBuf>,
}
impl Stackable {
pub fn new(lower: Vec<PathBuf>) -> Self {
Self {
lower,
upper: None,
work: None,
}
}
pub fn with_upper_dir(&mut self, upper: impl Into<PathBuf>) -> &mut Self {
self.upper = Some(upper.into());
self
}
pub fn with_work_dir(&mut self, work: impl Into<PathBuf>) -> &mut Self {
self.work = Some(work.into());
self
}
}
impl Stack for Stackable {
fn lower_dirs(&self) -> impl Iterator<Item = &Path> {
self.lower.iter().map(AsRef::as_ref)
}
fn upper_dir(&self) -> Option<&Path> {
self.upper.as_deref()
}
fn work_dir(&self) -> Option<&Path> {
self.work.as_deref()
}
}

View file

View file

@ -1,4 +1,5 @@
pub mod fs;
mod macros;
mod utils;
pub fn add(left: u64, right: u64) -> u64 {

45
src/macros.rs Normal file
View file

@ -0,0 +1,45 @@
macro_rules! impl_from_variants {
($enum_type:ident, $($variant:ident($inner_type:ty)),*) => {
$(
impl From<$inner_type> for $enum_type {
fn from(inner: $inner_type) -> Self {
$enum_type::$variant(inner)
}
}
)*
};
}
macro_rules! impl_wrapper_err_for {
($name:ident($inner:ty), $err:literal) => {
impl_wrapper_err!($name, $err);
impl_from_ty!($name, $inner);
};
}
macro_rules! impl_from_ty {
($name:ty, $from:ty) => {
impl From<$from> for $name {
fn from(value: $from) -> Self {
Self(value)
}
}
};
}
macro_rules! impl_wrapper_err {
($type:ty, $err:literal) => {
impl Display for $type {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}: {}", self.0, $err)
}
}
impl Error for $type {}
};
}
pub(crate) use impl_from_ty;
pub(crate) use impl_from_variants;
pub(crate) use impl_wrapper_err;
pub(crate) use impl_wrapper_err_for;