Apply Rinf version 6

This commit is contained in:
DongHyun Kim 2024-01-24 03:33:41 +09:00
parent aa15908153
commit ff96c3c358
23 changed files with 608 additions and 1085 deletions

View file

@ -27,11 +27,6 @@ jobs:
- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Setup Protobuf compiler
uses: arduino/setup-protoc@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Java toolchain (Only Android target)
uses: actions/setup-java@v3
@ -92,11 +87,6 @@ jobs:
- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Setup Protobuf compiler
uses: arduino/setup-protoc@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install the CLI tool
run: cargo install rinf
@ -147,11 +137,6 @@ jobs:
- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Setup Protobuf compiler
uses: arduino/setup-protoc@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install the CLI tool
run: cargo install rinf
@ -201,11 +186,6 @@ jobs:
# - name: Setup Rust toolchain
# uses: dtolnay/rust-toolchain@stable
# - name: Setup Protobuf compiler
# uses: arduino/setup-protoc@v2
# with:
# repo-token: ${{ secrets.GITHUB_TOKEN }}
# - name: Install the CLI tool
# run: cargo install rinf
@ -261,11 +241,6 @@ jobs:
- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Setup Protobuf compiler
uses: arduino/setup-protoc@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install the CLI tool
run: cargo install rinf
@ -317,11 +292,6 @@ jobs:
- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Setup Protobuf compiler
uses: arduino/setup-protoc@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install the CLI tool
run: cargo install rinf

339
Cargo.lock generated
View file

@ -31,9 +31,9 @@ dependencies = [
[[package]]
name = "allo-isolate"
version = "0.1.20"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f56b7997817c178b853573e8bdfb6c3afe02810b43f17d766d6703560074b0c3"
checksum = "f2f5a5fd28223e6f3cafb7d9cd685f51eafdd71d33ca1229f8316925d5957240"
dependencies = [
"atomic",
]
@ -95,6 +95,12 @@ dependencies = [
"rustc-demangle",
]
[[package]]
name = "base64"
version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]]
name = "bit_field"
version = "0.10.2"
@ -299,7 +305,7 @@ dependencies = [
"android-tzdata",
"iana-time-zone",
"num-traits",
"windows-targets",
"windows-targets 0.48.5",
]
[[package]]
@ -374,15 +380,6 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
name = "dart-sys"
version = "4.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d8b5680b5c2cc52f50acb2457d9b3a3b58adcca785db13a0e3655626f601de6"
dependencies = [
"cc",
]
[[package]]
name = "dashmap"
version = "5.5.3"
@ -475,6 +472,15 @@ dependencies = [
"spin",
]
[[package]]
name = "form_urlencoded"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
dependencies = [
"percent-encoding",
]
[[package]]
name = "futures-channel"
version = "0.3.28"
@ -547,10 +553,20 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
[[package]]
name = "home"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "hub"
version = "0.1.0"
dependencies = [
"allo-isolate",
"boa_engine",
"image",
"prost",
@ -698,6 +714,16 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "idna"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
dependencies = [
"unicode-bidi",
"unicode-normalization",
]
[[package]]
name = "image"
version = "0.24.7"
@ -753,19 +779,13 @@ dependencies = [
[[package]]
name = "js-sys"
version = "0.3.64"
version = "0.3.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"
checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lebe"
version = "0.5.2"
@ -833,7 +853,7 @@ checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0"
dependencies = [
"libc",
"wasi",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -958,9 +978,15 @@ dependencies = [
"libc",
"redox_syscall",
"smallvec",
"windows-targets",
"windows-targets 0.48.5",
]
[[package]]
name = "percent-encoding"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "phf"
version = "0.11.2"
@ -1066,9 +1092,9 @@ dependencies = [
[[package]]
name = "prost"
version = "0.12.1"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4fdd22f3b9c31b53c060df4a0613a1c7f062d4115a2b984dd15b1858f7e340d"
checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a"
dependencies = [
"bytes",
"prost-derive",
@ -1076,9 +1102,9 @@ dependencies = [
[[package]]
name = "prost-derive"
version = "0.12.1"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "265baba7fabd416cf5078179f7d2cbeca4ce7a9041111900675ea7c4cb8a4c32"
checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e"
dependencies = [
"anyhow",
"itertools",
@ -1087,6 +1113,16 @@ dependencies = [
"syn 2.0.38",
]
[[package]]
name = "protoc-prebuilt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37aee930fb53074ec083bf049aa6133bb1a93cce8fc39f83e07f36a0937304dd"
dependencies = [
"ureq",
"zip",
]
[[package]]
name = "qoi"
version = "0.4.1"
@ -1176,20 +1212,29 @@ dependencies = [
[[package]]
name = "rinf"
version = "4.16.3"
version = "6.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d805a4a3ba0e2564baa19a9360d2b334c3a7b016e434512ece130ce74d4ca76c"
checksum = "394a11182639141467cd388456a9fcb091ea0db5cfb3e8297eda242dfaa23860"
dependencies = [
"allo-isolate",
"backtrace",
"bytemuck",
"dart-sys",
"home",
"js-sys",
"lazy_static",
"libc",
"os-thread-local",
"wasm-bindgen",
"web-sys",
"protoc-prebuilt",
]
[[package]]
name = "ring"
version = "0.17.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74"
dependencies = [
"cc",
"getrandom",
"libc",
"spin",
"untrusted",
"windows-sys 0.48.0",
]
[[package]]
@ -1204,6 +1249,28 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustls"
version = "0.21.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba"
dependencies = [
"log",
"ring",
"rustls-webpki",
"sct",
]
[[package]]
name = "rustls-webpki"
version = "0.101.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "ryu"
version = "1.0.16"
@ -1222,6 +1289,16 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "sct"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "serde"
version = "1.0.193"
@ -1287,7 +1364,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9"
dependencies = [
"libc",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -1405,6 +1482,21 @@ dependencies = [
"zerovec",
]
[[package]]
name = "tinyvec"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.33.0"
@ -1421,7 +1513,7 @@ dependencies = [
"signal-hook-registry",
"socket2",
"tokio-macros",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -1437,9 +1529,9 @@ dependencies = [
[[package]]
name = "tokio_with_wasm"
version = "0.3.2"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22578519b09a4fd0f3e55e1b4fdf337fe0b8ce53c6a853009f37bee1b0b7127c"
checksum = "9e3e506fe942e7be6a129f928f263d4bf5d9c8c7104c885574aedb5c6138a164"
dependencies = [
"futures-channel",
"js-sys",
@ -1466,18 +1558,65 @@ dependencies = [
"winnow",
]
[[package]]
name = "unicode-bidi"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-normalization"
version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-xid"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]]
name = "untrusted"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "ureq"
version = "2.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8cdd25c339e200129fe4de81451814e5228c9b771d57378817d6117cc2b3f97"
dependencies = [
"base64",
"log",
"once_cell",
"rustls",
"rustls-webpki",
"url",
"webpki-roots",
]
[[package]]
name = "url"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
dependencies = [
"form_urlencoded",
"idna",
"percent-encoding",
]
[[package]]
name = "utf16_iter"
version = "1.0.5"
@ -1504,9 +1643,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
version = "0.2.87"
version = "0.2.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
@ -1514,9 +1653,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.87"
version = "0.2.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd"
dependencies = [
"bumpalo",
"log",
@ -1541,9 +1680,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.87"
version = "0.2.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@ -1551,9 +1690,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.87"
version = "0.2.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7"
dependencies = [
"proc-macro2",
"quote",
@ -1564,9 +1703,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.87"
version = "0.2.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b"
[[package]]
name = "web-sys"
@ -1578,6 +1717,12 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "webpki-roots"
version = "0.25.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10"
[[package]]
name = "weezl"
version = "0.1.7"
@ -1612,7 +1757,7 @@ version = "0.51.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64"
dependencies = [
"windows-targets",
"windows-targets 0.48.5",
]
[[package]]
@ -1621,7 +1766,16 @@ version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets",
"windows-targets 0.48.5",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets 0.52.0",
]
[[package]]
@ -1630,13 +1784,28 @@ version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
"windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc 0.48.5",
"windows_i686_gnu 0.48.5",
"windows_i686_msvc 0.48.5",
"windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm 0.48.5",
"windows_x86_64_msvc 0.48.5",
]
[[package]]
name = "windows-targets"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
dependencies = [
"windows_aarch64_gnullvm 0.52.0",
"windows_aarch64_msvc 0.52.0",
"windows_i686_gnu 0.52.0",
"windows_i686_msvc 0.52.0",
"windows_x86_64_gnu 0.52.0",
"windows_x86_64_gnullvm 0.52.0",
"windows_x86_64_msvc 0.52.0",
]
[[package]]
@ -1645,42 +1814,84 @@ version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
[[package]]
name = "winnow"
version = "0.5.30"
@ -1790,6 +2001,18 @@ dependencies = [
"syn 2.0.38",
]
[[package]]
name = "zip"
version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261"
dependencies = [
"byteorder",
"crc32fast",
"crossbeam-utils",
"flate2",
]
[[package]]
name = "zune-inflate"
version = "0.2.54"

View file

@ -47,16 +47,14 @@ Get the app from our [releases page](https://github.com/kodjodevf/mangayomi/rele
This project use Rust for the [auto-image-cropper](https://github.com/ritiek/auto-image-cropper) crate and [boa](https://github.com/boa-dev/boa) crate utilizing the capabilities of the [Rinf](https://pub.dev/packages/rinf) framework.
To run and build this app, you need to have
[Flutter SDK](https://docs.flutter.dev/get-started/install),
[Rust toolchain](https://www.rust-lang.org/tools/install),
and [Protobuf compiler](https://grpc.io/docs/protoc-installation)
[Flutter SDK](https://docs.flutter.dev/get-started/install)
and [Rust toolchain](https://www.rust-lang.org/tools/install)
installed on your system.
You can check that your system is ready with the commands below.
Note that all the Flutter subcomponents should be installed.
```bash
rustc --version
protoc --version
flutter doctor
```

View file

@ -17,7 +17,7 @@ import 'package:mangayomi/modules/more/settings/appearance/providers/pure_black_
import 'package:mangayomi/modules/more/settings/appearance/providers/theme_mode_state_provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:media_kit/media_kit.dart';
import 'package:rinf/rinf.dart';
import 'package:mangayomi/messages/generated.dart';
import 'package:window_manager/window_manager.dart';
// Global instance of the Isar database.
@ -35,7 +35,7 @@ class MyHttpoverrides extends HttpOverrides {
/// Entry point of the application.
void main(List<String> args) async {
await Rinf.ensureInitialized();
await Rinf.initialize();
// Override the default HTTP client.
HttpOverrides.global = MyHttpoverrides();
// If running on desktop platforms and web view title bar widget is active, exit.

View file

@ -1,13 +1,15 @@
import 'dart:async';
import 'dart:io';
import 'package:extended_image/extended_image.dart';
import 'package:flutter/foundation.dart';
import 'package:mangayomi/messages/crop_borders.pb.dart' as crop_borders;
import 'package:mangayomi/messages/crop_borders.pb.dart';
import 'package:mangayomi/modules/manga/reader/reader_view.dart';
import 'package:mangayomi/utils/reg_exp_matcher.dart';
import 'package:rinf/rinf.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'crop_borders_provider.g.dart';
int currentId = 0;
@Riverpod(keepAlive: true)
Future<Uint8List?> cropBorders(CropBordersRef ref,
{required UChapDataPreload datas, required bool cropBorder}) async {
@ -29,15 +31,22 @@ Future<Uint8List?> cropBorders(CropBordersRef ref,
if (imageBytes == null) {
return null;
}
final requestMessage = crop_borders.ReadRequest(
image: imageBytes,
);
final rustRequest = RustRequest(
resource: crop_borders.ID,
operation: RustOperation.Read,
message: requestMessage.writeToBuffer());
final rustResponse = await requestToRust(rustRequest);
return rustResponse.blob;
final completer = Completer<Uint8List>();
CropBordersInput(
interactionId: currentId,
).sendSignalToRust(imageBytes);
final stream = CropBordersOutput.rustSignalStream;
final subscription = stream.listen((rustSignal) {
if (rustSignal.message.interactionId == currentId) {
completer.complete(rustSignal.blob!);
}
});
final image = await completer.future;
subscription.cancel();
currentId++;
return image;
}
return null;
}

View file

@ -1,18 +1,23 @@
import 'package:mangayomi/messages/boa_js.pb.dart';
import 'package:rinf/rinf.dart';
import 'dart:async';
int currentId = 0;
Future<String> evalJs(String script) async {
final requestMessage = ReadRequest(codeScript: script);
final rustRequest = RustRequest(
resource: ID,
operation: RustOperation.Read,
message: requestMessage.writeToBuffer());
final rustResponse = await requestToRust(rustRequest);
if (rustResponse.successful) {
final responseMessage = ReadResponse.fromBuffer(
rustResponse.message!,
);
return responseMessage.response;
}
return "";
final completer = Completer<String>();
BoaInput(
interactionId: currentId,
codeScript: script,
).sendSignalToRust(null);
final stream = BoaOutput.rustSignalStream;
final subscription = stream.listen((rustSignal) {
if (rustSignal.message.interactionId == currentId) {
completer.complete(rustSignal.message.response);
}
});
final response = await completer.future;
subscription.cancel();
currentId++;
return response;
}

3
messages/README.md Normal file
View file

@ -0,0 +1,3 @@
# Protobuf Messages
This folder contains Protobuf message files that serve as an API between Dart and Rust. `.proto` files can be compiled into Dart and Rust code with the command `rinf message`, provided by the [Rinf](https://rinf.cunarist.com) framework.

View file

@ -1,9 +1,14 @@
syntax = "proto3";
package boa_js;
message ReadRequest {
string code_script = 1;
// [RINF:DART-SIGNAL]
message BoaInput {
int32 interaction_id = 1;
string code_script = 2;
}
message ReadResponse {
string response = 1;
// [RINF:RUST-SIGNAL]
message BoaOutput {
int32 interaction_id = 1;
string response = 2;
}

View file

@ -1,6 +1,8 @@
syntax = "proto3";
package crop_borders;
message ReadRequest {
bytes image = 1;
}
// [RINF:DART-SIGNAL]
message CropBordersInput { int32 interaction_id = 1; }
// [RINF:RUST-SIGNAL]
message CropBordersOutput { int32 interaction_id = 1; }

View file

@ -12,9 +12,10 @@ edition = "2021"
crate-type = ["lib", "cdylib", "staticlib"]
[dependencies]
rinf = "4.16.3"
tokio_with_wasm = "0.3.2"
wasm-bindgen = "0.2.87"
prost = "0.12.0"
rinf = "6.0.1"
allo-isolate = "0.1.24"
wasm-bindgen = "0.2.90"
prost = "0.12.3"
tokio_with_wasm = "0.4.0"
image = "0.24.7"
boa_engine = "0.17.3"

View file

@ -1,32 +1,20 @@
use crate::bridge::{RustOperation, RustRequest, RustResponse};
use crate::messages;
use boa_engine::{Context, Source};
use prost::Message;
pub async fn eval_js(rust_request: RustRequest) -> RustResponse {
use crate::messages::boa_js::{ReadRequest, ReadResponse};
pub async fn eval_js() {
use messages::boa_js::*;
match rust_request.operation {
RustOperation::Create => RustResponse::default(),
RustOperation::Read => {
let mut context = Context::default();
let code_script = rust_request.message.unwrap();
let request_message = ReadRequest::decode(code_script.as_slice()).unwrap();
let response_message = ReadResponse {
response: match context
.eval(Source::from_bytes(request_message.code_script.as_bytes()))
{
Ok(res) => res.to_string(&mut context).unwrap().to_std_string_escaped(),
Err(_e) => "error".to_string(),
},
};
RustResponse {
successful: true,
message: Some(response_message.encode_to_vec()),
blob: None,
}
let mut receiver = BoaInput::get_dart_signal_receiver();
while let Some(dart_signal) = receiver.recv().await {
let mut context = Context::default();
let code_script = dart_signal.message.code_script;
BoaOutput {
interaction_id: dart_signal.message.interaction_id,
response: match context.eval(Source::from_bytes(code_script.as_bytes())) {
Ok(res) => res.to_string(&mut context).unwrap().to_std_string_escaped(),
Err(_e) => "error".to_string(),
},
}
RustOperation::Delete => RustResponse::default(),
RustOperation::Update => RustResponse::default(),
.send_signal_to_dart(None);
}
}

View file

@ -1,174 +0,0 @@
use super::*;
// Section: wire functions
#[no_mangle]
pub extern "C" fn wire_prepare_rust_signal_stream(port_: i64) {
wire_prepare_rust_signal_stream_impl(port_)
}
#[no_mangle]
pub extern "C" fn wire_prepare_rust_response_stream(port_: i64) {
wire_prepare_rust_response_stream_impl(port_)
}
#[no_mangle]
pub extern "C" fn wire_prepare_rust_report_stream(port_: i64) {
wire_prepare_rust_report_stream_impl(port_)
}
#[no_mangle]
pub extern "C" fn wire_prepare_channels(port_: i64) {
wire_prepare_channels_impl(port_)
}
#[no_mangle]
pub extern "C" fn wire_check_rust_streams(port_: i64) {
wire_check_rust_streams_impl(port_)
}
#[no_mangle]
pub extern "C" fn wire_start_rust_logic(port_: i64) {
wire_start_rust_logic_impl(port_)
}
#[no_mangle]
pub extern "C" fn wire_stop_rust_logic(port_: i64) {
wire_stop_rust_logic_impl(port_)
}
#[no_mangle]
pub extern "C" fn wire_request_to_rust(port_: i64, request_unique: *mut wire_RustRequestUnique) {
wire_request_to_rust_impl(port_, request_unique)
}
// Section: allocate functions
#[no_mangle]
pub extern "C" fn new_box_autoadd_rust_request_unique_0() -> *mut wire_RustRequestUnique {
support::new_leak_box_ptr(wire_RustRequestUnique::new_with_null_ptr())
}
#[no_mangle]
pub extern "C" fn new_uint_8_list_0(len: i32) -> *mut wire_uint_8_list {
let ans = wire_uint_8_list {
ptr: support::new_leak_vec_ptr(Default::default(), len),
len,
};
support::new_leak_box_ptr(ans)
}
// Section: related functions
// Section: impl Wire2Api
impl Wire2Api<RustRequestUnique> for *mut wire_RustRequestUnique {
fn wire2api(self) -> RustRequestUnique {
let wrap = unsafe { support::box_from_leak_ptr(self) };
Wire2Api::<RustRequestUnique>::wire2api(*wrap).into()
}
}
impl Wire2Api<RustRequest> for wire_RustRequest {
fn wire2api(self) -> RustRequest {
RustRequest {
resource: self.resource.wire2api(),
operation: self.operation.wire2api(),
message: self.message.wire2api(),
blob: self.blob.wire2api(),
}
}
}
impl Wire2Api<RustRequestUnique> for wire_RustRequestUnique {
fn wire2api(self) -> RustRequestUnique {
RustRequestUnique {
id: self.id.wire2api(),
request: self.request.wire2api(),
}
}
}
impl Wire2Api<Vec<u8>> for *mut wire_uint_8_list {
fn wire2api(self) -> Vec<u8> {
unsafe {
let wrap = support::box_from_leak_ptr(self);
support::vec_from_leak_ptr(wrap.ptr, wrap.len)
}
}
}
// Section: wire structs
#[repr(C)]
#[derive(Clone)]
pub struct wire_RustRequest {
resource: i32,
operation: i32,
message: *mut wire_uint_8_list,
blob: *mut wire_uint_8_list,
}
#[repr(C)]
#[derive(Clone)]
pub struct wire_RustRequestUnique {
id: i32,
request: wire_RustRequest,
}
#[repr(C)]
#[derive(Clone)]
pub struct wire_uint_8_list {
ptr: *mut u8,
len: i32,
}
// Section: impl NewWithNullPtr
pub trait NewWithNullPtr {
fn new_with_null_ptr() -> Self;
}
impl<T> NewWithNullPtr for *mut T {
fn new_with_null_ptr() -> Self {
std::ptr::null_mut()
}
}
impl NewWithNullPtr for wire_RustRequest {
fn new_with_null_ptr() -> Self {
Self {
resource: Default::default(),
operation: Default::default(),
message: core::ptr::null_mut(),
blob: core::ptr::null_mut(),
}
}
}
impl Default for wire_RustRequest {
fn default() -> Self {
Self::new_with_null_ptr()
}
}
impl NewWithNullPtr for wire_RustRequestUnique {
fn new_with_null_ptr() -> Self {
Self {
id: Default::default(),
request: Default::default(),
}
}
}
impl Default for wire_RustRequestUnique {
fn default() -> Self {
Self::new_with_null_ptr()
}
}
// Section: sync execution mode utility
#[no_mangle]
pub extern "C" fn free_WireSyncReturn(ptr: support::WireSyncReturn) {
unsafe {
let _ = support::box_from_leak_ptr(ptr);
};
}

View file

@ -1,245 +0,0 @@
#![allow(
non_camel_case_types,
unused,
clippy::redundant_closure,
clippy::useless_conversion,
clippy::unit_arg,
clippy::double_parens,
non_snake_case,
clippy::too_many_arguments
)]
// AUTO GENERATED FILE, DO NOT EDIT.
// Generated by flutter_rust_bridge_codegen@ 1.79.0.
use crate::bridge::interface::*;
use core::panic::UnwindSafe;
use rinf::engine::rust2dart::IntoIntoDart;
use rinf::engine::*;
use std::ffi::c_void;
use std::sync::Arc;
// Section: imports
// Section: wire functions
fn wire_prepare_rust_signal_stream_impl(port_: MessagePort) {
BRIDGE_HANDLER.wrap::<_, _, _, ()>(
WrapInfo {
debug_name: "prepare_rust_signal_stream",
port: Some(port_),
mode: FfiCallMode::Stream,
},
move || {
move |task_callback| {
Ok(prepare_rust_signal_stream(
task_callback.stream_sink::<_, RustSignal>(),
))
}
},
)
}
fn wire_prepare_rust_response_stream_impl(port_: MessagePort) {
BRIDGE_HANDLER.wrap::<_, _, _, ()>(
WrapInfo {
debug_name: "prepare_rust_response_stream",
port: Some(port_),
mode: FfiCallMode::Stream,
},
move || {
move |task_callback| {
Ok(prepare_rust_response_stream(
task_callback.stream_sink::<_, RustResponseUnique>(),
))
}
},
)
}
fn wire_prepare_rust_report_stream_impl(port_: MessagePort) {
BRIDGE_HANDLER.wrap::<_, _, _, ()>(
WrapInfo {
debug_name: "prepare_rust_report_stream",
port: Some(port_),
mode: FfiCallMode::Stream,
},
move || {
move |task_callback| {
Ok(prepare_rust_report_stream(
task_callback.stream_sink::<_, String>(),
))
}
},
)
}
fn wire_prepare_channels_impl(port_: MessagePort) {
BRIDGE_HANDLER.wrap::<_, _, _, ()>(
WrapInfo {
debug_name: "prepare_channels",
port: Some(port_),
mode: FfiCallMode::Normal,
},
move || move |task_callback| Ok(prepare_channels()),
)
}
fn wire_check_rust_streams_impl(port_: MessagePort) {
BRIDGE_HANDLER.wrap::<_, _, _, bool>(
WrapInfo {
debug_name: "check_rust_streams",
port: Some(port_),
mode: FfiCallMode::Normal,
},
move || move |task_callback| Ok(check_rust_streams()),
)
}
fn wire_start_rust_logic_impl(port_: MessagePort) {
BRIDGE_HANDLER.wrap::<_, _, _, ()>(
WrapInfo {
debug_name: "start_rust_logic",
port: Some(port_),
mode: FfiCallMode::Normal,
},
move || move |task_callback| Ok(start_rust_logic()),
)
}
fn wire_stop_rust_logic_impl(port_: MessagePort) {
BRIDGE_HANDLER.wrap::<_, _, _, ()>(
WrapInfo {
debug_name: "stop_rust_logic",
port: Some(port_),
mode: FfiCallMode::Normal,
},
move || move |task_callback| Ok(stop_rust_logic()),
)
}
fn wire_request_to_rust_impl(
port_: MessagePort,
request_unique: impl Wire2Api<RustRequestUnique> + UnwindSafe,
) {
BRIDGE_HANDLER.wrap::<_, _, _, ()>(
WrapInfo {
debug_name: "request_to_rust",
port: Some(port_),
mode: FfiCallMode::Normal,
},
move || {
let api_request_unique = request_unique.wire2api();
move |task_callback| Ok(request_to_rust(api_request_unique))
},
)
}
// Section: wrapper structs
// Section: static checks
// Section: allocate functions
// Section: related functions
// Section: impl Wire2Api
pub trait Wire2Api<T> {
fn wire2api(self) -> T;
}
impl<T, S> Wire2Api<Option<T>> for *mut S
where
*mut S: Wire2Api<T>,
{
fn wire2api(self) -> Option<T> {
(!self.is_null()).then(|| self.wire2api())
}
}
impl Wire2Api<i32> for i32 {
fn wire2api(self) -> i32 {
self
}
}
impl Wire2Api<RustOperation> for i32 {
fn wire2api(self) -> RustOperation {
match self {
0 => RustOperation::Create,
1 => RustOperation::Read,
2 => RustOperation::Update,
3 => RustOperation::Delete,
_ => unreachable!("Invalid variant for RustOperation: {}", self),
}
}
}
impl Wire2Api<u8> for u8 {
fn wire2api(self) -> u8 {
self
}
}
// Section: impl IntoDart
impl support::IntoDart for RustResponse {
fn into_dart(self) -> support::DartAbi {
vec![
self.successful.into_into_dart().into_dart(),
self.message.into_dart(),
self.blob.into_dart(),
]
.into_dart()
}
}
impl support::IntoDartExceptPrimitive for RustResponse {}
impl rust2dart::IntoIntoDart<RustResponse> for RustResponse {
fn into_into_dart(self) -> Self {
self
}
}
impl support::IntoDart for RustResponseUnique {
fn into_dart(self) -> support::DartAbi {
vec![
self.id.into_into_dart().into_dart(),
self.response.into_into_dart().into_dart(),
]
.into_dart()
}
}
impl support::IntoDartExceptPrimitive for RustResponseUnique {}
impl rust2dart::IntoIntoDart<RustResponseUnique> for RustResponseUnique {
fn into_into_dart(self) -> Self {
self
}
}
impl support::IntoDart for RustSignal {
fn into_dart(self) -> support::DartAbi {
vec![
self.resource.into_into_dart().into_dart(),
self.message.into_dart(),
self.blob.into_dart(),
]
.into_dart()
}
}
impl support::IntoDartExceptPrimitive for RustSignal {}
impl rust2dart::IntoIntoDart<RustSignal> for RustSignal {
fn into_into_dart(self) -> Self {
self
}
}
// Section: executor
support::lazy_static! {
pub static ref BRIDGE_HANDLER: support::DefaultHandler = Default::default();
}
/// cbindgen:ignore
#[cfg(target_family = "wasm")]
#[path = "generated.web.rs"]
mod web;
#[cfg(target_family = "wasm")]
pub use web::*;
#[cfg(not(target_family = "wasm"))]
#[path = "generated.io.rs"]
mod io;
#[cfg(not(target_family = "wasm"))]
pub use io::*;

View file

@ -1,122 +0,0 @@
use super::*;
// Section: wire functions
#[wasm_bindgen]
pub fn wire_prepare_rust_signal_stream(port_: MessagePort) {
wire_prepare_rust_signal_stream_impl(port_)
}
#[wasm_bindgen]
pub fn wire_prepare_rust_response_stream(port_: MessagePort) {
wire_prepare_rust_response_stream_impl(port_)
}
#[wasm_bindgen]
pub fn wire_prepare_rust_report_stream(port_: MessagePort) {
wire_prepare_rust_report_stream_impl(port_)
}
#[wasm_bindgen]
pub fn wire_prepare_channels(port_: MessagePort) {
wire_prepare_channels_impl(port_)
}
#[wasm_bindgen]
pub fn wire_check_rust_streams(port_: MessagePort) {
wire_check_rust_streams_impl(port_)
}
#[wasm_bindgen]
pub fn wire_start_rust_logic(port_: MessagePort) {
wire_start_rust_logic_impl(port_)
}
#[wasm_bindgen]
pub fn wire_stop_rust_logic(port_: MessagePort) {
wire_stop_rust_logic_impl(port_)
}
#[wasm_bindgen]
pub fn wire_request_to_rust(port_: MessagePort, request_unique: JsValue) {
wire_request_to_rust_impl(port_, request_unique)
}
// Section: allocate functions
// Section: related functions
// Section: impl Wire2Api
impl Wire2Api<Option<Vec<u8>>> for Option<Box<[u8]>> {
fn wire2api(self) -> Option<Vec<u8>> {
self.map(Wire2Api::wire2api)
}
}
impl Wire2Api<RustRequest> for JsValue {
fn wire2api(self) -> RustRequest {
let self_ = self.dyn_into::<JsArray>().unwrap();
assert_eq!(
self_.length(),
4,
"Expected 4 elements, got {}",
self_.length()
);
RustRequest {
resource: self_.get(0).wire2api(),
operation: self_.get(1).wire2api(),
message: self_.get(2).wire2api(),
blob: self_.get(3).wire2api(),
}
}
}
impl Wire2Api<RustRequestUnique> for JsValue {
fn wire2api(self) -> RustRequestUnique {
let self_ = self.dyn_into::<JsArray>().unwrap();
assert_eq!(
self_.length(),
2,
"Expected 2 elements, got {}",
self_.length()
);
RustRequestUnique {
id: self_.get(0).wire2api(),
request: self_.get(1).wire2api(),
}
}
}
impl Wire2Api<Vec<u8>> for Box<[u8]> {
fn wire2api(self) -> Vec<u8> {
self.into_vec()
}
}
// Section: impl Wire2Api for JsValue
impl Wire2Api<i32> for JsValue {
fn wire2api(self) -> i32 {
self.unchecked_into_f64() as _
}
}
impl Wire2Api<Option<Vec<u8>>> for JsValue {
fn wire2api(self) -> Option<Vec<u8>> {
(!self.is_undefined() && !self.is_null()).then(|| self.wire2api())
}
}
impl Wire2Api<RustOperation> for JsValue {
fn wire2api(self) -> RustOperation {
(self.unchecked_into_f64() as i32).wire2api()
}
}
impl Wire2Api<u8> for JsValue {
fn wire2api(self) -> u8 {
self.unchecked_into_f64() as _
}
}
impl Wire2Api<Vec<u8>> for JsValue {
fn wire2api(self) -> Vec<u8> {
self.unchecked_into::<rinf::externs::js_sys::Uint8Array>()
.to_vec()
.into()
}
}

View file

@ -1,245 +1,53 @@
#![allow(dead_code)]
use rinf::engine::StreamSink;
use rinf::externs::lazy_static::lazy_static;
use std::cell::RefCell;
use std::sync::Arc;
use std::sync::Mutex;
use tokio::sync::mpsc::channel;
use tokio::sync::mpsc::Receiver;
use tokio::sync::mpsc::Sender;
use tokio_with_wasm::tokio;
/// Available operations that a `RustRequest` object can hold.
/// There are 4 options, `Create`,`Read`,`Update`, and `Delete`.
pub enum RustOperation {
Create,
Read,
Update,
Delete,
}
/// Holds the data that Rust streams to Dart.
#[derive(Clone)]
pub struct RustSignal {
pub resource: i32,
pub message: Option<Vec<u8>>,
pub blob: Option<Vec<u8>>,
}
/// Request object that is sent from Dart to Rust.
pub struct RustRequest {
pub resource: i32,
pub operation: RustOperation,
pub message: Option<Vec<u8>>,
pub blob: Option<Vec<u8>>,
}
/// Wrapper for `RustRequest` with a unique ID.
pub struct RustRequestUnique {
pub id: i32,
pub request: RustRequest,
}
/// Response object that is sent from Rust to Dart.
#[derive(Clone)]
pub struct RustResponse {
pub successful: bool,
pub message: Option<Vec<u8>>,
pub blob: Option<Vec<u8>>,
}
impl Default for RustResponse {
/// Empty response with the successful value of false.
fn default() -> RustResponse {
RustResponse {
successful: false,
message: None,
blob: None,
}
}
}
/// Wrapper for `RustResponse` with a unique ID.
#[derive(Clone)]
pub struct RustResponseUnique {
pub id: i32,
pub response: RustResponse,
}
type Cell<T> = RefCell<Option<T>>;
type SharedCell<T> = Arc<Mutex<Cell<T>>>;
type RustSignalStream = StreamSink<RustSignal>;
type RustResponseStream = StreamSink<RustResponseUnique>;
type RustReportStream = StreamSink<String>;
type RustRequestSender = Sender<RustRequestUnique>;
type RustRequestReceiver = Receiver<RustRequestUnique>;
// Native: Main thread
// Web: Worker thread
thread_local! {
pub static REQUEST_SENDER: Cell<RustRequestSender> = RefCell::new(None);
}
// Native: `tokio` runtime threads
// Web: Worker thread
thread_local! {
pub static SIGNAL_STREAM: Cell<RustSignalStream> = RefCell::new(None);
pub static RESPONSE_STREAM: Cell<RustResponseStream> = RefCell::new(None);
pub static REPORT_STREAM: Cell<RustReportStream> = RefCell::new(None);
}
// Native: All threads
// Web: Worker thread
lazy_static! {
pub static ref SIGNAL_STREAM_SHARED: SharedCell<RustSignalStream> =
Arc::new(Mutex::new(RefCell::new(None)));
pub static ref RESPONSE_STREAM_SHARED: SharedCell<RustResponseStream> =
Arc::new(Mutex::new(RefCell::new(None)));
pub static ref REPORT_STREAM_SHARED: SharedCell<RustReportStream> =
Arc::new(Mutex::new(RefCell::new(None)));
pub static ref REQUST_RECEIVER_SHARED: SharedCell<RustRequestReceiver> =
Arc::new(Mutex::new(RefCell::new(None)));
}
use std::sync::OnceLock;
#[cfg(not(target_family = "wasm"))]
lazy_static! {
pub static ref TOKIO_RUNTIME: rinf::externs::os_thread_local::ThreadLocal<Cell<tokio::runtime::Runtime>> =
rinf::externs::os_thread_local::ThreadLocal::new(|| RefCell::new(None));
}
pub use super::interface_os::*;
#[cfg(target_family = "wasm")]
thread_local! {
pub static IS_MAIN_STARTED: RefCell<bool> = RefCell::new(false);
pub use super::interface_web::*;
/// This contains a message from Dart.
/// Optionally, a custom binary called `blob` can also be included.
/// This type is generic, and the message
/// can be of any type declared in Protobuf.
pub struct DartSignal<T> {
pub message: T,
pub blob: Option<Vec<u8>>,
}
/// Returns a stream object in Dart that listens to Rust.
pub fn prepare_rust_signal_stream(signal_stream: StreamSink<RustSignal>) {
let cell = SIGNAL_STREAM_SHARED.lock().unwrap();
cell.replace(Some(signal_stream));
/// This is a mutable cell type that can be shared across threads.
pub type SharedCell<T> = OnceLock<Mutex<RefCell<Option<T>>>>;
/// Send a signal to Dart.
pub fn send_rust_signal(message_id: i32, message_bytes: Vec<u8>, blob: Option<Vec<u8>>) {
send_rust_signal_extern(
message_id,
message_bytes,
blob.is_some(),
blob.unwrap_or_default(),
);
}
/// Returns a stream object in Dart that gives responses from Rust.
pub fn prepare_rust_response_stream(response_stream: StreamSink<RustResponseUnique>) {
let cell = RESPONSE_STREAM_SHARED.lock().unwrap();
cell.replace(Some(response_stream));
}
/// Returns a stream object in Dart that gives strings to print from Rust.
pub fn prepare_rust_report_stream(print_stream: StreamSink<String>) {
let cell = REPORT_STREAM_SHARED.lock().unwrap();
cell.replace(Some(print_stream));
}
/// Prepare channels that are used in the Rust world.
pub fn prepare_channels() {
let (request_sender, request_receiver) = channel(1024);
REQUEST_SENDER.with(move |inner| {
inner.replace(Some(request_sender));
});
let cell = REQUST_RECEIVER_SHARED.lock().unwrap();
cell.replace(Some(request_receiver));
}
/// Check if the streams are ready in Rust.
/// This should be done before starting the Rust logic.
pub fn check_rust_streams() -> bool {
let mut are_all_ready = true;
let cell = SIGNAL_STREAM_SHARED.lock().unwrap();
if cell.borrow().is_none() {
are_all_ready = false;
};
let cell = RESPONSE_STREAM_SHARED.lock().unwrap();
if cell.borrow().is_none() {
are_all_ready = false;
};
#[cfg(debug_assertions)]
{
let cell = REPORT_STREAM_SHARED.lock().unwrap();
if cell.borrow().is_none() {
are_all_ready = false;
};
}
are_all_ready
}
/// Start the main function of Rust.
pub fn start_rust_logic() {
#[cfg(not(target_family = "wasm"))]
{
use rinf::externs::backtrace;
/// Delegates the printing operation to Flutter,
/// which excels at handling various platforms
/// including web and mobile emulators.
/// When debugging, using this macro is recommended over `println!()`,
/// as it seamlessly adapts to different environments.
/// Note that this macro does nothing in release mode.
#[macro_export]
macro_rules! debug_print {
( $( $t:tt )* ) => {
let rust_report = format!( $( $t )* );
#[cfg(debug_assertions)]
std::panic::set_hook(Box::new(|panic_info| {
let mut frames_filtered = Vec::new();
backtrace::trace(|frame| {
// Filter some backtrace frames
// as those from infrastructure functions are not needed.
let mut should_keep_tracing = true;
backtrace::resolve_frame(frame, |symbol| {
if let Some(symbol_name) = symbol.name() {
let name = symbol_name.to_string();
let name_trimmed = name.trim_start_matches('_');
if name_trimmed.starts_with("rust_begin_unwind") {
frames_filtered.clear();
return;
}
if name_trimmed.starts_with("rust_try") {
should_keep_tracing = false;
return;
}
}
let backtrace_frame = backtrace::BacktraceFrame::from(frame.to_owned());
frames_filtered.push(backtrace_frame);
});
should_keep_tracing
});
let mut backtrace_filtered = backtrace::Backtrace::from(frames_filtered);
backtrace_filtered.resolve();
crate::debug_print!(
"A panic occurred in Rust.\n{}\n{:?}",
panic_info,
backtrace_filtered
);
}));
TOKIO_RUNTIME.with(move |inner| {
let tokio_runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap();
tokio_runtime.spawn(crate::main());
inner.replace(Some(tokio_runtime));
});
}
#[cfg(target_family = "wasm")]
{
#[cfg(debug_assertions)]
std::panic::set_hook(Box::new(|panic_info| {
crate::debug_print!("A panic occurred in Rust.\n{panic_info}");
}));
IS_MAIN_STARTED.with(move |ref_cell| {
let is_started = *ref_cell.borrow();
if !is_started {
tokio::spawn(crate::main());
ref_cell.replace(true);
}
});
$crate::bridge::send_rust_signal(
-1, // This is a special message ID for Rust reports
Vec::new(),
Some(rust_report.into_bytes()),
);
#[cfg(not(debug_assertions))]
let _ = rust_report;
}
}
/// Stop and terminate all Rust tasks.
pub fn stop_rust_logic() {
#[cfg(not(target_family = "wasm"))]
TOKIO_RUNTIME.with(move |ref_cell| {
ref_cell.replace(None);
});
}
/// Send a request to Rust and receive a response in Dart.
pub fn request_to_rust(request_unique: RustRequestUnique) {
REQUEST_SENDER.with(move |inner| {
let borrowed = inner.borrow();
let sender = borrowed.as_ref().unwrap();
sender.try_send(request_unique).ok();
});
}

View file

@ -0,0 +1,119 @@
use super::SharedCell;
use crate::debug_print;
use crate::tokio::runtime::Builder;
use crate::tokio::runtime::Runtime;
use allo_isolate::IntoDart;
use allo_isolate::Isolate;
use allo_isolate::ZeroCopyBuffer;
use rinf::externs::backtrace::Backtrace;
use rinf::externs::os_thread_local::ThreadLocal;
use std::cell::RefCell;
use std::panic::catch_unwind;
use std::sync::Mutex;
use std::sync::OnceLock;
static DART_ISOLATE: SharedCell<Isolate> = OnceLock::new();
#[no_mangle]
pub extern "C" fn prepare_isolate_extern(port: i64) {
let _ = catch_unwind(|| {
let dart_isolate = Isolate::new(port);
let cell = DART_ISOLATE
.get_or_init(|| Mutex::new(RefCell::new(None)))
.lock()
.unwrap();
cell.replace(Some(dart_isolate));
});
}
// We use `os_thread_local` so that when the program fails
// and the main thread exits unexpectedly,
// the whole async tokio runtime can disappear as well.
type TokioRuntime = OnceLock<ThreadLocal<RefCell<Option<Runtime>>>>;
static TOKIO_RUNTIME: TokioRuntime = OnceLock::new();
#[no_mangle]
pub extern "C" fn start_rust_logic_extern() {
let _ = catch_unwind(|| {
// Enable backtrace output for panics.
#[cfg(debug_assertions)]
{
std::panic::set_hook(Box::new(|panic_info| {
let backtrace = Backtrace::new();
debug_print!("A panic occurred in Rust.\n{panic_info}\n{backtrace:?}");
}));
}
// Run the main function.
let tokio_runtime = Builder::new_multi_thread().enable_all().build().unwrap();
tokio_runtime.spawn(crate::main());
let os_cell = TOKIO_RUNTIME.get_or_init(|| ThreadLocal::new(|| RefCell::new(None)));
os_cell.with(move |cell| {
// If there was already a tokio runtime previously,
// most likely due to Dart's hot restart,
// its tasks as well as itself will be terminated,
// being replaced with the new one.
cell.replace(Some(tokio_runtime));
});
});
}
#[no_mangle]
pub extern "C" fn stop_rust_logic_extern() {
let _ = catch_unwind(|| {
let os_cell = TOKIO_RUNTIME.get_or_init(|| ThreadLocal::new(|| RefCell::new(None)));
os_cell.with(move |cell| {
// If there was already a tokio runtime previously,
// most likely due to Dart's hot restart,
// its tasks as well as itself will be terminated,
// being replaced with the new one.
cell.replace(None);
});
});
}
#[no_mangle]
pub extern "C" fn send_dart_signal_extern(
message_id: i64,
message_pointer: *const u8,
message_size: usize,
blob_valid: bool,
blob_pointer: *const u8,
blob_size: usize,
) {
let message_bytes =
unsafe { Vec::from_raw_parts(message_pointer as *mut u8, message_size, message_size) };
let blob = if blob_valid {
unsafe {
Some(Vec::from_raw_parts(
blob_pointer as *mut u8,
blob_size,
blob_size,
))
}
} else {
None
};
let _ = catch_unwind(|| {
crate::messages::generated::handle_dart_signal(message_id as i32, message_bytes, blob);
});
}
pub fn send_rust_signal_extern(
message_id: i32,
message_bytes: Vec<u8>,
blob_valid: bool,
blob_bytes: Vec<u8>,
) {
let cell = DART_ISOLATE.get().unwrap().lock().unwrap();
let dart_isolate = cell.borrow().unwrap();
dart_isolate.post(
vec![
message_id.into_dart(),
ZeroCopyBuffer(message_bytes).into_dart(),
blob_valid.into_dart(),
ZeroCopyBuffer(blob_bytes).into_dart(),
]
.into_dart(),
);
}

View file

@ -0,0 +1,64 @@
use crate::debug_print;
use crate::tokio;
use rinf::externs::js_sys::Uint8Array;
use std::panic::catch_unwind;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn start_rust_logic_extern() {
let _ = catch_unwind(|| {
// Add kind description for panics.
#[cfg(debug_assertions)]
{
std::panic::set_hook(Box::new(|panic_info| {
debug_print!("A panic occurred in Rust.\n{panic_info}");
}));
}
// Run the main function.
tokio::spawn(crate::main());
});
}
#[wasm_bindgen]
pub fn send_dart_signal_extern(
message_id: i32,
message_bytes: &[u8],
blob_valid: bool,
blob_bytes: &[u8],
) {
let message_bytes = message_bytes.to_vec();
let blob = if blob_valid {
Some(blob_bytes.to_vec())
} else {
None
};
let _ = catch_unwind(|| {
crate::messages::generated::handle_dart_signal(message_id, message_bytes, blob);
});
}
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_name = rinf_send_rust_signal_extern)]
pub fn send_rust_signal_extern_raw(
resource: i32,
message_bytes: Uint8Array,
blob_valid: bool,
blob_bytes: Uint8Array,
);
}
pub fn send_rust_signal_extern(
message_id: i32,
message_bytes: Vec<u8>,
blob_valid: bool,
blob_bytes: Vec<u8>,
) {
send_rust_signal_extern_raw(
message_id,
rinf::externs::js_sys::Uint8Array::from(message_bytes.as_slice()),
blob_valid,
rinf::externs::js_sys::Uint8Array::from(blob_bytes.as_slice()),
);
}

View file

@ -1,93 +1,12 @@
//! This module supports communication with Dart.
//! More specifically, sending responses and
//! stream signals to Dart are supported.
//! DO NOT EDIT.
#![allow(dead_code)]
pub use interface::*;
use tokio::sync::mpsc::Receiver;
use tokio_with_wasm::tokio;
mod generated;
mod interface;
pub use interface::*;
/// This function is expected to be used only once
/// during the initialization of the Rust logic.
pub fn get_request_receiver() -> Receiver<RustRequestUnique> {
let cell = REQUST_RECEIVER_SHARED.lock().unwrap();
let option = cell.replace(None);
option.unwrap()
}
/// Sending the signal will notify the Flutter widgets
/// and trigger the rebuild.
/// No memory copy is involved as the bytes are moved directly to Dart.
pub fn send_rust_signal(rust_signal: RustSignal) {
SIGNAL_STREAM.with(|inner| {
let mut borrowed = inner.borrow_mut();
let option = borrowed.as_ref();
if let Some(stream) = option {
stream.add(rust_signal);
} else {
let cell = SIGNAL_STREAM_SHARED.lock().unwrap();
let stream = cell.borrow().as_ref().unwrap().clone();
stream.add(rust_signal);
borrowed.replace(stream);
}
});
}
/// Sends a response to Dart with a unique interaction ID
/// to remember which request that response corresponds to.
/// No memory copy is involved as the bytes are moved directly to Dart.
pub fn respond_to_dart(response_unique: RustResponseUnique) {
RESPONSE_STREAM.with(|inner| {
let mut borrowed = inner.borrow_mut();
let option = borrowed.as_ref();
if let Some(stream) = option {
stream.add(response_unique);
} else {
let cell = RESPONSE_STREAM_SHARED.lock().unwrap();
let stream = cell.borrow().as_ref().unwrap().clone();
stream.add(response_unique);
borrowed.replace(stream);
}
});
}
/// Delegates the printing operation to Flutter,
/// which excels at handling various platforms
/// including web and mobile emulators.
/// When debugging, using this macro is recommended over `println!()`,
/// as it seamlessly adapts to different environments.
/// Note that this macro does nothing in release mode.
#[macro_export]
macro_rules! debug_print {
( $( $t:tt )* ) => {
let rust_report = format!( $( $t )* );
#[cfg(debug_assertions)]
$crate::bridge::send_rust_report(rust_report.into());
#[cfg(not(debug_assertions))]
let _ = rust_report;
}
}
/// Sends a string to Dart that should be printed in the CLI.
/// Do NOT use this function directly in the code.
/// Use `debug_print!` macro instead.
#[cfg(debug_assertions)]
pub fn send_rust_report(rust_report: String) {
REPORT_STREAM.with(|inner| {
let mut borrowed = inner.borrow_mut();
let option = borrowed.as_ref();
if let Some(stream) = option {
stream.add(rust_report);
} else {
let cell = REPORT_STREAM_SHARED.lock().unwrap();
let stream = cell.borrow().as_ref().unwrap().clone();
stream.add(rust_report);
borrowed.replace(stream);
}
});
}
#[cfg(not(target_family = "wasm"))]
mod interface_os;
#[cfg(target_family = "wasm")]
mod interface_web;

View file

@ -19,9 +19,8 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.*/
use crate::bridge::{RustOperation, RustRequest, RustResponse};
use crate::messages;
use image::{DynamicImage, GenericImageView, ImageOutputFormat, ImageResult, Rgba};
use prost::Message;
use std::io::Cursor;
pub struct Point {
@ -138,27 +137,19 @@ fn crop_image(image: Vec<u8>) -> DynamicImage {
return sub_image;
}
pub async fn start_croping(rust_request: RustRequest) -> RustResponse {
use crate::messages::crop_borders::ReadRequest;
pub async fn start_croping() {
use messages::crop_borders::*;
match rust_request.operation {
RustOperation::Create => RustResponse::default(),
RustOperation::Read => {
let message_bytes = rust_request.message.unwrap();
let request_message = ReadRequest::decode(message_bytes.as_slice()).unwrap();
let res = crop_image(request_message.image);
let mut image_data: Vec<u8> = Vec::new();
res.write_to(&mut Cursor::new(&mut image_data), ImageOutputFormat::Png)
.unwrap();
RustResponse {
successful: true,
message: None,
blob: Some(image_data),
}
let mut receiver = CropBordersInput::get_dart_signal_receiver();
while let Some(dart_signal) = receiver.recv().await {
let image = dart_signal.blob.unwrap();
let res = crop_image(image);
let mut image_data: Vec<u8> = Vec::new();
res.write_to(&mut Cursor::new(&mut image_data), ImageOutputFormat::Png)
.unwrap();
CropBordersOutput {
interaction_id: dart_signal.message.interaction_id,
}
RustOperation::Delete => RustResponse::default(),
RustOperation::Update => RustResponse::default(),
.send_signal_to_dart(Some(image_data));
}
}

View file

@ -1,24 +1,15 @@
use bridge::respond_to_dart;
use with_request::handle_request;
use tokio_with_wasm::tokio;
mod boa_js;
mod bridge;
mod imagecrop;
mod messages;
mod with_request;
mod boa_js;
/// This `hub` crate is the entry point for the Rust logic.
/// Always use non-blocking async functions such as `tokio::fs::File::open`.
async fn main() {
// This is `tokio::sync::mpsc::Reciver` that receives the requests from Dart.
let mut request_receiver = bridge::get_request_receiver();
// Repeat `crate::spawn` anywhere in your code
// if more concurrent tasks are needed.
while let Some(request_unique) = request_receiver.recv().await {
tokio::spawn(async {
let response_unique = handle_request(request_unique).await;
respond_to_dart(response_unique);
});
}
tokio::spawn(boa_js::eval_js());
tokio::spawn(imagecrop::start_croping());
}

View file

@ -1,32 +0,0 @@
//! This module runs the corresponding function
//! when a `RustRequest` was received from Dart
//! and returns `RustResponse`.
use crate::bridge::{RustRequestUnique, RustResponse, RustResponseUnique};
use crate::imagecrop;
use crate::boa_js;
use crate::messages;
pub async fn handle_request(request_unique: RustRequestUnique) -> RustResponseUnique {
// Get the request data.
let rust_request = request_unique.request;
let interaction_id = request_unique.id;
// Run the function that corresponds to the address.
let rust_resource = rust_request.resource;
let rust_response = match rust_resource {
messages::crop_borders::ID => {
imagecrop::start_croping(rust_request).await // ADD THIS BLOCK
}
messages::boa_js::ID => {
boa_js::eval_js(rust_request).await // ADD THIS BLOCK
}
_ => RustResponse::default(),
};
// Return the response.
RustResponseUnique {
id: interaction_id,
response: rust_response,
}
}

View file

@ -310,10 +310,10 @@ packages:
dependency: transitive
description:
name: dbus
sha256: "6f07cba3f7b3448d42d015bfd3d53fe12e5b36da2423f23838efc1d5fb31a263"
sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac"
url: "https://pub.dev"
source: hosted
version: "0.7.8"
version: "0.7.10"
desktop_webview_window:
dependency: "direct main"
description:
@ -1115,10 +1115,10 @@ packages:
dependency: "direct main"
description:
name: rinf
sha256: a76b3d53b9cf740ccff0e8edffc465b0fb81bcad090b83d8d1486dd70aadbd6a
sha256: "1b86528233c20b2ec9c5f08d94a1cfae471cdb279aa22ea2afdfeca189dd890c"
url: "https://pub.dev"
source: hosted
version: "4.20.0"
version: "6.0.1"
riverpod:
dependency: transitive
description:

View file

@ -60,7 +60,7 @@ dependencies:
ref: 0ab6b10ea660ead8e8e1694517aabe3582f25d5c
media_kit_libs_video: ^1.0.4
crypto: ^3.0.3
rinf: ^4.19.0
rinf: ^6.0.1
protobuf: ^3.1.0
cupertino_icons: ^1.0.2
window_manager: ^0.3.7