atproto repo as vfs

should work on wasm now hopefully

ptr.pet b85225eb faba3f07

verified
+161 -601
+4 -449
Cargo.lock
··· 58 58 checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" 59 59 60 60 [[package]] 61 - name = "async-channel" 62 - version = "1.9.0" 63 - source = "registry+https://github.com/rust-lang/crates.io-index" 64 - checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" 65 - dependencies = [ 66 - "concurrent-queue", 67 - "event-listener 2.5.3", 68 - "futures-core", 69 - ] 70 - 71 - [[package]] 72 - name = "async-channel" 73 - version = "2.5.0" 74 - source = "registry+https://github.com/rust-lang/crates.io-index" 75 - checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" 76 - dependencies = [ 77 - "concurrent-queue", 78 - "event-listener-strategy", 79 - "futures-core", 80 - "pin-project-lite", 81 - ] 82 - 83 - [[package]] 84 61 name = "async-compression" 85 62 version = "0.4.36" 86 63 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 94 71 ] 95 72 96 73 [[package]] 97 - name = "async-executor" 98 - version = "1.13.3" 99 - source = "registry+https://github.com/rust-lang/crates.io-index" 100 - checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8" 101 - dependencies = [ 102 - "async-task", 103 - "concurrent-queue", 104 - "fastrand", 105 - "futures-lite", 106 - "pin-project-lite", 107 - "slab", 108 - ] 109 - 110 - [[package]] 111 - name = "async-global-executor" 112 - version = "2.4.1" 113 - source = "registry+https://github.com/rust-lang/crates.io-index" 114 - checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" 115 - dependencies = [ 116 - "async-channel 2.5.0", 117 - "async-executor", 118 - "async-io", 119 - "async-lock", 120 - "blocking", 121 - "futures-lite", 122 - "once_cell", 123 - ] 124 - 125 - [[package]] 126 - name = "async-io" 127 - version = "2.6.0" 128 - source = "registry+https://github.com/rust-lang/crates.io-index" 129 - checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" 130 - dependencies = [ 131 - "autocfg", 132 - "cfg-if", 133 - "concurrent-queue", 134 - "futures-io", 135 - "futures-lite", 136 - "parking", 137 - "polling", 138 - "rustix", 139 - "slab", 140 - "windows-sys 0.61.2", 141 - ] 142 - 143 - [[package]] 144 - name = "async-lock" 145 - version = "3.4.1" 146 - source = "registry+https://github.com/rust-lang/crates.io-index" 147 - checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" 148 - dependencies = [ 149 - "event-listener 5.4.1", 150 - "event-listener-strategy", 151 - "pin-project-lite", 152 - ] 153 - 154 - [[package]] 155 - name = "async-recursion" 156 - version = "1.1.1" 157 - source = "registry+https://github.com/rust-lang/crates.io-index" 158 - checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" 159 - dependencies = [ 160 - "proc-macro2", 161 - "quote", 162 - "syn 2.0.111", 163 - ] 164 - 165 - [[package]] 166 - name = "async-std" 167 - version = "1.13.2" 168 - source = "registry+https://github.com/rust-lang/crates.io-index" 169 - checksum = "2c8e079a4ab67ae52b7403632e4618815d6db36d2a010cfe41b02c1b1578f93b" 170 - dependencies = [ 171 - "async-channel 1.9.0", 172 - "async-global-executor", 173 - "async-io", 174 - "async-lock", 175 - "crossbeam-utils", 176 - "futures-channel", 177 - "futures-core", 178 - "futures-io", 179 - "futures-lite", 180 - "gloo-timers", 181 - "kv-log-macro", 182 - "log", 183 - "memchr", 184 - "once_cell", 185 - "pin-project-lite", 186 - "pin-utils", 187 - "slab", 188 - "wasm-bindgen-futures", 189 - ] 190 - 191 - [[package]] 192 - name = "async-task" 193 - version = "4.7.1" 194 - source = "registry+https://github.com/rust-lang/crates.io-index" 195 - checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" 196 - 197 - [[package]] 198 74 name = "async-trait" 199 75 version = "0.1.89" 200 76 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 292 168 checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 293 169 dependencies = [ 294 170 "generic-array", 295 - ] 296 - 297 - [[package]] 298 - name = "blocking" 299 - version = "1.6.2" 300 - source = "registry+https://github.com/rust-lang/crates.io-index" 301 - checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" 302 - dependencies = [ 303 - "async-channel 2.5.0", 304 - "async-task", 305 - "futures-io", 306 - "futures-lite", 307 - "piper", 308 171 ] 309 172 310 173 [[package]] ··· 528 391 checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d" 529 392 530 393 [[package]] 531 - name = "concurrent-queue" 532 - version = "2.5.0" 533 - source = "registry+https://github.com/rust-lang/crates.io-index" 534 - checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" 535 - dependencies = [ 536 - "crossbeam-utils", 537 - ] 538 - 539 - [[package]] 540 394 name = "const-oid" 541 395 version = "0.9.6" 542 396 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 871 725 ] 872 726 873 727 [[package]] 874 - name = "enum-as-inner" 875 - version = "0.6.1" 876 - source = "registry+https://github.com/rust-lang/crates.io-index" 877 - checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" 878 - dependencies = [ 879 - "heck 0.5.0", 880 - "proc-macro2", 881 - "quote", 882 - "syn 2.0.111", 883 - ] 884 - 885 - [[package]] 886 728 name = "equivalent" 887 729 version = "1.0.2" 888 730 source = "registry+https://github.com/rust-lang/crates.io-index" 889 731 checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" 890 732 891 733 [[package]] 892 - name = "errno" 893 - version = "0.3.14" 894 - source = "registry+https://github.com/rust-lang/crates.io-index" 895 - checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" 896 - dependencies = [ 897 - "libc", 898 - "windows-sys 0.61.2", 899 - ] 900 - 901 - [[package]] 902 - name = "event-listener" 903 - version = "2.5.3" 904 - source = "registry+https://github.com/rust-lang/crates.io-index" 905 - checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" 906 - 907 - [[package]] 908 - name = "event-listener" 909 - version = "5.4.1" 910 - source = "registry+https://github.com/rust-lang/crates.io-index" 911 - checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" 912 - dependencies = [ 913 - "concurrent-queue", 914 - "parking", 915 - "pin-project-lite", 916 - ] 917 - 918 - [[package]] 919 - name = "event-listener-strategy" 920 - version = "0.5.4" 921 - source = "registry+https://github.com/rust-lang/crates.io-index" 922 - checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" 923 - dependencies = [ 924 - "event-listener 5.4.1", 925 - "pin-project-lite", 926 - ] 927 - 928 - [[package]] 929 734 name = "fastrand" 930 735 version = "2.3.0" 931 736 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1192 997 ] 1193 998 1194 999 [[package]] 1195 - name = "gloo-timers" 1196 - version = "0.3.0" 1197 - source = "registry+https://github.com/rust-lang/crates.io-index" 1198 - checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" 1199 - dependencies = [ 1200 - "futures-channel", 1201 - "futures-core", 1202 - "js-sys", 1203 - "wasm-bindgen", 1204 - ] 1205 - 1206 - [[package]] 1207 1000 name = "gloo-utils" 1208 1001 version = "0.2.0" 1209 1002 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1329 1122 checksum = "b07f60793ff0a4d9cef0f18e63b5357e06209987153a64648c972c1e5aff336f" 1330 1123 1331 1124 [[package]] 1332 - name = "hickory-proto" 1333 - version = "0.24.4" 1334 - source = "registry+https://github.com/rust-lang/crates.io-index" 1335 - checksum = "92652067c9ce6f66ce53cc38d1169daa36e6e7eb7dd3b63b5103bd9d97117248" 1336 - dependencies = [ 1337 - "async-trait", 1338 - "cfg-if", 1339 - "data-encoding", 1340 - "enum-as-inner", 1341 - "futures-channel", 1342 - "futures-io", 1343 - "futures-util", 1344 - "idna", 1345 - "ipnet", 1346 - "once_cell", 1347 - "rand 0.8.5", 1348 - "thiserror 1.0.69", 1349 - "tinyvec", 1350 - "tokio", 1351 - "tracing", 1352 - "url", 1353 - ] 1354 - 1355 - [[package]] 1356 - name = "hickory-resolver" 1357 - version = "0.24.4" 1358 - source = "registry+https://github.com/rust-lang/crates.io-index" 1359 - checksum = "cbb117a1ca520e111743ab2f6688eddee69db4e0ea242545a604dce8a66fd22e" 1360 - dependencies = [ 1361 - "cfg-if", 1362 - "futures-util", 1363 - "hickory-proto", 1364 - "ipconfig", 1365 - "lru-cache", 1366 - "once_cell", 1367 - "parking_lot", 1368 - "rand 0.8.5", 1369 - "resolv-conf", 1370 - "smallvec", 1371 - "thiserror 1.0.69", 1372 - "tokio", 1373 - "tracing", 1374 - ] 1375 - 1376 - [[package]] 1377 1125 name = "hmac" 1378 1126 version = "0.12.1" 1379 1127 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1492 1240 "libc", 1493 1241 "percent-encoding", 1494 1242 "pin-project-lite", 1495 - "socket2 0.6.1", 1243 + "socket2", 1496 1244 "system-configuration", 1497 1245 "tokio", 1498 1246 "tower-service", ··· 1674 1422 ] 1675 1423 1676 1424 [[package]] 1677 - name = "ipconfig" 1678 - version = "0.3.2" 1679 - source = "registry+https://github.com/rust-lang/crates.io-index" 1680 - checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" 1681 - dependencies = [ 1682 - "socket2 0.5.10", 1683 - "widestring", 1684 - "windows-sys 0.48.0", 1685 - "winreg", 1686 - ] 1687 - 1688 - [[package]] 1689 1425 name = "ipld-core" 1690 1426 version = "0.4.2" 1691 1427 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1827 1563 dependencies = [ 1828 1564 "bon", 1829 1565 "bytes", 1830 - "hickory-resolver", 1831 1566 "http", 1832 1567 "jacquard-api", 1833 1568 "jacquard-common", ··· 1963 1698 ] 1964 1699 1965 1700 [[package]] 1966 - name = "kv-log-macro" 1967 - version = "1.0.7" 1968 - source = "registry+https://github.com/rust-lang/crates.io-index" 1969 - checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" 1970 - dependencies = [ 1971 - "log", 1972 - ] 1973 - 1974 - [[package]] 1975 1701 name = "langtag" 1976 1702 version = "0.4.0" 1977 1703 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2015 1741 ] 2016 1742 2017 1743 [[package]] 2018 - name = "linked-hash-map" 2019 - version = "0.5.6" 2020 - source = "registry+https://github.com/rust-lang/crates.io-index" 2021 - checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" 2022 - 2023 - [[package]] 2024 - name = "linux-raw-sys" 2025 - version = "0.11.0" 2026 - source = "registry+https://github.com/rust-lang/crates.io-index" 2027 - checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" 2028 - 2029 - [[package]] 2030 1744 name = "litemap" 2031 1745 version = "0.8.1" 2032 1746 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2046 1760 version = "0.4.29" 2047 1761 source = "registry+https://github.com/rust-lang/crates.io-index" 2048 1762 checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" 2049 - dependencies = [ 2050 - "value-bag", 2051 - ] 2052 1763 2053 1764 [[package]] 2054 1765 name = "loom" ··· 2061 1772 "scoped-tls", 2062 1773 "tracing", 2063 1774 "tracing-subscriber", 2064 - ] 2065 - 2066 - [[package]] 2067 - name = "lru-cache" 2068 - version = "0.1.2" 2069 - source = "registry+https://github.com/rust-lang/crates.io-index" 2070 - checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" 2071 - dependencies = [ 2072 - "linked-hash-map", 2073 1775 ] 2074 1776 2075 1777 [[package]] ··· 2525 2227 checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 2526 2228 2527 2229 [[package]] 2528 - name = "piper" 2529 - version = "0.2.4" 2530 - source = "registry+https://github.com/rust-lang/crates.io-index" 2531 - checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" 2532 - dependencies = [ 2533 - "atomic-waker", 2534 - "fastrand", 2535 - "futures-io", 2536 - ] 2537 - 2538 - [[package]] 2539 2230 name = "pkcs1" 2540 2231 version = "0.7.5" 2541 2232 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2557 2248 ] 2558 2249 2559 2250 [[package]] 2560 - name = "polling" 2561 - version = "3.11.0" 2562 - source = "registry+https://github.com/rust-lang/crates.io-index" 2563 - checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" 2564 - dependencies = [ 2565 - "cfg-if", 2566 - "concurrent-queue", 2567 - "hermit-abi", 2568 - "pin-project-lite", 2569 - "rustix", 2570 - "windows-sys 0.61.2", 2571 - ] 2572 - 2573 - [[package]] 2574 2251 name = "postcard" 2575 2252 version = "1.1.3" 2576 2253 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2691 2368 "quinn-udp", 2692 2369 "rustc-hash", 2693 2370 "rustls", 2694 - "socket2 0.6.1", 2371 + "socket2", 2695 2372 "thiserror 2.0.17", 2696 2373 "tokio", 2697 2374 "tracing", ··· 2728 2405 "cfg_aliases", 2729 2406 "libc", 2730 2407 "once_cell", 2731 - "socket2 0.6.1", 2408 + "socket2", 2732 2409 "tracing", 2733 2410 "windows-sys 0.60.2", 2734 2411 ] ··· 2919 2596 ] 2920 2597 2921 2598 [[package]] 2922 - name = "resolv-conf" 2923 - version = "0.7.6" 2924 - source = "registry+https://github.com/rust-lang/crates.io-index" 2925 - checksum = "1e061d1b48cb8d38042de4ae0a7a6401009d6143dc80d2e2d6f31f0bdd6470c7" 2926 - 2927 - [[package]] 2928 2599 name = "rfc6979" 2929 2600 version = "0.4.0" 2930 2601 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2984 2655 ] 2985 2656 2986 2657 [[package]] 2987 - name = "rustix" 2988 - version = "1.1.2" 2989 - source = "registry+https://github.com/rust-lang/crates.io-index" 2990 - checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" 2991 - dependencies = [ 2992 - "bitflags", 2993 - "errno", 2994 - "libc", 2995 - "linux-raw-sys", 2996 - "windows-sys 0.61.2", 2997 - ] 2998 - 2999 - [[package]] 3000 2658 name = "rustls" 3001 2659 version = "0.23.35" 3002 2660 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3333 2991 3334 2992 [[package]] 3335 2993 name = "socket2" 3336 - version = "0.5.10" 3337 - source = "registry+https://github.com/rust-lang/crates.io-index" 3338 - checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" 3339 - dependencies = [ 3340 - "libc", 3341 - "windows-sys 0.52.0", 3342 - ] 3343 - 3344 - [[package]] 3345 - name = "socket2" 3346 2994 version = "0.6.1" 3347 2995 source = "registry+https://github.com/rust-lang/crates.io-index" 3348 2996 checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" ··· 3651 3299 "parking_lot", 3652 3300 "pin-project-lite", 3653 3301 "signal-hook-registry", 3654 - "socket2 0.6.1", 3302 + "socket2", 3655 3303 "tokio-macros", 3656 3304 "windows-sys 0.61.2", 3657 3305 ] ··· 3904 3552 checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" 3905 3553 3906 3554 [[package]] 3907 - name = "value-bag" 3908 - version = "1.12.0" 3909 - source = "registry+https://github.com/rust-lang/crates.io-index" 3910 - checksum = "7ba6f5989077681266825251a52748b8c1d8a4ad098cc37e440103d0ea717fc0" 3911 - 3912 - [[package]] 3913 3555 name = "version_check" 3914 3556 version = "0.9.5" 3915 3557 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3921 3563 source = "registry+https://github.com/rust-lang/crates.io-index" 3922 3564 checksum = "9e723b9e1c02a3cf9f9d0de6a4ddb8cdc1df859078902fe0ae0589d615711ae6" 3923 3565 dependencies = [ 3924 - "async-recursion", 3925 - "async-std", 3926 - "async-trait", 3927 3566 "filetime", 3928 - "futures", 3929 - "tokio", 3930 3567 ] 3931 3568 3932 3569 [[package]] ··· 4051 3688 dependencies = [ 4052 3689 "rustls-pki-types", 4053 3690 ] 4054 - 4055 - [[package]] 4056 - name = "widestring" 4057 - version = "1.2.1" 4058 - source = "registry+https://github.com/rust-lang/crates.io-index" 4059 - checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" 4060 3691 4061 3692 [[package]] 4062 3693 name = "winapi" ··· 4232 3863 4233 3864 [[package]] 4234 3865 name = "windows-sys" 4235 - version = "0.48.0" 4236 - source = "registry+https://github.com/rust-lang/crates.io-index" 4237 - checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 4238 - dependencies = [ 4239 - "windows-targets 0.48.5", 4240 - ] 4241 - 4242 - [[package]] 4243 - name = "windows-sys" 4244 3866 version = "0.52.0" 4245 3867 source = "registry+https://github.com/rust-lang/crates.io-index" 4246 3868 checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" ··· 4268 3890 4269 3891 [[package]] 4270 3892 name = "windows-targets" 4271 - version = "0.48.5" 4272 - source = "registry+https://github.com/rust-lang/crates.io-index" 4273 - checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 4274 - dependencies = [ 4275 - "windows_aarch64_gnullvm 0.48.5", 4276 - "windows_aarch64_msvc 0.48.5", 4277 - "windows_i686_gnu 0.48.5", 4278 - "windows_i686_msvc 0.48.5", 4279 - "windows_x86_64_gnu 0.48.5", 4280 - "windows_x86_64_gnullvm 0.48.5", 4281 - "windows_x86_64_msvc 0.48.5", 4282 - ] 4283 - 4284 - [[package]] 4285 - name = "windows-targets" 4286 3893 version = "0.52.6" 4287 3894 source = "registry+https://github.com/rust-lang/crates.io-index" 4288 3895 checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" ··· 4325 3932 4326 3933 [[package]] 4327 3934 name = "windows_aarch64_gnullvm" 4328 - version = "0.48.5" 4329 - source = "registry+https://github.com/rust-lang/crates.io-index" 4330 - checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 4331 - 4332 - [[package]] 4333 - name = "windows_aarch64_gnullvm" 4334 3935 version = "0.52.6" 4335 3936 source = "registry+https://github.com/rust-lang/crates.io-index" 4336 3937 checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" ··· 4343 3944 4344 3945 [[package]] 4345 3946 name = "windows_aarch64_msvc" 4346 - version = "0.48.5" 4347 - source = "registry+https://github.com/rust-lang/crates.io-index" 4348 - checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 4349 - 4350 - [[package]] 4351 - name = "windows_aarch64_msvc" 4352 3947 version = "0.52.6" 4353 3948 source = "registry+https://github.com/rust-lang/crates.io-index" 4354 3949 checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" ··· 4358 3953 version = "0.53.1" 4359 3954 source = "registry+https://github.com/rust-lang/crates.io-index" 4360 3955 checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" 4361 - 4362 - [[package]] 4363 - name = "windows_i686_gnu" 4364 - version = "0.48.5" 4365 - source = "registry+https://github.com/rust-lang/crates.io-index" 4366 - checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 4367 3956 4368 3957 [[package]] 4369 3958 name = "windows_i686_gnu" ··· 4388 3977 version = "0.53.1" 4389 3978 source = "registry+https://github.com/rust-lang/crates.io-index" 4390 3979 checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" 4391 - 4392 - [[package]] 4393 - name = "windows_i686_msvc" 4394 - version = "0.48.5" 4395 - source = "registry+https://github.com/rust-lang/crates.io-index" 4396 - checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 4397 3980 4398 3981 [[package]] 4399 3982 name = "windows_i686_msvc" ··· 4409 3992 4410 3993 [[package]] 4411 3994 name = "windows_x86_64_gnu" 4412 - version = "0.48.5" 4413 - source = "registry+https://github.com/rust-lang/crates.io-index" 4414 - checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 4415 - 4416 - [[package]] 4417 - name = "windows_x86_64_gnu" 4418 3995 version = "0.52.6" 4419 3996 source = "registry+https://github.com/rust-lang/crates.io-index" 4420 3997 checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" ··· 4427 4004 4428 4005 [[package]] 4429 4006 name = "windows_x86_64_gnullvm" 4430 - version = "0.48.5" 4431 - source = "registry+https://github.com/rust-lang/crates.io-index" 4432 - checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 4433 - 4434 - [[package]] 4435 - name = "windows_x86_64_gnullvm" 4436 4007 version = "0.52.6" 4437 4008 source = "registry+https://github.com/rust-lang/crates.io-index" 4438 4009 checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" ··· 4445 4016 4446 4017 [[package]] 4447 4018 name = "windows_x86_64_msvc" 4448 - version = "0.48.5" 4449 - source = "registry+https://github.com/rust-lang/crates.io-index" 4450 - checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 4451 - 4452 - [[package]] 4453 - name = "windows_x86_64_msvc" 4454 4019 version = "0.52.6" 4455 4020 source = "registry+https://github.com/rust-lang/crates.io-index" 4456 4021 checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" ··· 4460 4025 version = "0.53.1" 4461 4026 source = "registry+https://github.com/rust-lang/crates.io-index" 4462 4027 checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" 4463 - 4464 - [[package]] 4465 - name = "winreg" 4466 - version = "0.50.0" 4467 - source = "registry+https://github.com/rust-lang/crates.io-index" 4468 - checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" 4469 - dependencies = [ 4470 - "cfg-if", 4471 - "windows-sys 0.48.0", 4472 - ] 4473 4028 4474 4029 [[package]] 4475 4030 name = "wit-bindgen"
+5 -3
Cargo.toml
··· 4 4 edition = "2021" 5 5 6 6 [dependencies] 7 - vfs = { version = "0.12", features = ["async-vfs"] } 7 + vfs = { version = "0.12" } 8 8 bpaf = { version = "0.9", features = ["derive"] } 9 9 anyhow = "1.0" 10 10 scc = "2.1" 11 11 url = "2.5" 12 - tokio = { version = "1.0", features = ["full"] } 13 12 futures = "0.3" 14 13 async-trait = "0.1" 15 14 serde = { version = "1.0", features = ["derive"] } 16 15 serde_json = "1.0" 17 - jacquard = { git = "https://tangled.org/nonbinary.computer/jacquard", default-features = false, features = ["api", "cache", "dns"] } 16 + jacquard = { git = "https://tangled.org/nonbinary.computer/jacquard", default-features = false, features = ["api", "cache"] } 17 + 18 + [target.'cfg(not(target_arch = "wasm32"))'.dependencies] 19 + tokio = { version = "1.0", features = ["full"] } 18 20 19 21 [target.'cfg(target_os = "linux")'.dependencies] 20 22 easy_fuser = { version = "0.4", features = ["parallel"] }
+21 -31
src/fuse.rs
··· 1 1 use super::*; 2 2 use easy_fuser::{prelude::*, templates::DefaultFuseHandler}; 3 - use futures::StreamExt; 4 - use tokio::runtime::Handle; 5 3 6 4 use std::{ 7 5 ffi::{OsStr, OsString}, 6 + io::{Read, Seek, SeekFrom}, 8 7 path::PathBuf, 9 8 time::UNIX_EPOCH, 10 9 }; ··· 12 11 pub struct AtpFuse { 13 12 pub fs: Arc<AtpFS>, 14 13 pub inner: DefaultFuseHandler, 15 - pub rt: Handle, 16 14 } 17 15 18 16 impl AtpFuse { ··· 47 45 48 46 fn vfs_metadata_attr(&self, vfs_path: &str) -> FuseResult<FileAttribute> { 49 47 let meta = self 50 - .rt 51 - .block_on(self.fs.metadata(vfs_path)) 48 + .fs 49 + .metadata(vfs_path) 52 50 .map_err(|_| ErrorKind::FileNotFound.to_error("Not found"))?; 53 51 54 52 let (kind, perm, nlink) = match meta.file_type { ··· 116 114 ) -> FuseResult<Vec<(OsString, FileKind)>> { 117 115 let vfs_path = self.path_to_str(&file_id); 118 116 119 - let mut stream = self 120 - .rt 121 - .block_on(self.fs.read_dir(&vfs_path)) 117 + let stream = self 118 + .fs 119 + .read_dir(&vfs_path) 122 120 .map_err(|_| ErrorKind::InputOutputError.to_error("Read dir failed"))?; 123 121 124 122 let mut entries = vec![ ··· 126 124 (OsString::from(".."), FileKind::Directory), 127 125 ]; 128 126 129 - while let Some(name) = self.rt.block_on(stream.next()) { 127 + for name in stream { 130 128 let kind = name 131 129 .ends_with(".json") 132 130 .then_some(FileKind::RegularFile) ··· 149 147 ) -> FuseResult<Vec<u8>> { 150 148 let vfs_path = self.path_to_str(&file_id); 151 149 let mut reader = self 152 - .rt 153 - .block_on(self.fs.open_file(&vfs_path)) 150 + .fs 151 + .open_file(&vfs_path) 154 152 .map_err(|_| ErrorKind::FileNotFound.to_error("File not found"))?; 155 153 156 154 // Only support absolute start seeks for now. ··· 165 163 return Ok(Vec::new()); 166 164 } 167 165 168 - // Read directly into a buffer of the requested size without loading the whole file. 166 + // Seek to the requested position. 167 + reader 168 + .seek(SeekFrom::Start(pos)) 169 + .map_err(|_| ErrorKind::InputOutputError.to_error("Seek failed"))?; 170 + 171 + // Read up to `size` bytes into the buffer. 172 + // We use take to limit the read, then read_to_end or just read into buffer. 169 173 let mut buf = vec![0u8; size as usize]; 174 + let n = reader 175 + .read(&mut buf) 176 + .map_err(|_| ErrorKind::InputOutputError.to_error("Read failed"))?; 170 177 171 - // Use the async seek/read methods on the underlying reader via the runtime. 172 - use futures::{AsyncReadExt, AsyncSeekExt}; 173 - self.rt 174 - .block_on(async { 175 - // Seek to the requested position. 176 - reader 177 - .seek(std::io::SeekFrom::Start(pos)) 178 - .await 179 - .map_err(|_| ())?; 180 - // Read up to `size` bytes into the buffer. 181 - let n = reader.read(&mut buf).await.map_err(|_| ())?; 182 - Ok::<usize, ()>(n) 183 - }) 184 - .map_err(|_| ErrorKind::InputOutputError.to_error("Read failed")) 185 - .and_then(|n| { 186 - // Truncate to actual read length and return. 187 - buf.truncate(n); 188 - Ok(buf) 189 - }) 178 + buf.truncate(n); 179 + Ok(buf) 190 180 } 191 181 }
+127 -111
src/lib.rs
··· 1 1 use anyhow::{anyhow, Result}; 2 - use futures::stream; 2 + #[cfg(target_arch = "wasm32")] 3 + use futures::executor::block_on; 3 4 use jacquard::{ 4 5 api::com_atproto::repo::{describe_repo::DescribeRepo, list_records::ListRecords}, 5 6 client::{credential_session::CredentialSession, Agent, BasicClient, MemorySessionStore}, ··· 9 10 }; 10 11 use scc::{HashMap, HashSet}; 11 12 use url::Url; 12 - use vfs::{ 13 - async_vfs::{AsyncFileSystem, SeekAndRead}, 14 - error::VfsErrorKind, 15 - VfsFileType, VfsMetadata, VfsResult, 16 - }; 13 + use vfs::{error::VfsErrorKind, FileSystem, SeekAndRead, VfsFileType, VfsMetadata, VfsResult}; 17 14 18 15 use std::{collections::HashMap as StdHashMap, fmt::Debug, sync::Arc}; 19 16 ··· 55 52 client: BasicClient, 56 53 cache: HashMap<String, Arc<CachedPage>>, 57 54 root_cache: HashSet<String>, 55 + #[cfg(not(target_arch = "wasm32"))] 56 + handle: tokio::runtime::Handle, 58 57 } 59 58 60 59 impl Debug for AtpFS { ··· 64 63 } 65 64 66 65 impl AtpFS { 67 - pub async fn new(did: Did<'static>, pds: Url) -> Self { 66 + pub fn new(did: Did<'static>, pds: Url) -> Self { 67 + #[cfg(not(target_arch = "wasm32"))] 68 + let handle = tokio::runtime::Handle::current(); 69 + 68 70 let store = MemorySessionStore::default(); 69 71 let session = 70 72 CredentialSession::new(Arc::new(store), Arc::new(slingshot_resolver_default())); 71 - session.set_endpoint(pds).await; 73 + 74 + #[cfg(not(target_arch = "wasm32"))] 75 + tokio::task::block_in_place(|| handle.block_on(session.set_endpoint(pds))); 76 + 77 + #[cfg(target_arch = "wasm32")] 78 + block_on(session.set_endpoint(pds)); 79 + 72 80 Self { 73 81 did, 74 82 client: Agent::new(session), 75 83 cache: HashMap::default(), 76 84 root_cache: HashSet::default(), 85 + #[cfg(not(target_arch = "wasm32"))] 86 + handle, 77 87 } 88 + } 89 + 90 + #[cfg(not(target_arch = "wasm32"))] 91 + fn block_on<F: std::future::Future>(&self, future: F) -> F::Output { 92 + tokio::task::block_in_place(move || self.handle.block_on(future)) 93 + } 94 + 95 + #[cfg(target_arch = "wasm32")] 96 + fn block_on<F: std::future::Future>(&self, future: F) -> F::Output { 97 + block_on(future) 78 98 } 79 99 80 100 fn segments<'a, 's>(&'s self, path: &'a str) -> Vec<&'a str> { ··· 216 236 } 217 237 } 218 238 219 - #[async_trait::async_trait] 220 - impl AsyncFileSystem for AtpFS { 221 - async fn read_dir( 222 - &self, 223 - path: &str, 224 - ) -> VfsResult<Box<dyn Unpin + futures::Stream<Item = String> + Send>> { 225 - let segs = self.segments(path); 239 + impl FileSystem for AtpFS { 240 + fn read_dir(&self, path: &str) -> VfsResult<Box<dyn Iterator<Item = String> + Send>> { 241 + self.block_on(async { 242 + let segs = self.segments(path); 226 243 227 - if segs.is_empty() { 228 - self.ensure_root_loaded().await?; 229 - let mut keys = Vec::new(); 230 - self.root_cache.scan(|k| keys.push(k.clone())); 231 - return Ok(Box::new(stream::iter(keys))); 232 - } 244 + if segs.is_empty() { 245 + self.ensure_root_loaded().await?; 246 + let mut keys = Vec::new(); 247 + self.root_cache.scan(|k| keys.push(k.clone())); 248 + return Ok(Box::new(keys.into_iter()) as Box<dyn Iterator<Item = String> + Send>); 249 + } 233 250 234 - let cache_key = self.ensure_loaded(path).await?; 251 + let cache_key = self.ensure_loaded(path).await?; 235 252 236 - if path.ends_with(".json") { 237 - return Err(VfsErrorKind::Other("not a directory".into()).into()); 238 - } 253 + if path.ends_with(".json") { 254 + return Err(VfsErrorKind::Other("not a directory".into()).into()); 255 + } 239 256 240 - let page = self 241 - .cache 242 - .read(&cache_key, |_, v| v.clone()) 243 - .ok_or(VfsErrorKind::FileNotFound)?; 257 + let page = self 258 + .cache 259 + .read(&cache_key, |_, v| v.clone()) 260 + .ok_or(VfsErrorKind::FileNotFound)?; 244 261 245 - let mut entries: Vec<String> = page.files.keys().cloned().collect(); 246 - if page.next_cursor.is_some() { 247 - entries.push("next".to_string()); 248 - } 262 + let mut entries: Vec<String> = page.files.keys().cloned().collect(); 263 + if page.next_cursor.is_some() { 264 + entries.push("next".to_string()); 265 + } 249 266 250 - Ok(Box::new(stream::iter(entries))) 267 + Ok(Box::new(entries.into_iter()) as Box<dyn Iterator<Item = String> + Send>) 268 + }) 251 269 } 252 270 253 - async fn create_dir(&self, _path: &str) -> VfsResult<()> { 271 + fn create_dir(&self, _path: &str) -> VfsResult<()> { 254 272 Err(VfsErrorKind::NotSupported.into()) 255 273 } 256 274 257 - async fn open_file(&self, path: &str) -> VfsResult<Box<dyn SeekAndRead + Send + Unpin>> { 258 - let parent_path = std::path::Path::new(path) 259 - .parent() 260 - .unwrap_or(std::path::Path::new("")) 261 - .to_str() 262 - .unwrap(); 263 - let cache_key = self.ensure_loaded(parent_path).await?; 264 - let filename = path.split('/').last().ok_or(VfsErrorKind::FileNotFound)?; 275 + fn open_file(&self, path: &str) -> VfsResult<Box<dyn SeekAndRead + Send>> { 276 + self.block_on(async { 277 + let parent_path = std::path::Path::new(path) 278 + .parent() 279 + .unwrap_or(std::path::Path::new("")) 280 + .to_str() 281 + .unwrap(); 282 + let cache_key = self.ensure_loaded(parent_path).await?; 283 + let filename = path.split('/').last().ok_or(VfsErrorKind::FileNotFound)?; 265 284 266 - let content = self 267 - .cache 268 - .read(&cache_key, |_, page| page.files.get(filename).cloned()) 269 - .flatten(); 270 - 271 - if let Some(data) = content { 272 - return Ok(Box::new(futures::io::Cursor::new(data))); 273 - } 274 - 275 - Err(VfsErrorKind::FileNotFound.into()) 276 - } 285 + let content = self 286 + .cache 287 + .read(&cache_key, |_, page| page.files.get(filename).cloned()) 288 + .flatten(); 277 289 278 - async fn create_file( 279 - &self, 280 - _path: &str, 281 - ) -> VfsResult<Box<dyn futures::io::AsyncWrite + Send + Unpin>> { 282 - Err(VfsErrorKind::NotSupported.into()) 283 - } 290 + if let Some(data) = content { 291 + return Ok(Box::new(std::io::Cursor::new(data)) as Box<dyn SeekAndRead + Send>); 292 + } 284 293 285 - async fn append_file( 286 - &self, 287 - _path: &str, 288 - ) -> VfsResult<Box<dyn futures::io::AsyncWrite + Send + Unpin>> { 289 - Err(VfsErrorKind::NotSupported.into()) 294 + Err(VfsErrorKind::FileNotFound.into()) 295 + }) 290 296 } 291 297 292 - async fn metadata(&self, path: &str) -> VfsResult<VfsMetadata> { 293 - let segs = self.segments(path); 294 - if segs.is_empty() { 295 - return Ok(AtpFS::vfs_dir_metadata()); 296 - } 297 - 298 - if segs.len() == 1 { 299 - self.ensure_root_loaded().await?; 300 - if self.root_cache.contains(segs[0]) { 298 + fn metadata(&self, path: &str) -> VfsResult<VfsMetadata> { 299 + self.block_on(async { 300 + let segs = self.segments(path); 301 + if segs.is_empty() { 301 302 return Ok(AtpFS::vfs_dir_metadata()); 302 - } else { 303 - return Err(VfsErrorKind::FileNotFound.into()); 304 303 } 305 - } 306 304 307 - if let Some(last) = segs.last() { 308 - if *last == "next" { 309 - let parent = &path[0..path.len() - 5]; 310 - let cache_key = self.ensure_loaded(parent).await?; 311 - let has_next = self 312 - .cache 313 - .read(&cache_key, |_, v| v.next_cursor.is_some()) 314 - .unwrap_or(false); 315 - if has_next { 305 + if segs.len() == 1 { 306 + self.ensure_root_loaded().await?; 307 + if self.root_cache.contains(segs[0]) { 316 308 return Ok(AtpFS::vfs_dir_metadata()); 309 + } else { 310 + return Err(VfsErrorKind::FileNotFound.into()); 317 311 } 318 - return Err(VfsErrorKind::FileNotFound.into()); 312 + } 313 + 314 + if let Some(last) = segs.last() { 315 + if *last == "next" { 316 + let parent = &path[0..path.len() - 5]; 317 + let cache_key = self.ensure_loaded(parent).await?; 318 + let has_next = self 319 + .cache 320 + .read(&cache_key, |_, v| v.next_cursor.is_some()) 321 + .unwrap_or(false); 322 + if has_next { 323 + return Ok(AtpFS::vfs_dir_metadata()); 324 + } 325 + return Err(VfsErrorKind::FileNotFound.into()); 326 + } 319 327 } 320 - } 321 328 322 - if path.ends_with(".json") { 323 - let parent_path = std::path::Path::new(path) 324 - .parent() 325 - .unwrap() 326 - .to_str() 327 - .unwrap(); 328 - let cache_key = self.ensure_loaded(parent_path).await?; 329 - let filename = segs.last().unwrap(); 329 + if path.ends_with(".json") { 330 + let parent_path = std::path::Path::new(path) 331 + .parent() 332 + .unwrap() 333 + .to_str() 334 + .unwrap(); 335 + let cache_key = self.ensure_loaded(parent_path).await?; 336 + let filename = segs.last().unwrap(); 330 337 331 - let len = self 332 - .cache 333 - .read(&cache_key, |_, page| { 334 - page.files.get(*filename).map(|f| f.len()) 335 - }) 336 - .flatten(); 338 + let len = self 339 + .cache 340 + .read(&cache_key, |_, page| { 341 + page.files.get(*filename).map(|f| f.len()) 342 + }) 343 + .flatten(); 337 344 338 - if let Some(l) = len { 339 - return Ok(AtpFS::vfs_file_metadata(l as u64)); 345 + if let Some(l) = len { 346 + return Ok(AtpFS::vfs_file_metadata(l as u64)); 347 + } 348 + return Err(VfsErrorKind::FileNotFound.into()); 340 349 } 341 - return Err(VfsErrorKind::FileNotFound.into()); 342 - } 350 + 351 + Err(VfsErrorKind::FileNotFound.into()) 352 + }) 353 + } 354 + 355 + fn exists(&self, path: &str) -> VfsResult<bool> { 356 + Ok(self.metadata(path).is_ok()) 357 + } 343 358 344 - Err(VfsErrorKind::FileNotFound.into()) 359 + fn create_file(&self, _: &str) -> VfsResult<Box<dyn vfs::SeekAndWrite + Send>> { 360 + Err(VfsErrorKind::NotSupported.into()) 345 361 } 346 362 347 - async fn exists(&self, path: &str) -> VfsResult<bool> { 348 - Ok(self.metadata(path).await.is_ok()) 363 + fn append_file(&self, _: &str) -> VfsResult<Box<dyn vfs::SeekAndWrite + Send>> { 364 + Err(VfsErrorKind::NotSupported.into()) 349 365 } 350 366 351 - async fn remove_file(&self, _path: &str) -> VfsResult<()> { 367 + fn remove_file(&self, _path: &str) -> VfsResult<()> { 352 368 Err(VfsErrorKind::NotSupported.into()) 353 369 } 354 370 355 - async fn remove_dir(&self, _path: &str) -> VfsResult<()> { 371 + fn remove_dir(&self, _path: &str) -> VfsResult<()> { 356 372 Err(VfsErrorKind::NotSupported.into()) 357 373 } 358 374 }
+4 -7
src/main.rs
··· 3 3 cli::{opts, SubCommand}, 4 4 resolve_did, resolve_pds, AtpFS, 5 5 }; 6 - use futures::StreamExt; 7 - use vfs::async_vfs::AsyncFileSystem; 6 + use vfs::FileSystem; 8 7 9 8 use std::sync::Arc; 10 9 ··· 24 23 let pds = resolve_pds(&did).await?; 25 24 println!("resolved PDS: {}", pds); 26 25 27 - let fs = Arc::new(AtpFS::new(did, pds).await); 26 + let fs = Arc::new(AtpFS::new(did, pds)); 28 27 29 28 match opts.cmd { 30 29 SubCommand::Ls { path } => { 31 30 println!("Listing: {}", path); 32 - let mut stream = fs.read_dir(&path).await?; 33 - while let Some(item) = stream.next().await { 31 + let iterator = fs.read_dir(&path)?; 32 + for item in iterator { 34 33 println!("{}", item); 35 34 } 36 35 } ··· 41 40 42 41 let options = vec![MountOption::RO, MountOption::FSName("atproto".to_string())]; 43 42 44 - let rt = tokio::runtime::Handle::current(); 45 43 let fuse_handler = AtpFuse { 46 44 fs, 47 45 inner: DefaultFuseHandler::new(), 48 - rt, 49 46 }; 50 47 51 48 println!("mounting at {:?}...", mount_point);