feat: Add icon and update dependent (#3)

* fix: Type error on release mode and refactor README.md

* feat: Add icon and update dependent
This commit is contained in:
DaLaw2 2025-07-31 22:14:25 +08:00 committed by GitHub
parent 972bb94014
commit f72c66d348
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 765 additions and 115 deletions

BIN
.github/images/main-interface.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

583
Cargo.lock generated
View File

@ -4,7 +4,7 @@ version = 4
[[package]]
name = "MirrorSphere"
version = "0.1.0"
version = "0.0.9"
dependencies = [
"async-trait",
"bincode",
@ -18,12 +18,14 @@ dependencies = [
"egui-file-dialog",
"fs4",
"futures",
"image",
"libc",
"log-panics",
"macros",
"md-5",
"memmap2",
"privilege",
"rust-embed",
"serde",
"serde_json",
"sha2",
@ -32,13 +34,14 @@ dependencies = [
"thiserror 2.0.12",
"tokio",
"tokio-stream",
"toml",
"toml 0.9.4",
"tracing",
"tracing-appender",
"tracing-subscriber",
"uuid",
"windows",
"windows-acl",
"winres",
]
[[package]]
@ -184,6 +187,15 @@ dependencies = [
"memchr",
]
[[package]]
name = "aligned-vec"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc890384c8602f339876ded803c97ad529f3842aba97f6392b3dba0dd171769b"
dependencies = [
"equator",
]
[[package]]
name = "allocator-api2"
version = "0.2.21"
@ -232,6 +244,18 @@ dependencies = [
"libc",
]
[[package]]
name = "anyhow"
version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
[[package]]
name = "arbitrary"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223"
[[package]]
name = "arboard"
version = "3.6.0"
@ -252,6 +276,17 @@ dependencies = [
"x11rb",
]
[[package]]
name = "arg_enum_proc_macro"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "arrayref"
version = "0.3.9"
@ -474,6 +509,29 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "av1-grain"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f3efb2ca85bc610acfa917b5aaa36f3fcbebed5b3182d7f877b02531c4b80c8"
dependencies = [
"anyhow",
"arrayvec",
"log",
"nom",
"num-rational",
"v_frame",
]
[[package]]
name = "avif-serialize"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19135c0c7a60bfee564dbe44ab5ce0557c6bf3884e5291a50be76a15640c4fbd"
dependencies = [
"arrayvec",
]
[[package]]
name = "backtrace"
version = "0.3.75"
@ -536,6 +594,12 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
[[package]]
name = "bit_field"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
[[package]]
name = "bitflags"
version = "1.3.2"
@ -551,6 +615,12 @@ dependencies = [
"serde",
]
[[package]]
name = "bitstream-io"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2"
[[package]]
name = "blake2"
version = "0.10.6"
@ -605,6 +675,12 @@ dependencies = [
"piper",
]
[[package]]
name = "built"
version = "0.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56ed6191a7e78c36abdb16ab65341eefd73d64d303fffccdbb00d51e4205967b"
[[package]]
name = "bumpalo"
version = "3.19.0"
@ -692,6 +768,16 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
[[package]]
name = "cfg-expr"
version = "0.15.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02"
dependencies = [
"smallvec",
"target-lexicon",
]
[[package]]
name = "cfg-if"
version = "1.0.1"
@ -748,6 +834,12 @@ dependencies = [
"unicode-width",
]
[[package]]
name = "color_quant"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "combine"
version = "4.6.7"
@ -871,6 +963,25 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
dependencies = [
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-queue"
version = "0.3.12"
@ -1248,6 +1359,26 @@ version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8495e11ed527dff39663b8c36b6c2b2799d7e4287fb90556e455d72eca0b4d3"
[[package]]
name = "equator"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4711b213838dfee0117e3be6ac926007d7f433d7bbe33595975d4190cb07e6fc"
dependencies = [
"equator-macro",
]
[[package]]
name = "equator-macro"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "equivalent"
version = "1.0.2"
@ -1302,6 +1433,21 @@ dependencies = [
"pin-project-lite",
]
[[package]]
name = "exr"
version = "1.73.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f83197f59927b46c04a183a619b7c29df34e63e63c7869320862268c0ef687e0"
dependencies = [
"bit_field",
"half",
"lebe",
"miniz_oxide",
"rayon-core",
"smallvec",
"zune-inflate",
]
[[package]]
name = "fastrand"
version = "2.3.0"
@ -1557,6 +1703,16 @@ dependencies = [
"wasi 0.14.2+wasi-0.2.4",
]
[[package]]
name = "gif"
version = "0.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ae047235e33e2829703574b54fdec96bfbad892062d97fed2f76022287de61b"
dependencies = [
"color_quant",
"weezl",
]
[[package]]
name = "gimli"
version = "0.31.1"
@ -1879,11 +2035,37 @@ checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a"
dependencies = [
"bytemuck",
"byteorder-lite",
"color_quant",
"exr",
"gif",
"image-webp",
"num-traits",
"png",
"qoi",
"ravif",
"rayon",
"rgb",
"tiff",
"zune-core",
"zune-jpeg",
]
[[package]]
name = "image-webp"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6970fe7a5300b4b42e62c52efa0187540a5bef546c60edaf554ef595d2e6f0b"
dependencies = [
"byteorder-lite",
"quick-error",
]
[[package]]
name = "imgref"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408"
[[package]]
name = "indexmap"
version = "2.10.0"
@ -1894,6 +2076,17 @@ dependencies = [
"hashbrown 0.15.4",
]
[[package]]
name = "interpolate_name"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "io-uring"
version = "0.7.8"
@ -1905,6 +2098,15 @@ dependencies = [
"libc",
]
[[package]]
name = "itertools"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.15"
@ -1983,12 +2185,28 @@ dependencies = [
"spin",
]
[[package]]
name = "lebe"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
[[package]]
name = "libc"
version = "0.2.174"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
[[package]]
name = "libfuzzer-sys"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf78f52d400cf2d84a3a973a78a592b4adc535739e0a5597a0da6f0c357adc75"
dependencies = [
"arbitrary",
"cc",
]
[[package]]
name = "libloading"
version = "0.8.8"
@ -2077,6 +2295,15 @@ dependencies = [
"log",
]
[[package]]
name = "loop9"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062"
dependencies = [
"imgref",
]
[[package]]
name = "macros"
version = "0.1.0"
@ -2095,6 +2322,16 @@ dependencies = [
"regex-automata 0.1.10",
]
[[package]]
name = "maybe-rayon"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519"
dependencies = [
"cfg-if",
"rayon",
]
[[package]]
name = "md-5"
version = "0.10.6"
@ -2129,6 +2366,12 @@ dependencies = [
"autocfg",
]
[[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.8.9"
@ -2204,6 +2447,12 @@ dependencies = [
"jni-sys",
]
[[package]]
name = "new_debug_unreachable"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
[[package]]
name = "nix"
version = "0.30.1"
@ -2223,6 +2472,22 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
[[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 = "noop_proc_macro"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8"
[[package]]
name = "nu-ansi-term"
version = "0.46.0"
@ -2233,6 +2498,16 @@ dependencies = [
"winapi",
]
[[package]]
name = "num-bigint"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
dependencies = [
"num-integer",
"num-traits",
]
[[package]]
name = "num-bigint-dig"
version = "0.8.4"
@ -2256,6 +2531,17 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
[[package]]
name = "num-derive"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "num-integer"
version = "0.1.46"
@ -2276,6 +2562,17 @@ dependencies = [
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
dependencies = [
"num-bigint",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.19"
@ -2851,6 +3148,34 @@ name = "profiling"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773"
dependencies = [
"profiling-procmacros",
]
[[package]]
name = "profiling-procmacros"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "qoi"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001"
dependencies = [
"bytemuck",
]
[[package]]
name = "quick-error"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
[[package]]
name = "quick-xml"
@ -2945,12 +3270,82 @@ dependencies = [
"getrandom 0.3.3",
]
[[package]]
name = "rav1e"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9"
dependencies = [
"arbitrary",
"arg_enum_proc_macro",
"arrayvec",
"av1-grain",
"bitstream-io",
"built",
"cfg-if",
"interpolate_name",
"itertools",
"libc",
"libfuzzer-sys",
"log",
"maybe-rayon",
"new_debug_unreachable",
"noop_proc_macro",
"num-derive",
"num-traits",
"once_cell",
"paste",
"profiling",
"rand 0.8.5",
"rand_chacha 0.3.1",
"simd_helpers",
"system-deps",
"thiserror 1.0.69",
"v_frame",
"wasm-bindgen",
]
[[package]]
name = "ravif"
version = "0.11.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5825c26fddd16ab9f515930d49028a630efec172e903483c94796cfe31893e6b"
dependencies = [
"avif-serialize",
"imgref",
"loop9",
"quick-error",
"rav1e",
"rayon",
"rgb",
]
[[package]]
name = "raw-window-handle"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539"
[[package]]
name = "rayon"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
dependencies = [
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
dependencies = [
"crossbeam-deque",
"crossbeam-utils",
]
[[package]]
name = "redox_syscall"
version = "0.4.1"
@ -3030,6 +3425,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832"
[[package]]
name = "rgb"
version = "0.8.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a457e416a0f90d246a4c3288bd7a25b2304ca727f253f95be383dd17af56be8f"
[[package]]
name = "rsa"
version = "0.9.8"
@ -3050,6 +3451,40 @@ dependencies = [
"zeroize",
]
[[package]]
name = "rust-embed"
version = "8.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "025908b8682a26ba8d12f6f2d66b987584a4a87bc024abc5bbc12553a8cd178a"
dependencies = [
"rust-embed-impl",
"rust-embed-utils",
"walkdir",
]
[[package]]
name = "rust-embed-impl"
version = "8.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6065f1a4392b71819ec1ea1df1120673418bf386f50de1d6f54204d836d4349c"
dependencies = [
"proc-macro2",
"quote",
"rust-embed-utils",
"syn",
"walkdir",
]
[[package]]
name = "rust-embed-utils"
version = "8.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6cc0c81648b20b70c491ff8cce00c1c3b223bb8ed2b5d41f0e54c6c4c0a3594"
dependencies = [
"sha2",
"walkdir",
]
[[package]]
name = "rustc-demangle"
version = "0.1.25"
@ -3217,6 +3652,15 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_spanned"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83"
dependencies = [
"serde",
]
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
@ -3301,6 +3745,15 @@ version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
[[package]]
name = "simd_helpers"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6"
dependencies = [
"quote",
]
[[package]]
name = "slab"
version = "0.4.10"
@ -3686,6 +4139,25 @@ dependencies = [
"windows",
]
[[package]]
name = "system-deps"
version = "6.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349"
dependencies = [
"cfg-expr",
"heck",
"pkg-config",
"toml 0.8.23",
"version-compare",
]
[[package]]
name = "target-lexicon"
version = "0.12.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
[[package]]
name = "tempfile"
version = "3.20.0"
@ -3891,6 +4363,15 @@ dependencies = [
"tokio",
]
[[package]]
name = "toml"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
dependencies = [
"serde",
]
[[package]]
name = "toml"
version = "0.8.23"
@ -3898,11 +4379,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"serde_spanned 0.6.9",
"toml_datetime 0.6.11",
"toml_edit",
]
[[package]]
name = "toml"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41ae868b5a0f67631c14589f7e250c1ea2c574ee5ba21c6c8dd4b1485705a5a1"
dependencies = [
"indexmap",
"serde",
"serde_spanned 1.0.0",
"toml_datetime 0.7.0",
"toml_parser",
"toml_writer",
"winnow",
]
[[package]]
name = "toml_datetime"
version = "0.6.11"
@ -3912,6 +4408,15 @@ dependencies = [
"serde",
]
[[package]]
name = "toml_datetime"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
version = "0.22.27"
@ -3920,17 +4425,25 @@ checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
dependencies = [
"indexmap",
"serde",
"serde_spanned",
"toml_datetime",
"toml_write",
"serde_spanned 0.6.9",
"toml_datetime 0.6.11",
"winnow",
]
[[package]]
name = "toml_write"
version = "0.1.2"
name = "toml_parser"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
checksum = "97200572db069e74c512a14117b296ba0a80a30123fbbb5aa1f4a348f639ca30"
dependencies = [
"winnow",
]
[[package]]
name = "toml_writer"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64"
[[package]]
name = "tracing"
@ -4113,6 +4626,17 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "v_frame"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "666b7727c8875d6ab5db9533418d7c764233ac9c0cff1d469aec8fa127597be2"
dependencies = [
"aligned-vec",
"num-traits",
"wasm-bindgen",
]
[[package]]
name = "valuable"
version = "0.1.1"
@ -4125,6 +4649,12 @@ version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "version-compare"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b"
[[package]]
name = "version_check"
version = "0.9.5"
@ -5017,6 +5547,15 @@ dependencies = [
"memchr",
]
[[package]]
name = "winres"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b68db261ef59e9e52806f688020631e987592bd83619edccda9c47d42cde4f6c"
dependencies = [
"toml 0.5.11",
]
[[package]]
name = "wit-bindgen-rt"
version = "0.39.0"
@ -5296,6 +5835,30 @@ dependencies = [
"syn",
]
[[package]]
name = "zune-core"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"
[[package]]
name = "zune-inflate"
version = "0.2.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02"
dependencies = [
"simd-adler32",
]
[[package]]
name = "zune-jpeg"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c9e525af0a6a658e031e95f14b7f889976b74a11ba0eca5a5fc9ac8a1c43a6a"
dependencies = [
"zune-core",
]
[[package]]
name = "zvariant"
version = "5.6.0"

View File

@ -1,7 +1,9 @@
[package]
name = "MirrorSphere"
version = "0.1.0"
version = "0.0.9"
edition = "2024"
authors = ["DaLaw2"]
build = "build.rs"
[dependencies]
async-trait = "0.1.88"
@ -16,12 +18,14 @@ eframe = "0.32.0"
egui-file-dialog = "0.11.0"
fs4 = { version = "0.13.1", features = ["sync", "tokio"] }
futures = "0.3.31"
image = "0.25.6"
libc = "0.2.169"
log-panics = { version = "2.1.0", features = ["with-backtrace"] }
macros = { path = "macros" }
md-5 = "0.10.6"
memmap2 = "0.9.5"
privilege = "0.3.0"
rust-embed = "8.7.2"
serde = { version = "1.0.219", features = ["derive"] }
serde_json = "1.0.140"
sha2 = "0.10.8"
@ -30,7 +34,7 @@ sqlx = { version = "0.8.6", features = ["runtime-tokio", "sqlite", "uuid", "deri
thiserror = "2.0.12"
tokio-stream = "0.1.17"
tokio = { version = "1.45.1", features = ["full"] }
toml = "0.8.22"
toml = "0.9.4"
tracing = "0.1.41"
tracing-appender = "0.2.3"
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
@ -44,5 +48,8 @@ version = "0.61.1"
features = [
"Win32", "Win32_System", "Win32_System_Memory", "Win32_System_IO", "Win32_System_Threading", "Win32_System_Time",
"Win32_System_Registry", "Win32_System_Com", "Win32_Security", "Win32_Security_Authorization", "Win32_Storage",
"Win32_Storage_FileSystem", "Win32_UI_Shell", "Win32_UI_WindowsAndMessaging", "Win32_Foundation"
"Win32_Storage_FileSystem", "Win32_UI_Shell", "Win32_UI_WindowsAndMessaging", "Win32_Foundation", "Win32_System_Console"
]
[target.'cfg(windows)'.build-dependencies]
winres = "0.1.12"

155
README.md
View File

@ -1,61 +1,144 @@
# MirrorSphere
A high-performance, cross-platform graphical backup tool developed in Rust.
A powerful, cross-platform backup and file synchronization tool built with Rust, featuring both manual execution and automated scheduling capabilities.
## Features
- User-friendly graphical interface
- High-performance parallel backup algorithm
- Cross-platform support (Windows, Linux)
- Incremental backup capabilities
- File system change tracking (Windows NTFS)
- Windows NTFS ACL support
- Preservation of extended file attributes
- Real-time backup progress display
### Core Functionality
- **Multiple Backup Types**: Full backup and incremental backup support
- **File Comparison Modes**: Standard (size + modification time), Advanced (+ attributes), Thorough (+ hash verification)
- **Mirror Mode**: Maintains exact replica by removing extra files in destination
- **Symlink Handling**: Choose to follow symlinks or copy them as-is
- **Permission Backup**: Preserve file permissions and attributes
- **Source File Locking**: Prevent modifications during backup process
### Scheduling System
- **Flexible Intervals**: Once, Daily, Weekly, Monthly scheduling
- **Schedule Management**: Create, modify, pause, resume, and disable schedules
- **Automatic Execution**: Background scheduler with configurable timing
- **Persistent Storage**: SQLite database for schedule persistence
### User Interface
- **Modern GUI**: Built with egui for cross-platform compatibility
- **Real-time Progress**: Live updates on backup progress and current operations
- **Error Tracking**: Comprehensive error logging and display
- **Task Management**: Start, pause, resume, and monitor backup executions
### Technical Features
- **Multi-threading**: Configurable concurrency for optimal performance
- **Progress Recovery**: Resume interrupted backups from last checkpoint
- **Hash Algorithms**: MD5, SHA256, SHA3, BLAKE2B, BLAKE2S, BLAKE3 support
- **Cross-platform**: Windows and Linux support with platform-specific optimizations
## Installation
### Download Installer
### Prerequisites
- Rust 1.85+ (2024 edition)
Check the [Releases](https://github.com/DaLaw2/mirrorsphere/releases) page to download the latest version of the installer.
### Build from Source
### Building from Source
```bash
git clone https://github.com/DaLaw2/mirrorsphere.git
cd mirrorsphere
# Clone the repository
git clone https://github.com/DaLaw2/MirrorSphere
cd MirrorSphere
# Build the project
cargo build --release
# Run the application
cargo run --release
```
## Configuration
### Config File (config.toml)
```toml
[Config]
internal_timestamp = 100 # Internal timing in milliseconds
ui_refresh_time = 2 # UI refresh interval in seconds
default_wakeup_time = 30 # Default scheduler wake-up time in seconds
max_concurrency = 4 # Maximum concurrent backup workers
max_file_operations = 100 # Maximum concurrent file operations
```
## Screenshots
### Main Interface
![Main Interface](.github/images/main-interface.png)
*The main execution management interface showing backup tasks, progress tracking, and control options.*
## Usage
1. Launch the MirrorSphere application
2. In the main interface, click "New Backup Task"
3. Select source and destination directories
4. Configure backup options (thread count, enable incremental backup, etc.)
5. Click "Start Backup" button to begin the backup process
### GUI Interface
## Supported Platforms
1. **Executions Tab**: Manage manual backup tasks
- Create new backup executions
- Monitor progress in real-time
- Start, pause, resume, or cancel operations
- View detailed error logs
- **Windows**: Full support, including NTFS-specific features
- **Linux**: Full support for basic backup functionality
2. **Schedules Tab**: Manage automated backups
- Create scheduled backup tasks
- Set intervals (Once, Daily, Weekly, Monthly)
- Enable, pause, or disable schedules
- View execution history and next run times
## Technical Details
### Backup Options
### Parallel Backup Algorithm
- **Mirror Mode**: Remove files from destination that don't exist in source
- **Lock Source**: Lock source files during backup to prevent modifications
- **Backup Permissions**: Preserve file permissions and attributes
- **Follow Symlinks**: Follow symbolic links instead of copying them
MirrorSphere uses a high-performance parallel processing algorithm that maximizes performance by concurrently traversing directory structures and copying files, especially suitable for large file systems and multi-core processor environments.
### Comparison Modes
### Windows-Specific Features
1. **Standard**: Compare file size and modification time
2. **Advanced**: Standard comparison + file attributes
3. **Thorough**: Advanced comparison + cryptographic hash verification
- **USN Journal Tracking**: Utilize NTFS USN journals to quickly identify file system changes
- **ACL Support**: Preserve and restore Windows NTFS access control lists
- **Extended File Attributes**: Preserve additional file metadata
## Platform Support
## Roadmap
### Windows
- UAC elevation for administrator privileges
- Windows-specific file attributes and permissions
- NTFS symlink support
- Windows API integration for file operations
- [ ] Implement file compression
- [ ] Encrypted backup options
- [ ] Remote backup (SFTP, S3, etc.)
- [ ] Backup scheduling
- [ ] macOS support
### Linux
- Root privilege handling
- POSIX file permissions and attributes
- Unix-style symlink support
- Extended attribute support
## Future Features
The following features are planned for future development as time and interest permits:
### Cloud Storage Integration
- **Multiple Cloud Providers**: Amazon S3, Google Cloud Storage, Azure Blob Storage
- **Cloud Synchronization**: Direct backup to cloud storage with incremental sync
### Advanced File System Features
- **NTFS USN Journal Support**: Real-time change detection on Windows for efficient incremental backups
- **High-Performance I/O**: IOCP (Windows) and io_uring (Linux) support for better async performance
- **File System Monitoring**: Real-time file change notifications to trigger automatic backups
### Platform Expansion
- **macOS Support**: Complete cross-platform coverage with Apple File System (APFS) optimizations
- **Mobile Companion Apps**: iOS/Android apps for monitoring and basic management
### System Integration
- **Operating System Services**: Register as Windows Service, Linux systemd daemon, or macOS Launch Daemon
- **Background Operation**: Run silently in the background without user interaction
- **System Startup**: Automatic startup with the operating system
### Additional Ideas
- Enhanced security with encryption and authentication
*Note: This is a wish list of potential features, not a committed roadmap. Development priorities may change based on personal interest and available time.*
## Support
For issues, questions, or contributions, please use the GitHub issue tracker.

View File

@ -1,61 +0,0 @@
# MirrorSphere
一個用 Rust 開發的高效能、跨平台圖形化檔案備份工具。
## 特色
- 用戶友好的圖形界面
- 高效能平行備份演算法
- 跨平台支援 (Windows, Linux)
- 增量備份能力
- 檔案系統變更追蹤 (Windows NTFS)
- 支援 Windows NTFS ACL
- 保留額外檔案屬性
- 實時備份進度顯示
## 安裝
### 下載安裝程式
請查看 [Releases](https://github.com/DaLaw2/mirrorsphere/releases) 頁面下載最新版本的安裝程式。
### 從原始碼編譯
```bash
git clone https://github.com/DaLaw2/mirrorsphere.git
cd mirrorsphere
cargo build --release
```
## 使用方法
1. 啟動 MirrorSphere 應用程式
2. 在主界面中,點擊「新建備份任務」
3. 選擇源目錄和目標目錄
4. 設定備份選項(線程數量、是否啟用增量備份等)
5. 點擊「開始備份」按鈕開始備份過程
## 支援平台
- **Windows**: 完整支援,包括 NTFS 特定功能
- **Linux**: 完整支援基本備份功能
## 技術細節
### 平行備份演算法
MirrorSphere 使用高效能的平行處理演算法,通過並行遍歷目錄結構和檔案複製來最大化效能,特別適用於大型檔案系統和多核心處理器環境。
### Windows 特定功能
- **USN Journal 追蹤**: 利用 NTFS USN 日誌快速識別檔案系統變更
- **ACL 支援**: 保留和還原 Windows NTFS 訪問控制清單
- **擴展檔案屬性**: 保留檔案的額外元數據
## 路線圖
- [ ] 實現檔案壓縮
- [ ] 加密備份選項
- [ ] 遠端備份 (SFTP, S3 等)
- [ ] 備份排程
- [ ] macOS 支援

BIN
assets/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

15
build.rs Normal file
View File

@ -0,0 +1,15 @@
#[cfg(target_os = "windows")]
fn main() {
let mut res = winres::WindowsResource::new();
res.set_icon("assets/icon.ico")
.set("InternalName", "MirrorSphere.exe")
.set_version_info(winres::VersionInfo::PRODUCTVERSION, 0x0001000000000000)
.set_language(0x0409);
if let Err(e) = res.compile() {
eprintln!("winres error: {}", e);
}
}
#[cfg(target_os = "linux")]
fn main() {
}

View File

@ -7,6 +7,7 @@ use crate::ui::main_page::MainPage;
use eframe::egui;
use std::sync::Arc;
use crate::core::app_config::AppConfig;
use crate::utils::assets::Assets;
pub struct GuiManager {
app_config: Arc<AppConfig>,
@ -36,10 +37,13 @@ impl GuiManager {
let backup_engine = self.backup_engine.clone();
let schedule_manager = self.schedule_manager.clone();
let icon_data = Assets::load_app_icon()?;
let options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default()
.with_inner_size([1200.0, 800.0])
.with_title("MirrorSphere"),
.with_inner_size([800.0, 450.0])
.with_title("MirrorSphere")
.with_icon(icon_data),
..Default::default()
};

View File

@ -1,3 +1,5 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
use crate::core::system::System;
mod core;

View File

@ -13,5 +13,9 @@ traceable! {
#[error("Failed to initialize UI platform")]
UIPlatformError => tracing::Level::ERROR,
#[no_source]
#[error("Assert file not found")]
AssertFileNotFound => tracing::Level::ERROR,
}
}

View File

@ -1,15 +1,19 @@
use crate::model::error::Error;
use crate::model::error::system::SystemError;
use std::process::Command;
use std::{env, io};
pub fn elevate() -> io::Result<()> {
let exe = env::current_exe()?;
pub fn elevate() -> Result<(), Error> {
let exe = env::current_exe()
.map_err(|_| SystemError::RunAsAdminFailed)?;
let args: Vec<String> = env::args().skip(1).collect();
Command::new("sudo")
.arg("--")
.arg(exe)
.args(&args)
.status()?;
.status()
.map_err(|_| SystemError::RunAsAdminFailed)?;
Ok(())
}

28
src/utils/assets.rs Normal file
View File

@ -0,0 +1,28 @@
use crate::model::error::Error;
use crate::model::error::misc::MiscError;
use eframe::egui::IconData;
use rust_embed::RustEmbed;
#[derive(RustEmbed)]
#[folder = "assets/"]
pub struct Assets;
impl Assets {
pub fn load_app_icon() -> Result<IconData, Error> {
let icon_bytes = Assets::get("icon.ico")
.ok_or(MiscError::AssertFileNotFound)?;
let image = image::load_from_memory(&icon_bytes.data)
.map_err(MiscError::DeserializeError)?
.to_rgba8();
let (width, height) = image.dimensions();
let rgba = image.into_raw();
Ok(IconData {
rgba,
width,
height,
})
}
}

View File

@ -1,3 +1,4 @@
pub mod assets;
pub mod database_lock;
pub mod file_hash;
pub mod file_lock;