├── .github ├── dependabot.yml └── workflows │ └── ci.yml ├── .gitignore ├── .vim └── template.rs ├── .vimrc ├── Cargo.toml ├── LICENSE ├── README.md ├── assets ├── 009f.dat ├── README.md ├── ascii-control.txt ├── ascii-printable.txt ├── base64.txt ├── chinese.txt ├── emoji.txt ├── ff.dat ├── random.dat └── zero.dat ├── codegen ├── Cargo.toml └── src │ └── lib.rs ├── compress ├── Cargo.toml └── src │ └── lib.rs ├── fail_tests └── 009f-str.rs ├── src └── lib.rs ├── test_util.rs └── tests ├── 009f.rs ├── ascii-control.rs ├── ascii-printable.rs ├── base64-raw.rs ├── base64.rs ├── chinese.rs ├── emoji.rs ├── ff-raw.rs ├── ff.rs ├── random-raw.rs ├── random.rs ├── zero-raw.rs └── zero.rs /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: cargo 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | open-pull-requests-limit: 10 8 | labels: 9 | - dependabot 10 | - rust-deps 11 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | - push 4 | - pull_request 5 | jobs: 6 | fmt: 7 | name: rustfmt check 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v2 11 | - uses: actions-rs/toolchain@v1 12 | with: 13 | toolchain: stable 14 | profile: default 15 | - run: cargo fmt --all -- --check 16 | lint: 17 | name: clippy lint 18 | runs-on: ubuntu-latest 19 | strategy: 20 | matrix: 21 | toolchain: 22 | - stable 23 | - beta 24 | - nightly 25 | stability: 26 | - "" 27 | - "--release" 28 | feature: 29 | - "" 30 | - "--no-default-features --features deflate" 31 | - "--no-default-features --features zstd" 32 | steps: 33 | - uses: actions/checkout@v2 34 | - uses: actions-rs/toolchain@v1 35 | with: 36 | toolchain: ${{matrix.toolchain}} 37 | profile: default 38 | default: true 39 | - name: cargo clippy 40 | run: "cargo clippy --all ${{matrix.feature}} ${{matrix.stability}}" 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /Cargo.lock 3 | **/*.rs.bk 4 | .*.sw[a-z] 5 | *.asc 6 | *.gpg 7 | *.sig 8 | -------------------------------------------------------------------------------- /.vim/template.rs: -------------------------------------------------------------------------------- 1 | // include-flate 2 | // Copyright (C) SOFe 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | -------------------------------------------------------------------------------- /.vimrc: -------------------------------------------------------------------------------- 1 | if has("autocmd") 2 | augroup tmpl 3 | autocmd BufNewFile *.rs 0r .vim/template.rs 4 | augroup END 5 | endif 6 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [".", "codegen", "compress"] 3 | 4 | [package] 5 | name = "include-flate" 6 | version = "0.3.0" 7 | authors = ["SOFe "] 8 | edition = "2021" 9 | license = "Apache-2.0" 10 | repository = "https://github.com/SOF3/include-flate.git" 11 | homepage = "https://github.com/SOF3/include-flate" 12 | description = "A variant of include_bytes!/include_str! with compile-time deflation and runtime lazy inflation" 13 | categories = ["compression", "rust-patterns", "memory-management"] 14 | keywords = ["compression", "deflate", "macro", "include", "assets"] 15 | include = ["/src", "/LICENSE", "/README.md"] 16 | 17 | [dependencies] 18 | include-flate-codegen = { version = "0.3.0", path = "codegen" } 19 | include-flate-compress = { version = "0.3.0", path = "compress" } 20 | once_cell = "1.18.0" 21 | libflate = "2.0.0" 22 | zstd = "0.13.0" 23 | 24 | [features] 25 | default = ["deflate", "zstd"] 26 | deflate = ["include-flate-compress/deflate"] 27 | zstd = ["include-flate-compress/zstd"] 28 | no-compression-warnings = ["include-flate-codegen/no-compression-warnings"] 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # include-flate 2 | [!![CI](https://github.com/SOF3/include-flate/workflows/CI/badge.svg)](https://github.com/SOF3/include-flate/actions) 3 | [![crates.io](https://img.shields.io/crates/dv/include-flate.svg)](https://docs.rs/include-flate) 4 | [![docs.rs](https://docs.rs/include-flate/badge.svg)](https://docs.rs/include-flate) 5 | 6 | A variant of `include_bytes!`/`include_str!` with compile-time deflation and runtime lazy inflation. 7 | 8 | ## Why? 9 | `include_bytes!`/`include_str!` are great for embedding resources into an executable/library 10 | without involving the complex logistics of maintaining an assets manager. 11 | However, they are copied as-is into the artifact, leading to unnecessarily large binary size. 12 | This library automatically compresses the resources and lazily decompresses them at runtime, 13 | allowing smaller binary sizes. 14 | 15 | Nevertheless, this inevitably leads to wasting RAM to store both the compressed and decompressed data, 16 | which might be undesirable if the data are too large. 17 | An actual installer is still required if the binary involves too many resources that do not need to be kept in RAM all time. 18 | 19 | ## Warning 20 | This library compresses included data independently. 21 | It is usually more effective to compress the whole output binary together (e.g. distributing `.exe.gz` ) 22 | than to compress independently. 23 | In addition, compression algorithms usually produce smaller artifacts by processing the raw input together 24 | than by processing already-compressed output. 25 | `#[cfg_attr]` might come handy for conditionally using compression or direct data inclusion. 26 | -------------------------------------------------------------------------------- /assets/009f.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SOF3/include-flate/fe2e11382dec8f6628d52753cfbac8b2a3b33609/assets/009f.dat -------------------------------------------------------------------------------- /assets/README.md: -------------------------------------------------------------------------------- 1 | # assets 2 | This directory contains some binary and text files used as test cases 3 | 4 | ## 009f.dat 5 | `9f` is not a valid UTF-8 codepoint. This is intended to make the UTF-8 validator fail. 6 | 7 | ## ascii-printable.txt 8 | All characters in this file are printable ASCII characters. ASCII is a subset of UTF-8. 9 | 10 | ## ascii-control.txt 11 | This file contains all ASCII characters, including printable and control characters. ASCII is a subset of UTF-8. 12 | 13 | ## chinese.txt 14 | This file contains 1323 Chinese characters encoded in UTF-8. 15 | 16 | ## emoji.txt 17 | This file contains 64 4-byte emojis encoded in UTF-8. (We are not specifically working on glyphs here, so no need to waste time defining "character" precisely) 18 | 19 | ## zero.dat 20 | This file contains 1048576 (1 MB) null bytes. This consistency is useful for benchmarking compression. 21 | 22 | ## ff.dat 23 | This file contains 1048576 (1 MB) 0xFF bytes. This consistency is useful for benchmarking compression. 24 | 25 | ## base64.txt 26 | This file contains 1048576 (1 MB) bytes, repeating the base64 charset for 16384 times. 27 | 28 | ## random.dat 29 | This file contains 1048576 (1 MB) random bytes. This entropy is useful for benchmarking compression. 30 | -------------------------------------------------------------------------------- /assets/ascii-control.txt: -------------------------------------------------------------------------------- 1 |  2 |  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ -------------------------------------------------------------------------------- /assets/ascii-printable.txt: -------------------------------------------------------------------------------- 1 | abcdef 2 | 012345 3 | -------------------------------------------------------------------------------- /assets/chinese.txt: -------------------------------------------------------------------------------- 1 | 量 2 | 曋 3 | 是 4 | 門 5 | 間 6 | 閶 7 | 闒 8 | 晚 9 | 冕 10 | 閺 11 | 閒 12 | 閿 13 | 闅 14 | 闃 15 | 閱 16 | 閑 17 | 閉 18 | 闈 19 | 闌 20 | 闊 21 | 焛 22 | 闛 23 | 闣 24 | 閨 25 | 闔 26 | 昅 27 | 閣 28 | 閽 29 | 閐 30 | 闑 31 | 閰 32 | 閬 33 | 閾 34 | 閞 35 | 闐 36 | 闍 37 | 閎 38 | 閹 39 | 闠 40 | 閩 41 | 閂 42 | 閛 43 | 閏 44 | 閈 45 | 闞 46 | 閆 47 | 閜 48 | 開 49 | 闉 50 | 閻 51 | 閮 52 | 闋 53 | 閃 54 | 欥 55 | 閵 56 | 閥 57 | 暌 58 | 闟 59 | 閤 60 | 悶 61 | 閟 62 | 闚 63 | 問 64 | 閭 65 | 闡 66 | 闆 67 | 聞 68 | 闖 69 | 闢 70 | 闀 71 | 闕 72 | 闓 73 | 關 74 | 閫 75 | 閘 76 | 闤 77 | 闥 78 | 閌 79 | 閍 80 | 閔 81 | 誾 82 | 閼 83 | 闇 84 | 閡 85 | 韙 86 | 尟 87 | 鶗 88 | 昤 89 | 昑 90 | 題 91 | 匙 92 | 晦 93 | 易 94 | 昒 95 | 旳 96 | 昀 97 | 昆 98 | 昫 99 | 旽 100 | 曷 101 | 暙 102 | 晴 103 | 照 104 | 煦 105 | 冔 106 | 暺 107 | 曮 108 | 暇 109 | 煚 110 | 昭 111 | 最 112 | 曜 113 | 昵 114 | 暱 115 | 暯 116 | 晪 117 | 曚 118 | 暴 119 | 謈 120 | 曦 121 | 暪 122 | 曣 123 | 暵 124 | 曄 125 | 巴 126 | 旵 127 | 暨 128 | 塈 129 | 毷 130 | 勖 131 | 暟 132 | 郿 133 | 鱀 134 | 岊 135 | 昢 136 | 艮 137 | 鶡 138 | 鷃 139 | 鷐 140 | 曏 141 | 毼 142 | 歇 143 | 曙 144 | 曼 145 | 曨 146 | 暾 147 | 昉 148 | 旻 149 | 旼 150 | 晬 151 | 暠 152 | 景 153 | 晾 154 | 曩 155 | 暆 156 | 昱 157 | 暗 158 | 曈 159 | 暲 160 | 昡 161 | 月 162 | 腥 163 | 腸 164 | 肥 165 | 冥 166 | 朋 167 | 骨 168 | 腡 169 | 覶 170 | 骳 171 | 脟 172 | 受 173 | 髐 174 | 鶻 175 | 骼 176 | 鵬 177 | 髀 178 | 骰 179 | 髆 180 | 髍 181 | 髂 182 | 髕 183 | 骷 184 | 髖 185 | 骻 186 | 骫 187 | 剮 188 | 髏 189 | 顝 190 | 骭 191 | 骾 192 | 胴 193 | 脬 194 | 舜 195 | 骱 196 | 愛 197 | 咼 198 | 髒 199 | 髊 200 | 骿 201 | 體 202 | 亂 203 | 臞 204 | 鼏 205 | 覓 206 | 髁 207 | 髑 208 | 骹 209 | 骯 210 | 髓 211 | 骴 212 | 髇 213 | 辭 214 | 骸 215 | 賵 216 | 賜 217 | 贔 218 | 賝 219 | 賙 220 | 賱 221 | 賏 222 | 覭 223 | 贈 224 | 財 225 | 賧 226 | 贖 227 | 鵙 228 | 販 229 | 賂 230 | 貶 231 | 貾 232 | 貹 233 | 賻 234 | 賤 235 | 贂 236 | 賊 237 | 賕 238 | 贆 239 | 贓 240 | 貽 241 | 肸 242 | 賳 243 | 賭 244 | 貯 245 | 賄 246 | 賗 247 | 贐 248 | 則 249 | 罕 250 | 賑 251 | 賦 252 | 甖 253 | 贉 254 | 贍 255 | 鄍 256 | 郥 257 | 罌 258 | 敗 259 | 賒 260 | 貤 261 | 賰 262 | 冏 263 | 貺 264 | 腳 265 | 脫 266 | 鼆 267 | 賬 268 | 賟 269 | 賹 270 | 購 271 | 賺 272 | 嬰 273 | 貥 274 | 譻 275 | 賥 276 | 貼 277 | 賠 278 | 賅 279 | 采 280 | 彩 281 | 肘 282 | 郛 283 | 膝 284 | 乳 285 | 腏 286 | 鶢 287 | 炙 288 | 膛 289 | 膌 290 | 冞 291 | 膦 292 | 縣 293 | 胱 294 | 懸 295 | 胖 296 | 賸 297 | 滕 298 | 騰 299 | 縢 300 | 塍 301 | 螣 302 | 謄 303 | 勝 304 | 腃 305 | 媵 306 | 乿 307 | 肚 308 | 膮 309 | 氍 310 | 胠 311 | 周 312 | 臌 313 | 膨 314 | 胉 315 | 腺 316 | 貜 317 | 貕 318 | 豺 319 | 腇 320 | 膰 321 | 胳 322 | 臐 323 | 貌 324 | 貉 325 | 肜 326 | 貏 327 | 脾 328 | 脈 329 | 貔 330 | 貁 331 | 腶 332 | 腫 333 | 腄 334 | 腯 335 | 貄 336 | 貗 337 | 貊 338 | 貆 339 | 豻 340 | 肵 341 | 肌 342 | 冗 343 | 股 344 | 豽 345 | 貅 346 | 貐 347 | 胻 348 | 豹 349 | 胝 350 | 胜 351 | 胅 352 | 貚 353 | 貑 354 | 胙 355 | 貂 356 | 貙 357 | 貘 358 | 貓 359 | 臢 360 | 貒 361 | 貀 362 | 膬 363 | 胍 364 | 貍 365 | 膍 366 | 舀 367 | 腴 368 | 膊 369 | 朘 370 | 脧 371 | 脯 372 | 脙 373 | 胈 374 | 腑 375 | 膩 376 | 臕 377 | 胎 378 | 虢 379 | 肺 380 | 脖 381 | 腩 382 | 膣 383 | 腔 384 | 皸 385 | 肢 386 | 鶤 387 | 膞 388 | 蠈 389 | 顐 390 | 臏 391 | 脘 392 | 鄆 393 | 腕 394 | 膹 395 | 臗 396 | 胺 397 | 軍 398 | 膫 399 | 谿 400 | 然 401 | 鶪 402 | 肱 403 | 网 404 | 腌 405 | 胯 406 | 胰 407 | 肒 408 | 郹 409 | 雞 410 | 脥 411 | 肋 412 | 胦 413 | 胇 414 | 朓 415 | 脁 416 | 腓 417 | 刖 418 | 胂 419 | 膢 420 | 胏 421 | 且 422 | 肛 423 | 囗 424 | 臑 425 | 臛 426 | 胹 427 | 胚 428 | 胵 429 | 肝 430 | 爰 431 | 助 432 | 刞 433 | 具 434 | 冢 435 | 朊 436 | 脤 437 | 雎 438 | 同 439 | 膈 440 | 脰 441 | 腷 442 | 豚 443 | 冠 444 | 脛 445 | 膘 446 | 腰 447 | 肊 448 | 脕 449 | 膽 450 | 孚 451 | 膙 452 | 脡 453 | 腱 454 | 蠫 455 | 脆 456 | 冤 457 | 腹 458 | 肭 459 | 朒 460 | 胕 461 | 脽 462 | 膲 463 | 臇 464 | 胗 465 | 肣 466 | 腍 467 | 膾 468 | 祭 469 | 腧 470 | 臉 471 | 豋 472 | 肐 473 | 脞 474 | 胣 475 | 膴 476 | 脢 477 | 脂 478 | 朐 479 | 胊 480 | 胞 481 | 肫 482 | 胸 483 | 用 484 | 腠 485 | 膆 486 | 甩 487 | 胑 488 | 鵰 489 | 脭 490 | 彫 491 | 戙 492 | 雕 493 | 臊 494 | 翢 495 | 爭 496 | 鵩 497 | 豸 498 | 肕 499 | 腒 500 | 服 501 | 腛 502 | 膠 503 | 脹 504 | 凸 505 | 皿 506 | 冊 507 | 腊 508 | 冪 509 | 膜 510 | 腆 511 | 朦 512 | 膉 513 | 膳 514 | 臟 515 | 朕 516 | 臙 517 | 朠 518 | 刪 519 | 頯 520 | 腜 521 | 臒 522 | 胼 523 | 岡 524 | 膿 525 | 膵 526 | 罔 527 | 目 528 | 睅 529 | 睼 530 | 瞷 531 | 矙 532 | 眼 533 | 瞑 534 | 瞬 535 | 睬 536 | 睭 537 | 睜 538 | 瞁 539 | 睍 540 | 覞 541 | 貝 542 | 朡 543 | 瞈 544 | 盻 545 | 睇 546 | 盼 547 | 睞 548 | 睄 549 | 矘 550 | 瞠 551 | 眯 552 | 瞵 553 | 睒 554 | 眇 555 | 睠 556 | 睖 557 | 睦 558 | 眭 559 | 瞌 560 | 鷂 561 | 瞗 562 | 瞅 563 | 眅 564 | 矄 565 | 睥 566 | 眽 567 | 眨 568 | 睡 569 | 瞃 570 | 盺 571 | 颻 572 | 覹 573 | 瞛 574 | 睧 575 | 睋 576 | 眣 577 | 眊 578 | 睙 579 | 見 580 | 矏 581 | 繇 582 | 瞍 583 | 睨 584 | 眸 585 | 狊 586 | 眙 587 | 矌 588 | 眓 589 | 瞋 590 | 眛 591 | 睹 592 | 睫 593 | 矉 594 | 瞚 595 | 眝 596 | 睆 597 | 睕 598 | 瞎 599 | 瞭 600 | 睎 601 | 眱 602 | 眈 603 | 瞣 604 | 瞶 605 | 蜰 606 | 眺 607 | 剛 608 | 眒 609 | 瞜 610 | 矐 611 | 盱 612 | 睚 613 | 盰 614 | 瞰 615 | 眄 616 | 眃 617 | 盯 618 | 瞟 619 | 瞫 620 | 眐 621 | 睌 622 | 矎 623 | 瞻 624 | 瞲 625 | 眵 626 | 眳 627 | 睽 628 | 瞪 629 | 瞿 630 | 睢 631 | 膗 632 | 矍 633 | 瞧 634 | 眕 635 | 瞺 636 | 睔 637 | 睮 638 | 瞼 639 | 盵 640 | 瞴 641 | 眴 642 | 盷 643 | 盹 644 | 睛 645 | 瞡 646 | 睊 647 | 矂 648 | 眠 649 | 眧 650 | 眲 651 | 眶 652 | 矚 653 | 瞙 654 | 矇 655 | 瞨 656 | 眹 657 | 瞞 658 | 瞱 659 | 眻 660 | 矔 661 | 瞄 662 | 朏 663 | 胐 664 | 矊 665 | 眑 666 | 鼎 667 | 睩 668 | 睏 669 | 矓 670 | 瞇 671 | 睟 672 | 瞳 673 | 瞕 674 | 瞝 675 | 盳 676 | 眩 677 | 妥 678 | 墾 679 | 鸚 680 | 膷 681 | 奚 682 | 郻 683 | 腞 684 | 懇 685 | 臘 686 | 腦 687 | 膕 688 | 胭 689 | 胛 690 | 腢 691 | 爵 692 | 臅 693 | 腲 694 | 膃 695 | 腮 696 | 丹 697 | 腿 698 | 膼 699 | 朧 700 | 膀 701 | 鴅 702 | 彤 703 | 肮 704 | 膇 705 | 肪 706 | 膱 707 | 膟 708 | 刐 709 | 脺 710 | 腋 711 | 臄 712 | 臚 713 | 脝 714 | 腤 715 | 朣 716 | 膧 717 | 雘 718 | 臆 719 | 臃 720 | 胘 721 | 胲 722 | 膻 723 | 臍 724 | 金 725 | 鈤 726 | 錩 727 | 鎤 728 | 鉭 729 | 鍚 730 | 銲 731 | 鍉 732 | 甑 733 | 鍆 734 | 鄫 735 | 鑭 736 | 錫 737 | 錕 738 | 鍻 739 | 鎉 740 | 鑤 741 | 鈀 742 | 銀 743 | 鏝 744 | 鈅 745 | 錋 746 | 鑀 747 | 鍋 748 | 鍘 749 | 鋝 750 | 錭 751 | 鍕 752 | 鉏 753 | 鍰 754 | 銅 755 | 鋤 756 | 錚 757 | 鋼 758 | 鉬 759 | 鋇 760 | 钁 761 | 鋧 762 | 鑫 763 | 鈆 764 | 銻 765 | 鋊 766 | 鉛 767 | 銳 768 | 鈖 769 | 釮 770 | 鈹 771 | 鈌 772 | 鋉 773 | 鍏 774 | 錸 775 | 鍊 776 | 錔 777 | 鐋 778 | 鎟 779 | 錣 780 | 鎃 781 | 釵 782 | 鈥 783 | 銷 784 | 鎖 785 | 鏿 786 | 钂 787 | 鏜 788 | 鋿 789 | 鎲 790 | 鐺 791 | 銤 792 | 鏻 793 | 錟 794 | 鑅 795 | 鐒 796 | 鈔 797 | 銧 798 | 鉡 799 | 錈 800 | 釷 801 | 錂 802 | 錴 803 | 銈 804 | 鐃 805 | 鉣 806 | 鎑 807 | 鑄 808 | 鋕 809 | 銡 810 | 鎱 811 | 鉑 812 | 錦 813 | 鍠 814 | 鉌 815 | 鏼 816 | 鍬 817 | 銹 818 | 鋓 819 | 鐇 820 | 鈑 821 | 鋒 822 | 鉻 823 | 鉖 824 | 銩 825 | 鋯 826 | 銑 827 | 鵜 828 | 鳻 829 | 鑗 830 | 釤 831 | 錍 832 | 鉚 833 | 鎦 834 | 銖 835 | 鍛 836 | 鍾 837 | 錘 838 | 銛 839 | 鍎 840 | 鍤 841 | 鑕 842 | 剃 843 | 釽 844 | 頒 845 | 釿 846 | 銗 847 | 釩 848 | 邠 849 | 攽 850 | 鏦 851 | 錉 852 | 鋨 853 | 鉎 854 | 鎢 855 | 鑽 856 | 鎳 857 | 鎴 858 | 鈲 859 | 鎞 860 | 鎪 861 | 銵 862 | 公 863 | 鋃 864 | 鎛 865 | 鋑 866 | 鏚 867 | 銊 868 | 鉾 869 | 鍼 870 | 鋮 871 | 鈗 872 | 錢 873 | 鏒 874 | 鎯 875 | 鋪 876 | 鉥 877 | 銶 878 | 鈸 879 | 鏞 880 | 鏮 881 | 銂 882 | 鎕 883 | 頌 884 | 瓮 885 | 銢 886 | 釴 887 | 鑣 888 | 鉽 889 | 鋱 890 | 鈶 891 | 翁 892 | 鐮 893 | 鍍 894 | 鏣 895 | 鉞 896 | 鏕 897 | 針 898 | 鎮 899 | 鋍 900 | 鎍 901 | 鎔 902 | 鐵 903 | 鏄 904 | 鏸 905 | 鍺 906 | 鋐 907 | 銠 908 | 銬 909 | 鑌 910 | 鏔 911 | 錝 912 | 鍹 913 | 錠 914 | 鎵 915 | 鋎 916 | 鋺 917 | 鉈 918 | 鑏 919 | 鈷 920 | 錧 921 | 鐼 922 | 鑳 923 | 銨 924 | 父 925 | 釱 926 | 爸 927 | 銪 928 | 鎩 929 | 鐐 930 | 鍷 931 | 斧 932 | 鈜 933 | 鈦 934 | 錛 935 | 鈽 936 | 銌 937 | 錼 938 | 釜 939 | 錡 940 | 銙 941 | 銕 942 | 釚 943 | 爹 944 | 鋏 945 | 爺 946 | 丫 947 | 鉠 948 | 鈂 949 | 釧 950 | 鐀 951 | 銚 952 | 釗 953 | 鐨 954 | 鈾 955 | 鏤 956 | 鏽 957 | 釭 958 | 銆 959 | 鑐 960 | 顉 961 | 鐳 962 | 釪 963 | 鑈 964 | 鋄 965 | 銔 966 | 鈺 967 | 鑩 968 | 鶲 969 | 銍 970 | 釬 971 | 錏 972 | 鋙 973 | 釫 974 | 鋠 975 | 釘 976 | 鈳 977 | 憌 978 | 鉐 979 | 鎘 980 | 鋀 981 | 鈃 982 | 鉶 983 | 鐕 984 | 鎒 985 | 鋞 986 | 兮 987 | 鏢 988 | 鐔 989 | 鉦 990 | 鈣 991 | 釔 992 | 鐌 993 | 銫 994 | 釨 995 | 錳 996 | 鈕 997 | 鐍 998 | 鍒 999 | 鈒 1000 | 釢 1001 | 錎 1002 | 釸 1003 | 鏹 1004 | 鉹 1005 | 銘 1006 | 鋌 1007 | 鋋 1008 | 鍵 1009 | 鈏 1010 | 弚 1011 | 弟 1012 | 鐊 1013 | 錒 1014 | 釕 1015 | 欽 1016 | 鏺 1017 | 鐙 1018 | 鑱 1019 | 鍑 1020 | 鈉 1021 | 銝 1022 | 錐 1023 | 鏶 1024 | 鐎 1025 | 鎨 1026 | 鐫 1027 | 銋 1028 | 鈴 1029 | 鑯 1030 | 鈐 1031 | 鎗 1032 | 鋡 1033 | 鉓 1034 | 鎀 1035 | 螸 1036 | 鑰 1037 | 錀 1038 | 銓 1039 | 鐱 1040 | 鉿 1041 | 釳 1042 | 鎎 1043 | 鍭 1044 | 銼 1045 | 慾 1046 | 谷 1047 | 鋂 1048 | 鈊 1049 | 鉍 1050 | 釣 1051 | 鈞 1052 | 鋾 1053 | 鈚 1054 | 鍇 1055 | 鉤 1056 | 鉋 1057 | 鍱 1058 | 鈍 1059 | 鍧 1060 | 銇 1061 | 鍥 1062 | 鏏 1063 | 錆 1064 | 錶 1065 | 鈇 1066 | 釦 1067 | 鋗 1068 | 鵒 1069 | 鋁 1070 | 兌 1071 | 谾 1072 | 谹 1073 | 豃 1074 | 郤 1075 | 欲 1076 | 谻 1077 | 谽 1078 | 懖 1079 | 鐰 1080 | 鍔 1081 | 卻 1082 | 豂 1083 | 谼 1084 | 鐉 1085 | 鋘 1086 | 鈱 1087 | 豅 1088 | 鍜 1089 | 鏗 1090 | 分 1091 | 貧 1092 | 炃 1093 | 坌 1094 | 忿 1095 | 鉊 1096 | 盆 1097 | 弅 1098 | 岔 1099 | 鑑 1100 | 鉺 1101 | 鋷 1102 | 鑷 1103 | 鋸 1104 | 鉔 1105 | 鋟 1106 | 鏐 1107 | 鉰 1108 | 鋹 1109 | 鈮 1110 | 鎷 1111 | 鏂 1112 | 鉅 1113 | 鋦 1114 | 钃 1115 | 錯 1116 | 鏌 1117 | 錪 1118 | 鏾 1119 | 鐠 1120 | 鏷 1121 | 鎰 1122 | 鑮 1123 | 鑆 1124 | 鎂 1125 | 鑉 1126 | 錓 1127 | 鑶 1128 | 鉗 1129 | 錤 1130 | 鏵 1131 | 鍖 1132 | 鑊 1133 | 錵 1134 | 鎝 1135 | 鐷 1136 | 鎈 1137 | 鑵 1138 | 鍣 1139 | 鉼 1140 | 鎙 1141 | 鎡 1142 | 錨 1143 | 鐏 1144 | 鎌 1145 | 鑝 1146 | 鋩 1147 | 釓 1148 | 鍐 1149 | 毤 1150 | 錌 1151 | 鎧 1152 | 鑴 1153 | 鏙 1154 | 敓 1155 | 釹 1156 | 鐑 1157 | 鑠 1158 | 鐖 1159 | 鉯 1160 | 鏘 1161 | 錄 1162 | 銣 1163 | 鑞 1164 | 錙 1165 | 鈿 1166 | 曾 1167 | 錁 1168 | 鋰 1169 | 錮 1170 | 銦 1171 | 鉀 1172 | 鑼 1173 | 鐲 1174 | 鐸 1175 | 鐶 1176 | 鍡 1177 | 鍶 1178 | 鏎 1179 | 鏍 1180 | 鑸 1181 | 鉧 1182 | 釙 1183 | 鍗 1184 | 鐹 1185 | 鍞 1186 | 钀 1187 | 鑨 1188 | 鎊 1189 | 鏑 1190 | 鉸 1191 | 鐓 1192 | 鈙 1193 | 鉒 1194 | 鐽 1195 | 鏟 1196 | 鈧 1197 | 鎚 1198 | 鈁 1199 | 銥 1200 | 錥 1201 | 銃 1202 | 鈄 1203 | 鏈 1204 | 鈰 1205 | 錹 1206 | 鐬 1207 | 鉲 1208 | 鏬 1209 | 鐻 1210 | 鑢 1211 | 鐪 1212 | 鑪 1213 | 鉆 1214 | 鎬 1215 | 錞 1216 | 鑲 1217 | 鏃 1218 | 鏇 1219 | 鐘 1220 | 鋅 1221 | 鐩 1222 | 鐿 1223 | 鏡 1224 | 鉉 1225 | 鏀 1226 | 鑇 1227 | 木 1228 | 杳 1229 | 榥 1230 | 榯 1231 | 楣 1232 | 楖 1233 | 概 1234 | 查 1235 | 柦 1236 | 楊 1237 | 桿 1238 | 橍 1239 | 櫚 1240 | 欄 1241 | 棍 1242 | 楬 1243 | 榻 1244 | 杷 1245 | 根 1246 | 槾 1247 | 朿 1248 | 榠 1249 | 棚 1250 | 榾 1251 | 棎 1252 | 櫻 1253 | 棌 1254 | 棘 1255 | 棗 1256 | 椆 1257 | 槄 1258 | 楎 1259 | 橪 1260 | 刺 1261 | 柤 1262 | 椇 1263 | 楥 1264 | 桐 1265 | 桴 1266 | 僰 1267 | 榣 1268 | 棦 1269 | 棴 1270 | 柵 1271 | 棡 1272 | 相 1273 | 梖 1274 | 欋 1275 | 桵 1276 | 榽 1277 | 朳 1278 | 檭 1279 | 椕 1280 | 松 1281 | 棇 1282 | 枍 1283 | 梯 1284 | 梲 1285 | 枌 1286 | 橧 1287 | 林 1288 | 楂 1289 | 栜 1290 | 鬱 1291 | 棼 1292 | 森 1293 | 檚 1294 | 櫇 1295 | 焚 1296 | 埜 1297 | 材 1298 | 柀 1299 | 彬 1300 | 梵 1301 | 檒 1302 | 村 1303 | 麓 1304 | 枺 1305 | 樊 1306 | 蠜 1307 | 礬 1308 | 攀 1309 | 梀 1310 | 楋 1311 | 樕 1312 | 禁 1313 | 椲 1314 | 郴 1315 | 楚 1316 | 棽 1317 | 棶 1318 | 懋 1319 | 婪 1320 | 棟 1321 | 榃 1322 | 楝 1323 | 棳 1324 | -------------------------------------------------------------------------------- /assets/emoji.txt: -------------------------------------------------------------------------------- 1 | 🐀 2 | 🐁 3 | 🐂 4 | 🐃 5 | 🐄 6 | 🐅 7 | 🐆 8 | 🐇 9 | 🐈 10 | 🐉 11 | 🐊 12 | 🐋 13 | 🐌 14 | 🐍 15 | 🐎 16 | 🐏 17 | 🐐 18 | 🐑 19 | 🐒 20 | 🐓 21 | 🐔 22 | 🐕 23 | 🐖 24 | 🐗 25 | 🐘 26 | 🐙 27 | 🐚 28 | 🐛 29 | 🐜 30 | 🐝 31 | 🐞 32 | 🐟 33 | 🐠 34 | 🐡 35 | 🐢 36 | 🐣 37 | 🐤 38 | 🐥 39 | 🐦 40 | 🐧 41 | 🐨 42 | 🐩 43 | 🐪 44 | 🐫 45 | 🐬 46 | 🐭 47 | 🐮 48 | 🐯 49 | 🐰 50 | 🐱 51 | 🐲 52 | 🐳 53 | 🐴 54 | 🐵 55 | 🐶 56 | 🐷 57 | 🐸 58 | 🐹 59 | 🐺 60 | 🐻 61 | 🐼 62 | 🐽 63 | 🐾 64 | 🐿 65 | -------------------------------------------------------------------------------- /assets/ff.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SOF3/include-flate/fe2e11382dec8f6628d52753cfbac8b2a3b33609/assets/ff.dat -------------------------------------------------------------------------------- /assets/random.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SOF3/include-flate/fe2e11382dec8f6628d52753cfbac8b2a3b33609/assets/random.dat -------------------------------------------------------------------------------- /codegen/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "include-flate-codegen" 3 | version = "0.3.0" 4 | authors = ["SOFe "] 5 | edition = "2021" 6 | license = "Apache-2.0" 7 | repository = "https://github.com/SOF3/include-flate.git" 8 | homepage = "https://github.com/SOF3/include-flate" 9 | description = "Macro codegen for the include-flate crate" 10 | 11 | [lib] 12 | proc-macro = true 13 | 14 | [dependencies] 15 | libflate = "2.0.0" 16 | proc-macro2 = "1.0.9" 17 | quote = "1.0.2" 18 | syn = { version = "2.0.2", features = ["full"] } 19 | zstd = "0.13.0" 20 | include-flate-compress = { version = "0.3.0", path = "../compress" } 21 | proc-macro-error = "1.0.4" 22 | 23 | [features] 24 | default = [] 25 | no-compression-warnings = [] 26 | -------------------------------------------------------------------------------- /codegen/src/lib.rs: -------------------------------------------------------------------------------- 1 | // include-flate 2 | // Copyright (C) SOFe 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | extern crate proc_macro; 17 | 18 | use std::fs::{self, File}; 19 | use std::io::{Read, Seek}; 20 | use std::path::PathBuf; 21 | use std::str::{from_utf8, FromStr}; 22 | 23 | use include_flate_compress::{apply_compression, CompressionMethod}; 24 | use proc_macro::TokenStream; 25 | use proc_macro2::Span; 26 | use proc_macro_error::{emit_warning, proc_macro_error}; 27 | use quote::quote; 28 | use syn::{Error, LitByteStr}; 29 | 30 | /// `deflate_file!("file")` is equivalent to `include_bytes!("file.gz")`. 31 | /// 32 | /// # Parameters 33 | /// This macro accepts exactly one literal parameter that refers to a path relative to 34 | /// `CARGO_MANIFEST_DIR`. Absolute paths are not supported. 35 | /// 36 | /// Note that **this is distinct from the behaviour of the builtin `include_bytes!`/`include_str!` macros** — 37 | /// `includle_bytes!`/`include_str!` paths are relative to the current source file, while `deflate_file!` paths are relative to 38 | /// `CARGO_MANIFEST_DIR`. 39 | /// 40 | /// # Returns 41 | /// This macro expands to a `b"byte string"` literal that contains the deflated form of the file. 42 | /// 43 | /// # Compile errors 44 | /// - If the argument is not a single literal 45 | /// - If the referenced file does not exist or is not readable 46 | #[proc_macro] 47 | #[proc_macro_error] 48 | pub fn deflate_file(ts: TokenStream) -> TokenStream { 49 | match inner(ts, false) { 50 | Ok(ts) => ts.into(), 51 | Err(err) => err.to_compile_error().into(), 52 | } 53 | } 54 | 55 | /// This macro is identical to `deflate_file!()`, except it additionally performs UTF-8 validation. 56 | /// 57 | /// # Compile errors 58 | /// - The compile errors in `deflate_file!` 59 | /// - If the file contents are not all valid UTF-8 60 | #[proc_macro] 61 | #[proc_macro_error] 62 | pub fn deflate_utf8_file(ts: TokenStream) -> TokenStream { 63 | match inner(ts, true) { 64 | Ok(ts) => ts.into(), 65 | Err(err) => err.to_compile_error().into(), 66 | } 67 | } 68 | 69 | /// An arguments expected provided by the proc-macro. 70 | /// 71 | /// ```ignore 72 | /// flate!(pub static DATA: [u8] from "assets/009f.dat"); // default, DEFLATE 73 | /// flate!(pub static DATA: [u8] from "assets/009f.dat" with zstd); // Use Zstd for this file spcifically 74 | /// flate!(pub static DATA: [u8] from "assets/009f.dat" with deflate); // Explicitly use DEFLATE. 75 | /// ``` 76 | struct FlateArgs { 77 | path: syn::LitStr, 78 | algorithm: Option, 79 | } 80 | 81 | impl syn::parse::Parse for FlateArgs { 82 | fn parse(input: syn::parse::ParseStream) -> syn::Result { 83 | let path = input.parse()?; 84 | 85 | let algorithm = if input.is_empty() { 86 | None 87 | } else { 88 | let lookahead = input.lookahead1(); 89 | if lookahead.peek(kw::deflate) { 90 | input.parse::()?; 91 | Some(CompressionMethodTy(CompressionMethod::Deflate)) 92 | } else if lookahead.peek(kw::zstd) { 93 | input.parse::()?; 94 | Some(CompressionMethodTy(CompressionMethod::Zstd)) 95 | } else { 96 | return Err(lookahead.error()); 97 | } 98 | }; 99 | 100 | Ok(Self { path, algorithm }) 101 | } 102 | } 103 | 104 | mod kw { 105 | syn::custom_keyword!(deflate); 106 | syn::custom_keyword!(zstd); 107 | } 108 | 109 | #[derive(Debug)] 110 | struct CompressionMethodTy(CompressionMethod); 111 | 112 | fn compression_ratio(original_size: u64, compressed_size: u64) -> f64 { 113 | (compressed_size as f64 / original_size as f64) * 100.0 114 | } 115 | 116 | fn inner(ts: TokenStream, utf8: bool) -> syn::Result> { 117 | fn emap(error: E) -> Error { 118 | Error::new(Span::call_site(), error) 119 | } 120 | 121 | let dir = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").map_err(emap)?); 122 | 123 | let args: FlateArgs = syn::parse2::(ts.to_owned().into())?; 124 | let path = PathBuf::from_str(&args.path.value()).map_err(emap)?; 125 | let algo = args 126 | .algorithm 127 | .unwrap_or(CompressionMethodTy(CompressionMethod::Deflate)); 128 | 129 | if path.is_absolute() { 130 | Err(emap("absolute paths are not supported"))?; 131 | } 132 | 133 | let target = dir.join(&path); 134 | 135 | let mut file = File::open(&target).map_err(emap)?; 136 | 137 | let mut vec = Vec::::new(); 138 | if utf8 { 139 | std::io::copy(&mut file, &mut vec).map_err(emap)?; 140 | from_utf8(&vec).map_err(emap)?; 141 | } 142 | 143 | let mut compressed_buffer = Vec::::new(); 144 | 145 | { 146 | let mut compressed_cursor = std::io::Cursor::new(&mut compressed_buffer); 147 | let mut source: Box = if utf8 { 148 | Box::new(std::io::Cursor::new(vec)) 149 | } else { 150 | file.seek(std::io::SeekFrom::Start(0)).map_err(emap)?; 151 | Box::new(&file) 152 | }; 153 | 154 | apply_compression(&mut source, &mut compressed_cursor, algo.0).map_err(emap)?; 155 | } 156 | 157 | let bytes = LitByteStr::new(&compressed_buffer, Span::call_site()); 158 | let result = quote!(#bytes); 159 | 160 | #[cfg(not(feature = "no-compression-warnings"))] 161 | { 162 | let compression_ratio = compression_ratio( 163 | fs::metadata(&target).map_err(emap)?.len(), 164 | compressed_buffer.len() as u64, 165 | ); 166 | 167 | if compression_ratio < 10.0f64 { 168 | emit_warning!( 169 | &args.path, 170 | "Detected low compression ratio ({:.2}%) for file {:?} with `{:?}`. Consider using other compression methods.", 171 | compression_ratio, 172 | path.display(), 173 | algo.0, 174 | ); 175 | } 176 | } 177 | 178 | Ok(result) 179 | } 180 | -------------------------------------------------------------------------------- /compress/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "include-flate-compress" 3 | version = "0.3.0" 4 | authors = ["SOFe ", "Kento Oki "] 5 | edition = "2021" 6 | license = "Apache-2.0" 7 | repository = "https://github.com/SOF3/include-flate.git" 8 | homepage = "https://github.com/SOF3/include-flate" 9 | description = "Compression algorithm provider" 10 | 11 | [dependencies] 12 | libflate = { version = "2.0.0", optional = true } 13 | zstd = { version = "0.13.0", optional = true } 14 | 15 | [features] 16 | default = ["deflate", "zstd"] 17 | deflate = ["dep:libflate"] 18 | zstd = ["dep:zstd"] 19 | -------------------------------------------------------------------------------- /compress/src/lib.rs: -------------------------------------------------------------------------------- 1 | // include-flate 2 | // Copyright (C) SOFe, Kento Oki 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | #[cfg(not(any(feature = "zstd", feature = "deflate")))] 17 | compile_error!("You must enable either the `deflate` or `zstd` feature."); 18 | 19 | use std::{ 20 | fmt, 21 | io::{self, BufRead, BufReader, Read, Seek, Write}, 22 | }; 23 | 24 | #[cfg(feature = "deflate")] 25 | use libflate::deflate::Decoder as DeflateDecoder; 26 | #[cfg(feature = "deflate")] 27 | use libflate::deflate::Encoder as DeflateEncoder; 28 | #[cfg(feature = "zstd")] 29 | use zstd::Decoder as ZstdDecoder; 30 | #[cfg(feature = "zstd")] 31 | use zstd::Encoder as ZstdEncoder; 32 | 33 | #[derive(Debug)] 34 | pub enum FlateCompressionError { 35 | #[cfg(feature = "deflate")] 36 | DeflateError(io::Error), 37 | #[cfg(feature = "zstd")] 38 | ZstdError(io::Error), 39 | IoError(io::Error), 40 | } 41 | 42 | impl From for FlateCompressionError { 43 | fn from(err: io::Error) -> Self { 44 | FlateCompressionError::IoError(err) 45 | } 46 | } 47 | 48 | impl fmt::Display for FlateCompressionError { 49 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 50 | match self { 51 | #[cfg(feature = "deflate")] 52 | FlateCompressionError::DeflateError(err) => write!(f, "Deflate error: {}", err), 53 | #[cfg(feature = "zstd")] 54 | FlateCompressionError::ZstdError(err) => write!(f, "Zstd error: {}", err), 55 | FlateCompressionError::IoError(err) => write!(f, "I/O error: {}", err), 56 | } 57 | } 58 | } 59 | 60 | #[derive(Debug, Copy, Clone)] 61 | pub enum CompressionMethod { 62 | #[cfg(feature = "deflate")] 63 | Deflate, 64 | #[cfg(feature = "zstd")] 65 | Zstd, 66 | } 67 | 68 | impl CompressionMethod { 69 | pub fn encoder<'a, W: BufRead + Write + Seek + 'a>( 70 | &'a self, 71 | write: W, 72 | ) -> Result, FlateCompressionError> { 73 | FlateEncoder::new(*self, write) 74 | } 75 | 76 | pub fn decoder<'a, R: ReadSeek + 'a>( 77 | &'a self, 78 | read: R, 79 | ) -> Result, FlateCompressionError> { 80 | FlateDecoder::new(*self, Box::new(read)) 81 | } 82 | } 83 | 84 | #[cfg(any(feature = "deflate", feature = "zstd"))] 85 | impl Default for CompressionMethod { 86 | fn default() -> Self { 87 | #[cfg(feature = "deflate")] 88 | { 89 | Self::Deflate 90 | } 91 | #[cfg(all(not(feature = "deflate"), feature = "zstd"))] 92 | { 93 | Self::Zstd 94 | } 95 | } 96 | } 97 | 98 | pub enum FlateEncoder { 99 | #[cfg(feature = "deflate")] 100 | Deflate(DeflateEncoder), 101 | #[cfg(feature = "zstd")] 102 | Zstd(ZstdEncoder<'static, W>), 103 | } 104 | 105 | impl<'a, W: BufRead + Write + Seek + 'a> FlateEncoder { 106 | pub fn new( 107 | method: CompressionMethod, 108 | write: W, 109 | ) -> Result, FlateCompressionError> { 110 | match method { 111 | #[cfg(feature = "deflate")] 112 | CompressionMethod::Deflate => Ok(FlateEncoder::Deflate(DeflateEncoder::new(write))), 113 | #[cfg(feature = "zstd")] 114 | CompressionMethod::Zstd => ZstdEncoder::new(write, 0) 115 | .map(FlateEncoder::Zstd) 116 | .map_err(|e| FlateCompressionError::ZstdError(e)), 117 | } 118 | } 119 | } 120 | 121 | impl<'a, W: Write + 'a> Write for FlateEncoder { 122 | fn write(&mut self, buf: &[u8]) -> io::Result { 123 | match self { 124 | #[cfg(feature = "deflate")] 125 | FlateEncoder::Deflate(encoder) => encoder.write(buf), 126 | #[cfg(feature = "zstd")] 127 | FlateEncoder::Zstd(encoder) => encoder.write(buf), 128 | } 129 | } 130 | 131 | fn flush(&mut self) -> io::Result<()> { 132 | match self { 133 | #[cfg(feature = "deflate")] 134 | FlateEncoder::Deflate(encoder) => encoder.flush(), 135 | #[cfg(feature = "zstd")] 136 | FlateEncoder::Zstd(encoder) => encoder.flush(), 137 | } 138 | } 139 | } 140 | 141 | impl<'a, W: Write + 'a> FlateEncoder { 142 | fn finish_encode(self) -> Result { 143 | match self { 144 | #[cfg(feature = "deflate")] 145 | FlateEncoder::Deflate(encoder) => encoder 146 | .finish() 147 | .into_result() 148 | .map_err(|e| FlateCompressionError::DeflateError(e)), 149 | #[cfg(feature = "zstd")] 150 | FlateEncoder::Zstd(encoder) => encoder 151 | .finish() 152 | .map_err(|e| FlateCompressionError::ZstdError(e)), 153 | } 154 | } 155 | } 156 | 157 | pub trait ReadSeek: BufRead + Seek {} 158 | 159 | impl ReadSeek for T {} 160 | 161 | pub enum FlateDecoder<'a> { 162 | #[cfg(feature = "deflate")] 163 | Deflate(DeflateDecoder>), 164 | #[cfg(feature = "zstd")] 165 | Zstd(ZstdDecoder<'a, BufReader>>), 166 | } 167 | 168 | impl<'a> FlateDecoder<'a> { 169 | pub fn new( 170 | method: CompressionMethod, 171 | read: Box, 172 | ) -> Result, FlateCompressionError> { 173 | match method { 174 | #[cfg(feature = "deflate")] 175 | CompressionMethod::Deflate => Ok(FlateDecoder::Deflate(DeflateDecoder::new(read))), 176 | #[cfg(feature = "zstd")] 177 | CompressionMethod::Zstd => { 178 | let decoder = ZstdDecoder::new(read)?; 179 | Ok(FlateDecoder::Zstd(decoder)) 180 | } 181 | } 182 | } 183 | } 184 | 185 | impl<'a> Read for FlateDecoder<'a> { 186 | fn read(&mut self, buf: &mut [u8]) -> io::Result { 187 | match self { 188 | #[cfg(feature = "deflate")] 189 | FlateDecoder::Deflate(decoder) => decoder.read(buf), 190 | #[cfg(feature = "zstd")] 191 | FlateDecoder::Zstd(decoder) => decoder.read(buf), 192 | } 193 | } 194 | } 195 | 196 | pub fn apply_compression( 197 | reader: &mut R, 198 | writer: &mut W, 199 | method: CompressionMethod, 200 | ) -> Result<(), FlateCompressionError> 201 | where 202 | R: Read, 203 | W: Write, 204 | { 205 | let mut encoder = method.encoder(writer)?; 206 | io::copy(reader, &mut encoder)?; 207 | encoder.finish_encode().map(|_| ()) 208 | } 209 | 210 | pub fn apply_decompression( 211 | reader: &mut R, 212 | writer: &mut W, 213 | method: CompressionMethod, 214 | ) -> Result<(), FlateCompressionError> 215 | where 216 | R: Read, 217 | W: Write, 218 | { 219 | let mut decoder = method.decoder(reader)?; 220 | io::copy(&mut decoder, writer)?; 221 | Ok(()) 222 | } 223 | -------------------------------------------------------------------------------- /fail_tests/009f-str.rs: -------------------------------------------------------------------------------- 1 | // include-flate 2 | // Copyright (C) SOFe 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | include!("../test_util.rs"); 17 | 18 | use include_flate::flate; 19 | 20 | flate!(pub static DATA: str from "assets/009f.dat"); 21 | flate!(pub static DATA: str from "assets/009f.dat" with deflate); 22 | flate!(pub static DATA: str from "assets/009f.dat" with zstd); 23 | 24 | #[test] 25 | fn test() { 26 | verify_str("009f.dat", &DATA); 27 | } 28 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | // include-flate 2 | // Copyright (C) SOFe 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! A variant of `include_bytes!`/`include_str!` with compile-time deflation and runtime lazy inflation. 17 | //! 18 | //! ## Why? 19 | //! `include_bytes!`/`include_str!` are great for embedding resources into an executable/library 20 | //! without involving the complex logistics of maintaining an assets manager. 21 | //! However, they are copied as-is into the artifact, leading to unnecessarily large binary size. 22 | //! This library automatically compresses the resources and lazily decompresses them at runtime, 23 | //! allowing smaller binary sizes. 24 | //! 25 | //! Nevertheless, this inevitably leads to wasting RAM to store both the compressed and decompressed data, 26 | //! which might be undesirable if the data are too large. 27 | //! An actual installer is still required if the binary involves too many resources that do not need to be kept in RAM all time. 28 | 29 | /// The low-level macros used by this crate. 30 | pub use include_flate_codegen as codegen; 31 | use include_flate_compress::apply_decompression; 32 | 33 | #[doc(hidden)] 34 | pub use include_flate_compress::CompressionMethod; 35 | 36 | #[doc(hidden)] 37 | pub use once_cell::sync::Lazy; 38 | 39 | /// This macro is like [`include_bytes!`][1] or [`include_str!`][2], but compresses at compile time 40 | /// and lazily decompresses at runtime. 41 | /// 42 | /// # Parameters 43 | /// The macro can be used like this: 44 | /// ```ignore 45 | /// flate!($meta $vis static $name: $type from $file); 46 | /// ``` 47 | /// 48 | /// - `$meta` is zero or more `#[...]` attributes that can be applied on the static parameters of 49 | /// `lazy_static`. For the actual semantics of the meta attributes, please refer to 50 | /// [`lazy_static`][3] documentation. 51 | /// - `$vis` is a visibility modifier (e.g. `pub`, `pub(crate)`) or empty. 52 | /// - `$name` is the name of the static variable.. 53 | /// - `$type` can be either `[u8]` or `str`. However, the actual type created would dereference 54 | /// into `Vec` and `String` (although they are `AsRef<[u8]>` and `AsRef`) respectively. 55 | /// - `$file` is a path relative to the current [`CARGO_MANIFEST_DIR`][4]. Absolute paths are not supported. 56 | /// Note that **this is distinct from the behaviour of the builtin `include_bytes!`/`include_str!` 57 | /// macros** — `includle_bytes!`/`include_str!` paths are relative to the current source file, 58 | /// while `flate!` paths are relative to `CARGO_MANIFEST_DIR`. 59 | /// 60 | /// # Returns 61 | /// The macro expands to a [`lazy_static`][3] call, which lazily inflates the compressed bytes. 62 | /// 63 | /// # Compile errors 64 | /// - If the input format is incorrect 65 | /// - If the referenced file does not exist or is not readable 66 | /// - If `$type` is `str` but the file is not fully valid UTF-8 67 | /// 68 | /// # Algorithm 69 | /// Compression and decompression use the DEFLATE algorithm from [`libflate`][5]. 70 | /// 71 | /// # Examples 72 | /// Below are some basic examples. For actual compiled examples, see the [`tests`][6] directory. 73 | /// 74 | /// ```ignore 75 | /// // This declares a `static VAR_NAME: impl Deref>` 76 | /// flate!(static VAR_NAME: [u8] from "binary-file.dat"); 77 | /// 78 | /// // This declares a `static VAR_NAME: impl Deref` 79 | /// flate!(static VAR_NAME: str from "text-file.txt"); 80 | /// 81 | /// // Visibility modifiers can be added in the front 82 | /// flate!(pub static VAR_NAME: str from "public-file.txt"); 83 | /// 84 | /// // Meta attributes can also be added 85 | /// flate!(#[allow(unused)] 86 | /// #[doc = "Example const"] 87 | /// pub static VAR_NAME: str from "file.txt"); 88 | /// ``` 89 | /// 90 | /// [1]: https://doc.rust-lang.org/std/macro.include_bytes.html 91 | /// [2]: https://doc.rust-lang.org/std/macro.include_str.html 92 | /// [3]: https://docs.rs/lazy_static/1.3.0/lazy_static/ 93 | /// [4]: https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates 94 | /// [5]: https://docs.rs/libflate/0.1.26/libflate/ 95 | /// [6]: https://github.com/SOF3/include-flate/tree/master/tests 96 | #[macro_export] 97 | macro_rules! flate { 98 | ($(#[$meta:meta])* 99 | $(pub $(($($vis:tt)+))?)? static $name:ident: [u8] from $path:literal $(with $algo:ident)?) => { 100 | // HACK: workaround to make cargo auto rebuild on modification of source file 101 | const _: &'static [u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/", $path)); 102 | 103 | $(#[$meta])* 104 | $(pub $(($($vis)+))?)? static $name: $crate::Lazy<::std::vec::Vec> = $crate::Lazy::new(|| { 105 | $crate::decode($crate::codegen::deflate_file!($path), None) 106 | }); 107 | }; 108 | ($(#[$meta:meta])* 109 | $(pub $(($($vis:tt)+))?)? static $name:ident: str from $path:literal $(with $algo:ident)?) => { 110 | // HACK: workaround to make cargo auto rebuild on modification of source file 111 | const _: &'static str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/", $path)); 112 | 113 | $(#[$meta])* 114 | $(pub $(($($vis)+))?)? static $name: $crate::Lazy<::std::string::String> = $crate::Lazy::new(|| { 115 | let algo = match stringify!($($algo)?){ 116 | "deflate" => $crate::CompressionMethod::Deflate, 117 | "zstd" => $crate::CompressionMethod::Zstd, 118 | _ => $crate::CompressionMethod::default(), 119 | }; 120 | $crate::decode_string($crate::codegen::deflate_utf8_file!($path $($algo)?), Some($crate::CompressionMethodTy(algo))) 121 | }); 122 | }; 123 | } 124 | 125 | #[derive(Debug)] 126 | pub struct CompressionMethodTy(pub CompressionMethod); 127 | 128 | impl Into for CompressionMethodTy { 129 | fn into(self) -> CompressionMethod { 130 | self.0 131 | } 132 | } 133 | 134 | #[doc(hidden)] 135 | #[allow(private_interfaces)] 136 | pub fn decode(bytes: &[u8], algo: Option) -> Vec { 137 | use std::io::Cursor; 138 | 139 | let algo: CompressionMethod = algo 140 | .unwrap_or(CompressionMethodTy(CompressionMethod::Deflate)) 141 | .into(); 142 | let mut source = Cursor::new(bytes); 143 | let mut ret = Vec::new(); 144 | 145 | match apply_decompression(&mut source, &mut ret, algo) { 146 | Ok(_) => {} 147 | Err(err) => panic!("Compiled `{:?}` buffer was corrupted: {:?}", algo, err), 148 | } 149 | 150 | ret 151 | } 152 | 153 | #[doc(hidden)] 154 | #[allow(private_interfaces)] 155 | pub fn decode_string(bytes: &[u8], algo: Option) -> String { 156 | // We should have checked for utf8 correctness in encode_utf8_file! 157 | String::from_utf8(decode(bytes, algo)) 158 | .expect("flate_str has malformed UTF-8 despite checked at compile time") 159 | } 160 | -------------------------------------------------------------------------------- /test_util.rs: -------------------------------------------------------------------------------- 1 | // include-flate 2 | // Copyright (C) SOFe 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | use std::fs::File; 17 | use std::io::{Read, Seek, SeekFrom}; 18 | use std::path::{Path, PathBuf}; 19 | use std::str::from_utf8; 20 | 21 | use include_flate_compress::{apply_compression, apply_decompression, CompressionMethod}; 22 | 23 | pub fn get_file_path>(relative_from: Option<&Path>, path: P) -> PathBuf { 24 | let cargo_manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap(); 25 | let default_base_path = Path::new(&cargo_manifest_dir); 26 | let base_path = relative_from.unwrap_or_else(|| default_base_path); 27 | base_path.join("assets").join(path) 28 | } 29 | 30 | pub fn read_file>(name: P) -> Vec { 31 | let path = get_file_path(None, name); 32 | let mut vec = Vec::::new(); 33 | std::io::copy(&mut File::open(path).unwrap(), &mut vec).unwrap(); 34 | vec 35 | } 36 | 37 | pub fn verify_compression>(name: P, data: &[u8], method: CompressionMethod) { 38 | let path = get_file_path(None, &name); 39 | let mut file = File::open(&path).unwrap(); 40 | let mut file_buffer = Vec::new(); 41 | file.read_to_end(&mut file_buffer).unwrap(); 42 | let mut source = std::io::Cursor::new(file_buffer); 43 | let mut compressed_buffer = Vec::new(); 44 | { 45 | let mut compressed_cursor = std::io::Cursor::new(&mut compressed_buffer); 46 | apply_compression(&mut source, &mut compressed_cursor, method).unwrap(); 47 | compressed_cursor.seek(SeekFrom::Start(0)).unwrap(); // Reset cursor position 48 | } 49 | assert_ne!(compressed_buffer.as_slice(), data); 50 | let mut decompressed_buffer = Vec::new(); 51 | { 52 | let mut compressed_cursor = std::io::Cursor::new(&mut compressed_buffer); 53 | let mut decompressed_cursor = std::io::Cursor::new(&mut decompressed_buffer); 54 | apply_decompression(&mut compressed_cursor, &mut decompressed_cursor, method).unwrap(); 55 | decompressed_cursor.seek(SeekFrom::Start(0)).unwrap(); // Reset cursor position 56 | } 57 | assert_ne!(compressed_buffer.as_slice(), decompressed_buffer.as_slice()); 58 | } 59 | 60 | pub fn verify>(name: P, data: &[u8]) { 61 | verify_compression(&name, data, CompressionMethod::Deflate); 62 | verify_compression(&name, data, CompressionMethod::Zstd); 63 | assert_eq!(read_file(&name), data); 64 | } 65 | 66 | pub fn verify_str(name: &str, data: &str) { 67 | // But the file should not have compiled in the first place 68 | assert_eq!( 69 | from_utf8(&read_file(name)).expect("File is not encoded"), 70 | data 71 | ); 72 | } 73 | -------------------------------------------------------------------------------- /tests/009f.rs: -------------------------------------------------------------------------------- 1 | // include-flate 2 | // Copyright (C) SOFe 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | include!("../test_util.rs"); 17 | 18 | use include_flate::flate; 19 | 20 | flate!(pub static DATA1: [u8] from "assets/009f.dat"); 21 | flate!(pub static DATA2: [u8] from "assets/009f.dat" with deflate); 22 | flate!(pub static DATA3: [u8] from "assets/009f.dat" with zstd); 23 | 24 | #[test] 25 | fn test() { 26 | verify("009f.dat", &DATA1); 27 | verify("009f.dat", &DATA2); 28 | verify("009f.dat", &DATA3); 29 | } 30 | -------------------------------------------------------------------------------- /tests/ascii-control.rs: -------------------------------------------------------------------------------- 1 | // include-flate 2 | // Copyright (C) SOFe 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | include!("../test_util.rs"); 17 | 18 | use include_flate::flate; 19 | 20 | flate!(pub static DATA1: str from "assets/ascii-printable.txt"); 21 | flate!(pub static DATA2: str from "assets/ascii-printable.txt" with deflate); 22 | flate!(pub static DATA3: str from "assets/ascii-printable.txt" with zstd); 23 | 24 | #[test] 25 | fn test() { 26 | verify_str("ascii-printable.txt", &DATA1); 27 | verify_str("ascii-printable.txt", &DATA2); 28 | verify_str("ascii-printable.txt", &DATA3); 29 | } 30 | -------------------------------------------------------------------------------- /tests/ascii-printable.rs: -------------------------------------------------------------------------------- 1 | // include-flate 2 | // Copyright (C) SOFe 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | include!("../test_util.rs"); 17 | 18 | use include_flate::flate; 19 | 20 | flate!(pub static DATA1: str from "assets/ascii-printable.txt"); 21 | flate!(pub static DATA2: str from "assets/ascii-printable.txt" with deflate); 22 | flate!(pub static DATA3: str from "assets/ascii-printable.txt" with zstd); 23 | 24 | #[test] 25 | fn test() { 26 | verify_str("ascii-printable.txt", &DATA1); 27 | verify_str("ascii-printable.txt", &DATA2); 28 | verify_str("ascii-printable.txt", &DATA3); 29 | } 30 | -------------------------------------------------------------------------------- /tests/base64-raw.rs: -------------------------------------------------------------------------------- 1 | // include-flate 2 | // Copyright (C) SOFe 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | include!("../test_util.rs"); 17 | 18 | pub static DATA: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/base64.txt")); 19 | 20 | #[test] 21 | fn test() { 22 | verify_str("base64.txt", DATA); 23 | } 24 | -------------------------------------------------------------------------------- /tests/base64.rs: -------------------------------------------------------------------------------- 1 | // include-flate 2 | // Copyright (C) SOFe 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | include!("../test_util.rs"); 17 | 18 | use include_flate::flate; 19 | 20 | flate!(pub static DATA1: str from "assets/base64.txt"); 21 | flate!(pub static DATA2: str from "assets/base64.txt" with deflate); 22 | flate!(pub static DATA3: str from "assets/base64.txt" with zstd); 23 | 24 | #[test] 25 | fn test() { 26 | verify_str("base64.txt", &DATA1); 27 | verify_str("base64.txt", &DATA2); 28 | verify_str("base64.txt", &DATA3); 29 | } 30 | -------------------------------------------------------------------------------- /tests/chinese.rs: -------------------------------------------------------------------------------- 1 | // include-flate 2 | // Copyright (C) SOFe 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | include!("../test_util.rs"); 17 | 18 | use include_flate::flate; 19 | 20 | flate!(pub static DATA1: str from "assets/chinese.txt"); 21 | flate!(pub static DATA2: str from "assets/chinese.txt" with deflate); 22 | flate!(pub static DATA3: str from "assets/chinese.txt" with zstd); 23 | 24 | #[test] 25 | fn test() { 26 | verify_str("chinese.txt", &DATA1); 27 | verify_str("chinese.txt", &DATA2); 28 | verify_str("chinese.txt", &DATA3); 29 | } 30 | -------------------------------------------------------------------------------- /tests/emoji.rs: -------------------------------------------------------------------------------- 1 | // include-flate 2 | // Copyright (C) SOFe 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | include!("../test_util.rs"); 17 | 18 | use include_flate::flate; 19 | 20 | flate!(pub static DATA1: str from "assets/emoji.txt"); 21 | flate!(pub static DATA2: str from "assets/emoji.txt" with deflate); 22 | flate!(pub static DATA3: str from "assets/emoji.txt" with zstd); 23 | 24 | #[test] 25 | fn test() { 26 | verify_str("emoji.txt", &DATA1); 27 | verify_str("emoji.txt", &DATA2); 28 | verify_str("emoji.txt", &DATA3); 29 | } 30 | -------------------------------------------------------------------------------- /tests/ff-raw.rs: -------------------------------------------------------------------------------- 1 | // include-flate 2 | // Copyright (C) SOFe 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | include!("../test_util.rs"); 17 | 18 | pub static DATA: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/ff.dat")); 19 | 20 | #[test] 21 | fn test() { 22 | verify("ff.dat", DATA); 23 | } 24 | -------------------------------------------------------------------------------- /tests/ff.rs: -------------------------------------------------------------------------------- 1 | // include-flate 2 | // Copyright (C) SOFe 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | include!("../test_util.rs"); 17 | 18 | use include_flate::flate; 19 | 20 | flate!(pub static DATA1: [u8] from "assets/ff.dat"); 21 | flate!(pub static DATA2: [u8] from "assets/ff.dat" with deflate); 22 | flate!(pub static DATA3: [u8] from "assets/ff.dat" with zstd); 23 | 24 | #[test] 25 | fn test() { 26 | verify("ff.dat", &DATA1); 27 | verify("ff.dat", &DATA2); 28 | verify("ff.dat", &DATA3); 29 | } 30 | -------------------------------------------------------------------------------- /tests/random-raw.rs: -------------------------------------------------------------------------------- 1 | // include-flate 2 | // Copyright (C) SOFe 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | include!("../test_util.rs"); 17 | 18 | pub static DATA: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/random.dat")); 19 | 20 | #[test] 21 | fn test() { 22 | verify("random.dat", DATA); 23 | } 24 | -------------------------------------------------------------------------------- /tests/random.rs: -------------------------------------------------------------------------------- 1 | // include-flate 2 | // Copyright (C) SOFe 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | include!("../test_util.rs"); 17 | 18 | use include_flate::flate; 19 | 20 | flate!(pub static DATA1: [u8] from "assets/random.dat"); 21 | flate!(pub static DATA2: [u8] from "assets/random.dat" with deflate); 22 | flate!(pub static DATA3: [u8] from "assets/random.dat" with zstd); 23 | 24 | #[test] 25 | fn test() { 26 | verify("random.dat", &DATA1); 27 | verify("random.dat", &DATA2); 28 | verify("random.dat", &DATA3); 29 | } 30 | -------------------------------------------------------------------------------- /tests/zero-raw.rs: -------------------------------------------------------------------------------- 1 | // include-flate 2 | // Copyright (C) SOFe 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | include!("../test_util.rs"); 17 | 18 | pub static DATA: &[u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/zero.dat")); 19 | 20 | #[test] 21 | fn test() { 22 | verify("zero.dat", DATA); 23 | } 24 | -------------------------------------------------------------------------------- /tests/zero.rs: -------------------------------------------------------------------------------- 1 | // include-flate 2 | // Copyright (C) SOFe 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | include!("../test_util.rs"); 17 | 18 | use include_flate::flate; 19 | 20 | flate!(pub static DATA1: [u8] from "assets/zero.dat"); 21 | flate!(pub static DATA2: [u8] from "assets/zero.dat" with deflate); 22 | flate!(pub static DATA3: [u8] from "assets/zero.dat" with zstd); 23 | 24 | #[test] 25 | fn test() { 26 | verify("zero.dat", &DATA1); 27 | verify("zero.dat", &DATA2); 28 | verify("zero.dat", &DATA3); 29 | } 30 | --------------------------------------------------------------------------------