├── .github └── workflows │ ├── ci.yml │ └── watch-upstream.yml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── assets └── tui-1.0.1.png └── src ├── bin └── main.rs ├── calculate.rs ├── lib.rs ├── prompt.rs ├── syntax.rs └── thread_loop.rs /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Build & test 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | env: 10 | CARGO_TERM_COLOR: always 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v2 17 | - name: Build 18 | run: cargo build --verbose 19 | - name: Run tests 20 | run: cargo test --verbose 21 | -------------------------------------------------------------------------------- /.github/workflows/watch-upstream.yml: -------------------------------------------------------------------------------- 1 | name: Watch upstream for new releases 2 | 3 | on: 4 | workflow_dispatch: 5 | schedule: 6 | # daily at 9am PDT 7 | - cron: '0 16 * * *' 8 | 9 | jobs: 10 | check-upstream: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/setup-python@v3 14 | with: 15 | python-version: '3.9' 16 | - name: install tomlq 17 | run: pip install yq 18 | - uses: actions/checkout@v3 19 | - name: check smartcalc-tui dependency version 20 | id: tui 21 | run: echo "::set-output name=version::$(tomlq -r '.dependencies.smartcalc' Cargo.toml)" 22 | - uses: actions/checkout@v3 23 | with: 24 | repository: erhanbaris/smartcalc 25 | path: smartcalc 26 | - name: check upstream smartcalc version 27 | id: lib 28 | run: echo "::set-output name=version::$(tomlq -r '.package.version' smartcalc/Cargo.toml)" 29 | - if: ${{ steps.tui.outputs.version != steps.lib.outputs.version }} 30 | name: update dependency version 31 | run: | 32 | rm -rf smartcalc 33 | sed -i 's/version = "${{ steps.tui.outputs.version }}"/version = "${{ steps.lib.outputs.version }}"/' Cargo.toml 34 | sed -i 's/smartcalc = "${{ steps.tui.outputs.version }}"/smartcalc = "${{ steps.lib.outputs.version }}"/' Cargo.toml 35 | cargo generate-lockfile 36 | - if: ${{ steps.tui.outputs.version != steps.lib.outputs.version }} 37 | name: create PR to update dependency 38 | uses: peter-evans/create-pull-request@v3 39 | with: 40 | commit-message: update smartcalc to ${{ steps.lib.outputs.version }} 41 | branch: chore/smartcalc-${{ steps.lib.outputs.version }} 42 | title: Update smartcalc to ${{ steps.lib.outputs.version }} 43 | body: |- 44 | This is an auto-generated PR created because `smartcalc` appears to have recently released a new version. The dependency and package versions have been bumped automatically. 45 | 46 | You can check this branch out locally to make any required changes: 47 | 48 | ``` 49 | git fetch origin 50 | git checkout chore/smartcalc-${{ steps.lib.outputs.version }} 51 | ``` 52 | 53 | Tests won't run automatically (bots can't trigger other workflows), so make sure to **close and then re-open** this PR to have the automated tests run. 54 | 55 | Once tests are passing, don't forget to publish to crates.io! :partying_face: 56 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.17.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler" 16 | version = "1.0.2" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 19 | 20 | [[package]] 21 | name = "aho-corasick" 22 | version = "0.7.18" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" 25 | dependencies = [ 26 | "memchr", 27 | ] 28 | 29 | [[package]] 30 | name = "ansi_term" 31 | version = "0.12.1" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" 34 | dependencies = [ 35 | "winapi", 36 | ] 37 | 38 | [[package]] 39 | name = "anyhow" 40 | version = "1.0.56" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" 43 | 44 | [[package]] 45 | name = "arrayref" 46 | version = "0.3.6" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" 49 | 50 | [[package]] 51 | name = "arrayvec" 52 | version = "0.4.12" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" 55 | dependencies = [ 56 | "nodrop", 57 | ] 58 | 59 | [[package]] 60 | name = "arrayvec" 61 | version = "0.5.2" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" 64 | 65 | [[package]] 66 | name = "atty" 67 | version = "0.2.14" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 70 | dependencies = [ 71 | "hermit-abi", 72 | "libc", 73 | "winapi", 74 | ] 75 | 76 | [[package]] 77 | name = "autocfg" 78 | version = "1.1.0" 79 | source = "registry+https://github.com/rust-lang/crates.io-index" 80 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 81 | 82 | [[package]] 83 | name = "backtrace" 84 | version = "0.3.64" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "5e121dee8023ce33ab248d9ce1493df03c3b38a659b240096fcbd7048ff9c31f" 87 | dependencies = [ 88 | "addr2line", 89 | "cc", 90 | "cfg-if 1.0.0", 91 | "libc", 92 | "miniz_oxide", 93 | "object", 94 | "rustc-demangle", 95 | ] 96 | 97 | [[package]] 98 | name = "base64" 99 | version = "0.13.0" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" 102 | 103 | [[package]] 104 | name = "bindgen" 105 | version = "0.47.4" 106 | source = "registry+https://github.com/rust-lang/crates.io-index" 107 | checksum = "2a817f8356b784c37ee29b7a9a15c3fec321cd46b0ec67bcebe5530207f62e2d" 108 | dependencies = [ 109 | "bitflags", 110 | "cexpr", 111 | "cfg-if 0.1.10", 112 | "clang-sys", 113 | "clap", 114 | "env_logger", 115 | "hashbrown", 116 | "lazy_static", 117 | "log", 118 | "peeking_take_while", 119 | "proc-macro2 0.4.30", 120 | "quote 0.6.13", 121 | "regex", 122 | "shlex", 123 | "which", 124 | ] 125 | 126 | [[package]] 127 | name = "bitflags" 128 | version = "1.3.2" 129 | source = "registry+https://github.com/rust-lang/crates.io-index" 130 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 131 | 132 | [[package]] 133 | name = "blake2b_simd" 134 | version = "0.5.11" 135 | source = "registry+https://github.com/rust-lang/crates.io-index" 136 | checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" 137 | dependencies = [ 138 | "arrayref", 139 | "arrayvec 0.5.2", 140 | "constant_time_eq", 141 | ] 142 | 143 | [[package]] 144 | name = "bumpalo" 145 | version = "3.9.1" 146 | source = "registry+https://github.com/rust-lang/crates.io-index" 147 | checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" 148 | 149 | [[package]] 150 | name = "byteorder" 151 | version = "1.4.3" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 154 | 155 | [[package]] 156 | name = "cc" 157 | version = "1.0.73" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" 160 | 161 | [[package]] 162 | name = "cexpr" 163 | version = "0.3.6" 164 | source = "registry+https://github.com/rust-lang/crates.io-index" 165 | checksum = "fce5b5fb86b0c57c20c834c1b412fd09c77c8a59b9473f86272709e78874cd1d" 166 | dependencies = [ 167 | "nom 4.2.3", 168 | ] 169 | 170 | [[package]] 171 | name = "cfg-if" 172 | version = "0.1.10" 173 | source = "registry+https://github.com/rust-lang/crates.io-index" 174 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 175 | 176 | [[package]] 177 | name = "cfg-if" 178 | version = "1.0.0" 179 | source = "registry+https://github.com/rust-lang/crates.io-index" 180 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 181 | 182 | [[package]] 183 | name = "chrono" 184 | version = "0.4.19" 185 | source = "registry+https://github.com/rust-lang/crates.io-index" 186 | checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" 187 | dependencies = [ 188 | "js-sys", 189 | "libc", 190 | "num-integer", 191 | "num-traits", 192 | "time", 193 | "wasm-bindgen", 194 | "winapi", 195 | ] 196 | 197 | [[package]] 198 | name = "chrono-tz" 199 | version = "0.6.1" 200 | source = "registry+https://github.com/rust-lang/crates.io-index" 201 | checksum = "58549f1842da3080ce63002102d5bc954c7bc843d4f47818e642abdc36253552" 202 | dependencies = [ 203 | "chrono", 204 | "chrono-tz-build", 205 | "phf 0.10.1", 206 | ] 207 | 208 | [[package]] 209 | name = "chrono-tz-build" 210 | version = "0.0.2" 211 | source = "registry+https://github.com/rust-lang/crates.io-index" 212 | checksum = "db058d493fb2f65f41861bfed7e3fe6335264a9f0f92710cab5bdf01fef09069" 213 | dependencies = [ 214 | "parse-zoneinfo", 215 | "phf 0.10.1", 216 | "phf_codegen 0.10.0", 217 | ] 218 | 219 | [[package]] 220 | name = "clang-sys" 221 | version = "0.26.4" 222 | source = "registry+https://github.com/rust-lang/crates.io-index" 223 | checksum = "6ef0c1bcf2e99c649104bd7a7012d8f8802684400e03db0ec0af48583c6fa0e4" 224 | dependencies = [ 225 | "glob", 226 | "libc", 227 | "libloading", 228 | ] 229 | 230 | [[package]] 231 | name = "clap" 232 | version = "2.34.0" 233 | source = "registry+https://github.com/rust-lang/crates.io-index" 234 | checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" 235 | dependencies = [ 236 | "ansi_term", 237 | "atty", 238 | "bitflags", 239 | "strsim", 240 | "textwrap", 241 | "unicode-width", 242 | "vec_map", 243 | ] 244 | 245 | [[package]] 246 | name = "colored" 247 | version = "2.0.0" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" 250 | dependencies = [ 251 | "atty", 252 | "lazy_static", 253 | "winapi", 254 | ] 255 | 256 | [[package]] 257 | name = "const_format" 258 | version = "0.2.22" 259 | source = "registry+https://github.com/rust-lang/crates.io-index" 260 | checksum = "22bc6cd49b0ec407b680c3e380182b6ac63b73991cb7602de350352fc309b614" 261 | dependencies = [ 262 | "const_format_proc_macros", 263 | ] 264 | 265 | [[package]] 266 | name = "const_format_proc_macros" 267 | version = "0.2.22" 268 | source = "registry+https://github.com/rust-lang/crates.io-index" 269 | checksum = "ef196d5d972878a48da7decb7686eded338b4858fbabeed513d63a7c98b2b82d" 270 | dependencies = [ 271 | "proc-macro2 1.0.37", 272 | "quote 1.0.17", 273 | "unicode-xid 0.2.2", 274 | ] 275 | 276 | [[package]] 277 | name = "constant_time_eq" 278 | version = "0.1.5" 279 | source = "registry+https://github.com/rust-lang/crates.io-index" 280 | checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" 281 | 282 | [[package]] 283 | name = "crossbeam-channel" 284 | version = "0.5.4" 285 | source = "registry+https://github.com/rust-lang/crates.io-index" 286 | checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" 287 | dependencies = [ 288 | "cfg-if 1.0.0", 289 | "crossbeam-utils", 290 | ] 291 | 292 | [[package]] 293 | name = "crossbeam-utils" 294 | version = "0.8.8" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" 297 | dependencies = [ 298 | "cfg-if 1.0.0", 299 | "lazy_static", 300 | ] 301 | 302 | [[package]] 303 | name = "crossterm" 304 | version = "0.23.2" 305 | source = "registry+https://github.com/rust-lang/crates.io-index" 306 | checksum = "a2102ea4f781910f8a5b98dd061f4c2023f479ce7bb1236330099ceb5a93cf17" 307 | dependencies = [ 308 | "bitflags", 309 | "crossterm_winapi", 310 | "libc", 311 | "mio", 312 | "parking_lot", 313 | "signal-hook", 314 | "signal-hook-mio", 315 | "winapi", 316 | ] 317 | 318 | [[package]] 319 | name = "crossterm_winapi" 320 | version = "0.9.0" 321 | source = "registry+https://github.com/rust-lang/crates.io-index" 322 | checksum = "2ae1b35a484aa10e07fe0638d02301c5ad24de82d310ccbd2f3693da5f09bf1c" 323 | dependencies = [ 324 | "winapi", 325 | ] 326 | 327 | [[package]] 328 | name = "dirs" 329 | version = "1.0.5" 330 | source = "registry+https://github.com/rust-lang/crates.io-index" 331 | checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" 332 | dependencies = [ 333 | "libc", 334 | "redox_users 0.3.5", 335 | "winapi", 336 | ] 337 | 338 | [[package]] 339 | name = "dirs" 340 | version = "2.0.2" 341 | source = "registry+https://github.com/rust-lang/crates.io-index" 342 | checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" 343 | dependencies = [ 344 | "cfg-if 0.1.10", 345 | "dirs-sys", 346 | ] 347 | 348 | [[package]] 349 | name = "dirs-sys" 350 | version = "0.3.7" 351 | source = "registry+https://github.com/rust-lang/crates.io-index" 352 | checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" 353 | dependencies = [ 354 | "libc", 355 | "redox_users 0.4.3", 356 | "winapi", 357 | ] 358 | 359 | [[package]] 360 | name = "encoding_rs" 361 | version = "0.8.31" 362 | source = "registry+https://github.com/rust-lang/crates.io-index" 363 | checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" 364 | dependencies = [ 365 | "cfg-if 1.0.0", 366 | ] 367 | 368 | [[package]] 369 | name = "env_logger" 370 | version = "0.6.2" 371 | source = "registry+https://github.com/rust-lang/crates.io-index" 372 | checksum = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" 373 | dependencies = [ 374 | "atty", 375 | "humantime", 376 | "log", 377 | "regex", 378 | "termcolor", 379 | ] 380 | 381 | [[package]] 382 | name = "failure" 383 | version = "0.1.8" 384 | source = "registry+https://github.com/rust-lang/crates.io-index" 385 | checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" 386 | dependencies = [ 387 | "backtrace", 388 | ] 389 | 390 | [[package]] 391 | name = "fnv" 392 | version = "1.0.7" 393 | source = "registry+https://github.com/rust-lang/crates.io-index" 394 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 395 | 396 | [[package]] 397 | name = "getrandom" 398 | version = "0.1.16" 399 | source = "registry+https://github.com/rust-lang/crates.io-index" 400 | checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" 401 | dependencies = [ 402 | "cfg-if 1.0.0", 403 | "js-sys", 404 | "libc", 405 | "wasi 0.9.0+wasi-snapshot-preview1", 406 | "wasm-bindgen", 407 | ] 408 | 409 | [[package]] 410 | name = "getrandom" 411 | version = "0.2.6" 412 | source = "registry+https://github.com/rust-lang/crates.io-index" 413 | checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" 414 | dependencies = [ 415 | "cfg-if 1.0.0", 416 | "libc", 417 | "wasi 0.10.0+wasi-snapshot-preview1", 418 | ] 419 | 420 | [[package]] 421 | name = "gimli" 422 | version = "0.26.1" 423 | source = "registry+https://github.com/rust-lang/crates.io-index" 424 | checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" 425 | 426 | [[package]] 427 | name = "glob" 428 | version = "0.2.11" 429 | source = "registry+https://github.com/rust-lang/crates.io-index" 430 | checksum = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" 431 | 432 | [[package]] 433 | name = "hashbrown" 434 | version = "0.1.8" 435 | source = "registry+https://github.com/rust-lang/crates.io-index" 436 | checksum = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da" 437 | dependencies = [ 438 | "byteorder", 439 | "scopeguard 0.3.3", 440 | ] 441 | 442 | [[package]] 443 | name = "hermit-abi" 444 | version = "0.1.19" 445 | source = "registry+https://github.com/rust-lang/crates.io-index" 446 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 447 | dependencies = [ 448 | "libc", 449 | ] 450 | 451 | [[package]] 452 | name = "humantime" 453 | version = "1.3.0" 454 | source = "registry+https://github.com/rust-lang/crates.io-index" 455 | checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" 456 | dependencies = [ 457 | "quick-error", 458 | ] 459 | 460 | [[package]] 461 | name = "itoa" 462 | version = "0.4.8" 463 | source = "registry+https://github.com/rust-lang/crates.io-index" 464 | checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" 465 | 466 | [[package]] 467 | name = "itoa" 468 | version = "1.0.1" 469 | source = "registry+https://github.com/rust-lang/crates.io-index" 470 | checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" 471 | 472 | [[package]] 473 | name = "js-sys" 474 | version = "0.3.57" 475 | source = "registry+https://github.com/rust-lang/crates.io-index" 476 | checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" 477 | dependencies = [ 478 | "wasm-bindgen", 479 | ] 480 | 481 | [[package]] 482 | name = "lazy_static" 483 | version = "1.4.0" 484 | source = "registry+https://github.com/rust-lang/crates.io-index" 485 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 486 | 487 | [[package]] 488 | name = "libc" 489 | version = "0.2.122" 490 | source = "registry+https://github.com/rust-lang/crates.io-index" 491 | checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259" 492 | 493 | [[package]] 494 | name = "libc-print" 495 | version = "0.1.19" 496 | source = "registry+https://github.com/rust-lang/crates.io-index" 497 | checksum = "4580c894695923468a80b039d7e552739c79612fe4d32beb0f20175de1985d6d" 498 | dependencies = [ 499 | "libc", 500 | ] 501 | 502 | [[package]] 503 | name = "libloading" 504 | version = "0.5.2" 505 | source = "registry+https://github.com/rust-lang/crates.io-index" 506 | checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" 507 | dependencies = [ 508 | "cc", 509 | "winapi", 510 | ] 511 | 512 | [[package]] 513 | name = "linefeed" 514 | version = "0.6.0" 515 | source = "registry+https://github.com/rust-lang/crates.io-index" 516 | checksum = "28715d08e35c6c074f9ae6b2e6a2420bac75d050c66ecd669d7d5b98e2caa036" 517 | dependencies = [ 518 | "dirs 1.0.5", 519 | "mortal", 520 | "winapi", 521 | ] 522 | 523 | [[package]] 524 | name = "localzone" 525 | version = "0.2.0" 526 | source = "registry+https://github.com/rust-lang/crates.io-index" 527 | checksum = "7865f5a13ecb548180b8fe7e538d739090329fdb984eef9e9a16db214f216c6f" 528 | dependencies = [ 529 | "js-sys", 530 | "windows", 531 | ] 532 | 533 | [[package]] 534 | name = "lock_api" 535 | version = "0.4.7" 536 | source = "registry+https://github.com/rust-lang/crates.io-index" 537 | checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" 538 | dependencies = [ 539 | "autocfg", 540 | "scopeguard 1.1.0", 541 | ] 542 | 543 | [[package]] 544 | name = "log" 545 | version = "0.4.16" 546 | source = "registry+https://github.com/rust-lang/crates.io-index" 547 | checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" 548 | dependencies = [ 549 | "cfg-if 1.0.0", 550 | ] 551 | 552 | [[package]] 553 | name = "memchr" 554 | version = "2.4.1" 555 | source = "registry+https://github.com/rust-lang/crates.io-index" 556 | checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" 557 | 558 | [[package]] 559 | name = "memoffset" 560 | version = "0.6.5" 561 | source = "registry+https://github.com/rust-lang/crates.io-index" 562 | checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" 563 | dependencies = [ 564 | "autocfg", 565 | ] 566 | 567 | [[package]] 568 | name = "miniz_oxide" 569 | version = "0.4.4" 570 | source = "registry+https://github.com/rust-lang/crates.io-index" 571 | checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" 572 | dependencies = [ 573 | "adler", 574 | "autocfg", 575 | ] 576 | 577 | [[package]] 578 | name = "mio" 579 | version = "0.8.2" 580 | source = "registry+https://github.com/rust-lang/crates.io-index" 581 | checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" 582 | dependencies = [ 583 | "libc", 584 | "log", 585 | "miow", 586 | "ntapi", 587 | "wasi 0.11.0+wasi-snapshot-preview1", 588 | "winapi", 589 | ] 590 | 591 | [[package]] 592 | name = "miow" 593 | version = "0.3.7" 594 | source = "registry+https://github.com/rust-lang/crates.io-index" 595 | checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" 596 | dependencies = [ 597 | "winapi", 598 | ] 599 | 600 | [[package]] 601 | name = "mortal" 602 | version = "0.2.3" 603 | source = "registry+https://github.com/rust-lang/crates.io-index" 604 | checksum = "8d3b281c45a2dbb0609b854de9df94694fb77eab2fa2933c07d07001dcb29377" 605 | dependencies = [ 606 | "bitflags", 607 | "libc", 608 | "nix", 609 | "smallstr", 610 | "terminfo", 611 | "unicode-normalization", 612 | "unicode-width", 613 | "winapi", 614 | ] 615 | 616 | [[package]] 617 | name = "nix" 618 | version = "0.23.1" 619 | source = "registry+https://github.com/rust-lang/crates.io-index" 620 | checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" 621 | dependencies = [ 622 | "bitflags", 623 | "cc", 624 | "cfg-if 1.0.0", 625 | "libc", 626 | "memoffset", 627 | ] 628 | 629 | [[package]] 630 | name = "nodrop" 631 | version = "0.1.14" 632 | source = "registry+https://github.com/rust-lang/crates.io-index" 633 | checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" 634 | 635 | [[package]] 636 | name = "nom" 637 | version = "4.2.3" 638 | source = "registry+https://github.com/rust-lang/crates.io-index" 639 | checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" 640 | dependencies = [ 641 | "memchr", 642 | "version_check 0.1.5", 643 | ] 644 | 645 | [[package]] 646 | name = "nom" 647 | version = "5.1.2" 648 | source = "registry+https://github.com/rust-lang/crates.io-index" 649 | checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" 650 | dependencies = [ 651 | "memchr", 652 | "version_check 0.9.4", 653 | ] 654 | 655 | [[package]] 656 | name = "ntapi" 657 | version = "0.3.7" 658 | source = "registry+https://github.com/rust-lang/crates.io-index" 659 | checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" 660 | dependencies = [ 661 | "winapi", 662 | ] 663 | 664 | [[package]] 665 | name = "num-format" 666 | version = "0.4.0" 667 | source = "registry+https://github.com/rust-lang/crates.io-index" 668 | checksum = "bafe4179722c2894288ee77a9f044f02811c86af699344c498b0840c698a2465" 669 | dependencies = [ 670 | "arrayvec 0.4.12", 671 | "cfg-if 0.1.10", 672 | "encoding_rs", 673 | "itoa 0.4.8", 674 | "lazy_static", 675 | "libc", 676 | "num-format-windows", 677 | "widestring", 678 | "winapi", 679 | ] 680 | 681 | [[package]] 682 | name = "num-format-windows" 683 | version = "0.3.0" 684 | source = "registry+https://github.com/rust-lang/crates.io-index" 685 | checksum = "4e179850c4611faf725cc7d92016aa9261a4c9887fc5501812da6cb87297c5eb" 686 | dependencies = [ 687 | "bindgen", 688 | ] 689 | 690 | [[package]] 691 | name = "num-integer" 692 | version = "0.1.44" 693 | source = "registry+https://github.com/rust-lang/crates.io-index" 694 | checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" 695 | dependencies = [ 696 | "autocfg", 697 | "num-traits", 698 | ] 699 | 700 | [[package]] 701 | name = "num-traits" 702 | version = "0.2.14" 703 | source = "registry+https://github.com/rust-lang/crates.io-index" 704 | checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" 705 | dependencies = [ 706 | "autocfg", 707 | ] 708 | 709 | [[package]] 710 | name = "object" 711 | version = "0.27.1" 712 | source = "registry+https://github.com/rust-lang/crates.io-index" 713 | checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9" 714 | dependencies = [ 715 | "memchr", 716 | ] 717 | 718 | [[package]] 719 | name = "parking_lot" 720 | version = "0.12.0" 721 | source = "registry+https://github.com/rust-lang/crates.io-index" 722 | checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" 723 | dependencies = [ 724 | "lock_api", 725 | "parking_lot_core", 726 | ] 727 | 728 | [[package]] 729 | name = "parking_lot_core" 730 | version = "0.9.2" 731 | source = "registry+https://github.com/rust-lang/crates.io-index" 732 | checksum = "995f667a6c822200b0433ac218e05582f0e2efa1b922a3fd2fbaadc5f87bab37" 733 | dependencies = [ 734 | "cfg-if 1.0.0", 735 | "libc", 736 | "redox_syscall 0.2.13", 737 | "smallvec", 738 | "windows-sys 0.34.0", 739 | ] 740 | 741 | [[package]] 742 | name = "parse-zoneinfo" 743 | version = "0.3.0" 744 | source = "registry+https://github.com/rust-lang/crates.io-index" 745 | checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41" 746 | dependencies = [ 747 | "regex", 748 | ] 749 | 750 | [[package]] 751 | name = "peeking_take_while" 752 | version = "0.1.2" 753 | source = "registry+https://github.com/rust-lang/crates.io-index" 754 | checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" 755 | 756 | [[package]] 757 | name = "phf" 758 | version = "0.8.0" 759 | source = "registry+https://github.com/rust-lang/crates.io-index" 760 | checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" 761 | dependencies = [ 762 | "phf_shared 0.8.0", 763 | ] 764 | 765 | [[package]] 766 | name = "phf" 767 | version = "0.10.1" 768 | source = "registry+https://github.com/rust-lang/crates.io-index" 769 | checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" 770 | dependencies = [ 771 | "phf_shared 0.10.0", 772 | ] 773 | 774 | [[package]] 775 | name = "phf_codegen" 776 | version = "0.8.0" 777 | source = "registry+https://github.com/rust-lang/crates.io-index" 778 | checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" 779 | dependencies = [ 780 | "phf_generator 0.8.0", 781 | "phf_shared 0.8.0", 782 | ] 783 | 784 | [[package]] 785 | name = "phf_codegen" 786 | version = "0.10.0" 787 | source = "registry+https://github.com/rust-lang/crates.io-index" 788 | checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" 789 | dependencies = [ 790 | "phf_generator 0.10.0", 791 | "phf_shared 0.10.0", 792 | ] 793 | 794 | [[package]] 795 | name = "phf_generator" 796 | version = "0.8.0" 797 | source = "registry+https://github.com/rust-lang/crates.io-index" 798 | checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" 799 | dependencies = [ 800 | "phf_shared 0.8.0", 801 | "rand 0.7.3", 802 | ] 803 | 804 | [[package]] 805 | name = "phf_generator" 806 | version = "0.10.0" 807 | source = "registry+https://github.com/rust-lang/crates.io-index" 808 | checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" 809 | dependencies = [ 810 | "phf_shared 0.10.0", 811 | "rand 0.8.5", 812 | ] 813 | 814 | [[package]] 815 | name = "phf_shared" 816 | version = "0.8.0" 817 | source = "registry+https://github.com/rust-lang/crates.io-index" 818 | checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" 819 | dependencies = [ 820 | "siphasher", 821 | ] 822 | 823 | [[package]] 824 | name = "phf_shared" 825 | version = "0.10.0" 826 | source = "registry+https://github.com/rust-lang/crates.io-index" 827 | checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" 828 | dependencies = [ 829 | "siphasher", 830 | "uncased", 831 | ] 832 | 833 | [[package]] 834 | name = "ppv-lite86" 835 | version = "0.2.16" 836 | source = "registry+https://github.com/rust-lang/crates.io-index" 837 | checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" 838 | 839 | [[package]] 840 | name = "proc-macro2" 841 | version = "0.4.30" 842 | source = "registry+https://github.com/rust-lang/crates.io-index" 843 | checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" 844 | dependencies = [ 845 | "unicode-xid 0.1.0", 846 | ] 847 | 848 | [[package]] 849 | name = "proc-macro2" 850 | version = "1.0.37" 851 | source = "registry+https://github.com/rust-lang/crates.io-index" 852 | checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" 853 | dependencies = [ 854 | "unicode-xid 0.2.2", 855 | ] 856 | 857 | [[package]] 858 | name = "quick-error" 859 | version = "1.2.3" 860 | source = "registry+https://github.com/rust-lang/crates.io-index" 861 | checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" 862 | 863 | [[package]] 864 | name = "quote" 865 | version = "0.6.13" 866 | source = "registry+https://github.com/rust-lang/crates.io-index" 867 | checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" 868 | dependencies = [ 869 | "proc-macro2 0.4.30", 870 | ] 871 | 872 | [[package]] 873 | name = "quote" 874 | version = "1.0.17" 875 | source = "registry+https://github.com/rust-lang/crates.io-index" 876 | checksum = "632d02bff7f874a36f33ea8bb416cd484b90cc66c1194b1a1110d067a7013f58" 877 | dependencies = [ 878 | "proc-macro2 1.0.37", 879 | ] 880 | 881 | [[package]] 882 | name = "rand" 883 | version = "0.7.3" 884 | source = "registry+https://github.com/rust-lang/crates.io-index" 885 | checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" 886 | dependencies = [ 887 | "getrandom 0.1.16", 888 | "libc", 889 | "rand_chacha 0.2.2", 890 | "rand_core 0.5.1", 891 | "rand_hc", 892 | "rand_pcg", 893 | ] 894 | 895 | [[package]] 896 | name = "rand" 897 | version = "0.8.5" 898 | source = "registry+https://github.com/rust-lang/crates.io-index" 899 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 900 | dependencies = [ 901 | "libc", 902 | "rand_chacha 0.3.1", 903 | "rand_core 0.6.3", 904 | ] 905 | 906 | [[package]] 907 | name = "rand_chacha" 908 | version = "0.2.2" 909 | source = "registry+https://github.com/rust-lang/crates.io-index" 910 | checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" 911 | dependencies = [ 912 | "ppv-lite86", 913 | "rand_core 0.5.1", 914 | ] 915 | 916 | [[package]] 917 | name = "rand_chacha" 918 | version = "0.3.1" 919 | source = "registry+https://github.com/rust-lang/crates.io-index" 920 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 921 | dependencies = [ 922 | "ppv-lite86", 923 | "rand_core 0.6.3", 924 | ] 925 | 926 | [[package]] 927 | name = "rand_core" 928 | version = "0.5.1" 929 | source = "registry+https://github.com/rust-lang/crates.io-index" 930 | checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 931 | dependencies = [ 932 | "getrandom 0.1.16", 933 | ] 934 | 935 | [[package]] 936 | name = "rand_core" 937 | version = "0.6.3" 938 | source = "registry+https://github.com/rust-lang/crates.io-index" 939 | checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" 940 | dependencies = [ 941 | "getrandom 0.2.6", 942 | ] 943 | 944 | [[package]] 945 | name = "rand_hc" 946 | version = "0.2.0" 947 | source = "registry+https://github.com/rust-lang/crates.io-index" 948 | checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 949 | dependencies = [ 950 | "rand_core 0.5.1", 951 | ] 952 | 953 | [[package]] 954 | name = "rand_pcg" 955 | version = "0.2.1" 956 | source = "registry+https://github.com/rust-lang/crates.io-index" 957 | checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" 958 | dependencies = [ 959 | "rand_core 0.5.1", 960 | ] 961 | 962 | [[package]] 963 | name = "redox_syscall" 964 | version = "0.1.57" 965 | source = "registry+https://github.com/rust-lang/crates.io-index" 966 | checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" 967 | 968 | [[package]] 969 | name = "redox_syscall" 970 | version = "0.2.13" 971 | source = "registry+https://github.com/rust-lang/crates.io-index" 972 | checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" 973 | dependencies = [ 974 | "bitflags", 975 | ] 976 | 977 | [[package]] 978 | name = "redox_users" 979 | version = "0.3.5" 980 | source = "registry+https://github.com/rust-lang/crates.io-index" 981 | checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" 982 | dependencies = [ 983 | "getrandom 0.1.16", 984 | "redox_syscall 0.1.57", 985 | "rust-argon2", 986 | ] 987 | 988 | [[package]] 989 | name = "redox_users" 990 | version = "0.4.3" 991 | source = "registry+https://github.com/rust-lang/crates.io-index" 992 | checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" 993 | dependencies = [ 994 | "getrandom 0.2.6", 995 | "redox_syscall 0.2.13", 996 | "thiserror", 997 | ] 998 | 999 | [[package]] 1000 | name = "regex" 1001 | version = "1.5.5" 1002 | source = "registry+https://github.com/rust-lang/crates.io-index" 1003 | checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" 1004 | dependencies = [ 1005 | "aho-corasick", 1006 | "memchr", 1007 | "regex-syntax", 1008 | ] 1009 | 1010 | [[package]] 1011 | name = "regex-syntax" 1012 | version = "0.6.25" 1013 | source = "registry+https://github.com/rust-lang/crates.io-index" 1014 | checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" 1015 | 1016 | [[package]] 1017 | name = "rust-argon2" 1018 | version = "0.8.3" 1019 | source = "registry+https://github.com/rust-lang/crates.io-index" 1020 | checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" 1021 | dependencies = [ 1022 | "base64", 1023 | "blake2b_simd", 1024 | "constant_time_eq", 1025 | "crossbeam-utils", 1026 | ] 1027 | 1028 | [[package]] 1029 | name = "rustc-demangle" 1030 | version = "0.1.21" 1031 | source = "registry+https://github.com/rust-lang/crates.io-index" 1032 | checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" 1033 | 1034 | [[package]] 1035 | name = "ryu" 1036 | version = "1.0.9" 1037 | source = "registry+https://github.com/rust-lang/crates.io-index" 1038 | checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" 1039 | 1040 | [[package]] 1041 | name = "scopeguard" 1042 | version = "0.3.3" 1043 | source = "registry+https://github.com/rust-lang/crates.io-index" 1044 | checksum = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" 1045 | 1046 | [[package]] 1047 | name = "scopeguard" 1048 | version = "1.1.0" 1049 | source = "registry+https://github.com/rust-lang/crates.io-index" 1050 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 1051 | 1052 | [[package]] 1053 | name = "serde" 1054 | version = "1.0.136" 1055 | source = "registry+https://github.com/rust-lang/crates.io-index" 1056 | checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" 1057 | 1058 | [[package]] 1059 | name = "serde_derive" 1060 | version = "1.0.136" 1061 | source = "registry+https://github.com/rust-lang/crates.io-index" 1062 | checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" 1063 | dependencies = [ 1064 | "proc-macro2 1.0.37", 1065 | "quote 1.0.17", 1066 | "syn", 1067 | ] 1068 | 1069 | [[package]] 1070 | name = "serde_json" 1071 | version = "1.0.79" 1072 | source = "registry+https://github.com/rust-lang/crates.io-index" 1073 | checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" 1074 | dependencies = [ 1075 | "itoa 1.0.1", 1076 | "ryu", 1077 | "serde", 1078 | ] 1079 | 1080 | [[package]] 1081 | name = "serde_repr" 1082 | version = "0.1.7" 1083 | source = "registry+https://github.com/rust-lang/crates.io-index" 1084 | checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5" 1085 | dependencies = [ 1086 | "proc-macro2 1.0.37", 1087 | "quote 1.0.17", 1088 | "syn", 1089 | ] 1090 | 1091 | [[package]] 1092 | name = "shlex" 1093 | version = "0.1.1" 1094 | source = "registry+https://github.com/rust-lang/crates.io-index" 1095 | checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" 1096 | 1097 | [[package]] 1098 | name = "signal-hook" 1099 | version = "0.3.13" 1100 | source = "registry+https://github.com/rust-lang/crates.io-index" 1101 | checksum = "647c97df271007dcea485bb74ffdb57f2e683f1306c854f468a0c244badabf2d" 1102 | dependencies = [ 1103 | "libc", 1104 | "signal-hook-registry", 1105 | ] 1106 | 1107 | [[package]] 1108 | name = "signal-hook-mio" 1109 | version = "0.2.3" 1110 | source = "registry+https://github.com/rust-lang/crates.io-index" 1111 | checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" 1112 | dependencies = [ 1113 | "libc", 1114 | "mio", 1115 | "signal-hook", 1116 | ] 1117 | 1118 | [[package]] 1119 | name = "signal-hook-registry" 1120 | version = "1.4.0" 1121 | source = "registry+https://github.com/rust-lang/crates.io-index" 1122 | checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" 1123 | dependencies = [ 1124 | "libc", 1125 | ] 1126 | 1127 | [[package]] 1128 | name = "siphasher" 1129 | version = "0.3.10" 1130 | source = "registry+https://github.com/rust-lang/crates.io-index" 1131 | checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" 1132 | 1133 | [[package]] 1134 | name = "smallstr" 1135 | version = "0.2.0" 1136 | source = "registry+https://github.com/rust-lang/crates.io-index" 1137 | checksum = "1e922794d168678729ffc7e07182721a14219c65814e66e91b839a272fe5ae4f" 1138 | dependencies = [ 1139 | "smallvec", 1140 | ] 1141 | 1142 | [[package]] 1143 | name = "smallvec" 1144 | version = "1.8.0" 1145 | source = "registry+https://github.com/rust-lang/crates.io-index" 1146 | checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" 1147 | 1148 | [[package]] 1149 | name = "smartcalc" 1150 | version = "1.0.8" 1151 | source = "registry+https://github.com/rust-lang/crates.io-index" 1152 | checksum = "a9263d54977c25ec1b661a006e138360ef08788755ed8e53eb31978945a444c0" 1153 | dependencies = [ 1154 | "anyhow", 1155 | "chrono", 1156 | "chrono-tz", 1157 | "lazy_static", 1158 | "libc-print", 1159 | "log", 1160 | "rand 0.7.3", 1161 | "regex", 1162 | "serde", 1163 | "serde_derive", 1164 | "serde_json", 1165 | "serde_repr", 1166 | ] 1167 | 1168 | [[package]] 1169 | name = "smartcalc-tui" 1170 | version = "1.0.8" 1171 | dependencies = [ 1172 | "chrono", 1173 | "chrono-tz", 1174 | "colored", 1175 | "const_format", 1176 | "crossbeam-channel", 1177 | "crossterm", 1178 | "linefeed", 1179 | "localzone", 1180 | "log", 1181 | "num-format", 1182 | "parking_lot", 1183 | "smartcalc", 1184 | ] 1185 | 1186 | [[package]] 1187 | name = "strsim" 1188 | version = "0.8.0" 1189 | source = "registry+https://github.com/rust-lang/crates.io-index" 1190 | checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" 1191 | 1192 | [[package]] 1193 | name = "syn" 1194 | version = "1.0.91" 1195 | source = "registry+https://github.com/rust-lang/crates.io-index" 1196 | checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" 1197 | dependencies = [ 1198 | "proc-macro2 1.0.37", 1199 | "quote 1.0.17", 1200 | "unicode-xid 0.2.2", 1201 | ] 1202 | 1203 | [[package]] 1204 | name = "termcolor" 1205 | version = "1.1.3" 1206 | source = "registry+https://github.com/rust-lang/crates.io-index" 1207 | checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" 1208 | dependencies = [ 1209 | "winapi-util", 1210 | ] 1211 | 1212 | [[package]] 1213 | name = "terminfo" 1214 | version = "0.7.3" 1215 | source = "registry+https://github.com/rust-lang/crates.io-index" 1216 | checksum = "76971977e6121664ec1b960d1313aacfa75642adc93b9d4d53b247bd4cb1747e" 1217 | dependencies = [ 1218 | "dirs 2.0.2", 1219 | "fnv", 1220 | "nom 5.1.2", 1221 | "phf 0.8.0", 1222 | "phf_codegen 0.8.0", 1223 | ] 1224 | 1225 | [[package]] 1226 | name = "textwrap" 1227 | version = "0.11.0" 1228 | source = "registry+https://github.com/rust-lang/crates.io-index" 1229 | checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" 1230 | dependencies = [ 1231 | "unicode-width", 1232 | ] 1233 | 1234 | [[package]] 1235 | name = "thiserror" 1236 | version = "1.0.30" 1237 | source = "registry+https://github.com/rust-lang/crates.io-index" 1238 | checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" 1239 | dependencies = [ 1240 | "thiserror-impl", 1241 | ] 1242 | 1243 | [[package]] 1244 | name = "thiserror-impl" 1245 | version = "1.0.30" 1246 | source = "registry+https://github.com/rust-lang/crates.io-index" 1247 | checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" 1248 | dependencies = [ 1249 | "proc-macro2 1.0.37", 1250 | "quote 1.0.17", 1251 | "syn", 1252 | ] 1253 | 1254 | [[package]] 1255 | name = "time" 1256 | version = "0.1.44" 1257 | source = "registry+https://github.com/rust-lang/crates.io-index" 1258 | checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" 1259 | dependencies = [ 1260 | "libc", 1261 | "wasi 0.10.0+wasi-snapshot-preview1", 1262 | "winapi", 1263 | ] 1264 | 1265 | [[package]] 1266 | name = "tinyvec" 1267 | version = "1.5.1" 1268 | source = "registry+https://github.com/rust-lang/crates.io-index" 1269 | checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" 1270 | dependencies = [ 1271 | "tinyvec_macros", 1272 | ] 1273 | 1274 | [[package]] 1275 | name = "tinyvec_macros" 1276 | version = "0.1.0" 1277 | source = "registry+https://github.com/rust-lang/crates.io-index" 1278 | checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" 1279 | 1280 | [[package]] 1281 | name = "uncased" 1282 | version = "0.9.6" 1283 | source = "registry+https://github.com/rust-lang/crates.io-index" 1284 | checksum = "5baeed7327e25054889b9bd4f975f32e5f4c5d434042d59ab6cd4142c0a76ed0" 1285 | dependencies = [ 1286 | "version_check 0.9.4", 1287 | ] 1288 | 1289 | [[package]] 1290 | name = "unicode-normalization" 1291 | version = "0.1.19" 1292 | source = "registry+https://github.com/rust-lang/crates.io-index" 1293 | checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" 1294 | dependencies = [ 1295 | "tinyvec", 1296 | ] 1297 | 1298 | [[package]] 1299 | name = "unicode-width" 1300 | version = "0.1.9" 1301 | source = "registry+https://github.com/rust-lang/crates.io-index" 1302 | checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" 1303 | 1304 | [[package]] 1305 | name = "unicode-xid" 1306 | version = "0.1.0" 1307 | source = "registry+https://github.com/rust-lang/crates.io-index" 1308 | checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" 1309 | 1310 | [[package]] 1311 | name = "unicode-xid" 1312 | version = "0.2.2" 1313 | source = "registry+https://github.com/rust-lang/crates.io-index" 1314 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" 1315 | 1316 | [[package]] 1317 | name = "vec_map" 1318 | version = "0.8.2" 1319 | source = "registry+https://github.com/rust-lang/crates.io-index" 1320 | checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" 1321 | 1322 | [[package]] 1323 | name = "version_check" 1324 | version = "0.1.5" 1325 | source = "registry+https://github.com/rust-lang/crates.io-index" 1326 | checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" 1327 | 1328 | [[package]] 1329 | name = "version_check" 1330 | version = "0.9.4" 1331 | source = "registry+https://github.com/rust-lang/crates.io-index" 1332 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1333 | 1334 | [[package]] 1335 | name = "wasi" 1336 | version = "0.9.0+wasi-snapshot-preview1" 1337 | source = "registry+https://github.com/rust-lang/crates.io-index" 1338 | checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" 1339 | 1340 | [[package]] 1341 | name = "wasi" 1342 | version = "0.10.0+wasi-snapshot-preview1" 1343 | source = "registry+https://github.com/rust-lang/crates.io-index" 1344 | checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" 1345 | 1346 | [[package]] 1347 | name = "wasi" 1348 | version = "0.11.0+wasi-snapshot-preview1" 1349 | source = "registry+https://github.com/rust-lang/crates.io-index" 1350 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1351 | 1352 | [[package]] 1353 | name = "wasm-bindgen" 1354 | version = "0.2.80" 1355 | source = "registry+https://github.com/rust-lang/crates.io-index" 1356 | checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" 1357 | dependencies = [ 1358 | "cfg-if 1.0.0", 1359 | "wasm-bindgen-macro", 1360 | ] 1361 | 1362 | [[package]] 1363 | name = "wasm-bindgen-backend" 1364 | version = "0.2.80" 1365 | source = "registry+https://github.com/rust-lang/crates.io-index" 1366 | checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" 1367 | dependencies = [ 1368 | "bumpalo", 1369 | "lazy_static", 1370 | "log", 1371 | "proc-macro2 1.0.37", 1372 | "quote 1.0.17", 1373 | "syn", 1374 | "wasm-bindgen-shared", 1375 | ] 1376 | 1377 | [[package]] 1378 | name = "wasm-bindgen-macro" 1379 | version = "0.2.80" 1380 | source = "registry+https://github.com/rust-lang/crates.io-index" 1381 | checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" 1382 | dependencies = [ 1383 | "quote 1.0.17", 1384 | "wasm-bindgen-macro-support", 1385 | ] 1386 | 1387 | [[package]] 1388 | name = "wasm-bindgen-macro-support" 1389 | version = "0.2.80" 1390 | source = "registry+https://github.com/rust-lang/crates.io-index" 1391 | checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" 1392 | dependencies = [ 1393 | "proc-macro2 1.0.37", 1394 | "quote 1.0.17", 1395 | "syn", 1396 | "wasm-bindgen-backend", 1397 | "wasm-bindgen-shared", 1398 | ] 1399 | 1400 | [[package]] 1401 | name = "wasm-bindgen-shared" 1402 | version = "0.2.80" 1403 | source = "registry+https://github.com/rust-lang/crates.io-index" 1404 | checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" 1405 | 1406 | [[package]] 1407 | name = "which" 1408 | version = "2.0.1" 1409 | source = "registry+https://github.com/rust-lang/crates.io-index" 1410 | checksum = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164" 1411 | dependencies = [ 1412 | "failure", 1413 | "libc", 1414 | ] 1415 | 1416 | [[package]] 1417 | name = "widestring" 1418 | version = "0.4.3" 1419 | source = "registry+https://github.com/rust-lang/crates.io-index" 1420 | checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" 1421 | 1422 | [[package]] 1423 | name = "winapi" 1424 | version = "0.3.9" 1425 | source = "registry+https://github.com/rust-lang/crates.io-index" 1426 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1427 | dependencies = [ 1428 | "winapi-i686-pc-windows-gnu", 1429 | "winapi-x86_64-pc-windows-gnu", 1430 | ] 1431 | 1432 | [[package]] 1433 | name = "winapi-i686-pc-windows-gnu" 1434 | version = "0.4.0" 1435 | source = "registry+https://github.com/rust-lang/crates.io-index" 1436 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1437 | 1438 | [[package]] 1439 | name = "winapi-util" 1440 | version = "0.1.5" 1441 | source = "registry+https://github.com/rust-lang/crates.io-index" 1442 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 1443 | dependencies = [ 1444 | "winapi", 1445 | ] 1446 | 1447 | [[package]] 1448 | name = "winapi-x86_64-pc-windows-gnu" 1449 | version = "0.4.0" 1450 | source = "registry+https://github.com/rust-lang/crates.io-index" 1451 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1452 | 1453 | [[package]] 1454 | name = "windows" 1455 | version = "0.28.0" 1456 | source = "registry+https://github.com/rust-lang/crates.io-index" 1457 | checksum = "054d31561409bbf7e1ee4a4f0a1233ac2bb79cfadf2a398438a04d8dda69225f" 1458 | dependencies = [ 1459 | "windows-sys 0.28.0", 1460 | ] 1461 | 1462 | [[package]] 1463 | name = "windows-sys" 1464 | version = "0.28.0" 1465 | source = "registry+https://github.com/rust-lang/crates.io-index" 1466 | checksum = "82ca39602d5cbfa692c4b67e3bcbb2751477355141c1ed434c94da4186836ff6" 1467 | dependencies = [ 1468 | "windows_aarch64_msvc 0.28.0", 1469 | "windows_i686_gnu 0.28.0", 1470 | "windows_i686_msvc 0.28.0", 1471 | "windows_x86_64_gnu 0.28.0", 1472 | "windows_x86_64_msvc 0.28.0", 1473 | ] 1474 | 1475 | [[package]] 1476 | name = "windows-sys" 1477 | version = "0.34.0" 1478 | source = "registry+https://github.com/rust-lang/crates.io-index" 1479 | checksum = "5acdd78cb4ba54c0045ac14f62d8f94a03d10047904ae2a40afa1e99d8f70825" 1480 | dependencies = [ 1481 | "windows_aarch64_msvc 0.34.0", 1482 | "windows_i686_gnu 0.34.0", 1483 | "windows_i686_msvc 0.34.0", 1484 | "windows_x86_64_gnu 0.34.0", 1485 | "windows_x86_64_msvc 0.34.0", 1486 | ] 1487 | 1488 | [[package]] 1489 | name = "windows_aarch64_msvc" 1490 | version = "0.28.0" 1491 | source = "registry+https://github.com/rust-lang/crates.io-index" 1492 | checksum = "52695a41e536859d5308cc613b4a022261a274390b25bd29dfff4bf08505f3c2" 1493 | 1494 | [[package]] 1495 | name = "windows_aarch64_msvc" 1496 | version = "0.34.0" 1497 | source = "registry+https://github.com/rust-lang/crates.io-index" 1498 | checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" 1499 | 1500 | [[package]] 1501 | name = "windows_i686_gnu" 1502 | version = "0.28.0" 1503 | source = "registry+https://github.com/rust-lang/crates.io-index" 1504 | checksum = "f54725ac23affef038fecb177de6c9bf065787c2f432f79e3c373da92f3e1d8a" 1505 | 1506 | [[package]] 1507 | name = "windows_i686_gnu" 1508 | version = "0.34.0" 1509 | source = "registry+https://github.com/rust-lang/crates.io-index" 1510 | checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" 1511 | 1512 | [[package]] 1513 | name = "windows_i686_msvc" 1514 | version = "0.28.0" 1515 | source = "registry+https://github.com/rust-lang/crates.io-index" 1516 | checksum = "51d5158a43cc43623c0729d1ad6647e62fa384a3d135fd15108d37c683461f64" 1517 | 1518 | [[package]] 1519 | name = "windows_i686_msvc" 1520 | version = "0.34.0" 1521 | source = "registry+https://github.com/rust-lang/crates.io-index" 1522 | checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" 1523 | 1524 | [[package]] 1525 | name = "windows_x86_64_gnu" 1526 | version = "0.28.0" 1527 | source = "registry+https://github.com/rust-lang/crates.io-index" 1528 | checksum = "bc31f409f565611535130cfe7ee8e6655d3fa99c1c61013981e491921b5ce954" 1529 | 1530 | [[package]] 1531 | name = "windows_x86_64_gnu" 1532 | version = "0.34.0" 1533 | source = "registry+https://github.com/rust-lang/crates.io-index" 1534 | checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" 1535 | 1536 | [[package]] 1537 | name = "windows_x86_64_msvc" 1538 | version = "0.28.0" 1539 | source = "registry+https://github.com/rust-lang/crates.io-index" 1540 | checksum = "3f2b8c7cbd3bfdddd9ab98769f9746a7fad1bca236554cd032b78d768bc0e89f" 1541 | 1542 | [[package]] 1543 | name = "windows_x86_64_msvc" 1544 | version = "0.34.0" 1545 | source = "registry+https://github.com/rust-lang/crates.io-index" 1546 | checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" 1547 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "smartcalc-tui" 3 | authors = ["Aaron Ross "] 4 | version = "1.0.8" 5 | edition = "2018" 6 | license = "MIT" 7 | description = "Terminal UI for erhanbaris/smartcalc" 8 | repository = "https://github.com/superhawk610/smartcalc-tui" 9 | documentation = "https://github.com/superhawk610/smartcalc-tui" 10 | homepage = "https://github.com/superhawk610/smartcalc-tui" 11 | readme = "README.md" 12 | keywords = ["calculator", "tui"] 13 | categories = ["mathematics", "science", "command-line-utilities", "development-tools"] 14 | exclude = [".github/", "assets/"] 15 | 16 | [lib] 17 | name = "smartcalc_tui" 18 | path = "src/lib.rs" 19 | 20 | [[bin]] 21 | name = "smartcalc" 22 | path = "src/bin/main.rs" 23 | 24 | [dependencies] 25 | crossterm = "0.23.0" 26 | colored = "2.0.0" 27 | linefeed = "0.6.0" 28 | crossbeam-channel = "0.5.1" 29 | parking_lot = "0.12.0" 30 | num-format = { version = "0.4.0", features = ["with-system-locale"] } 31 | const_format = "0.2.19" 32 | localzone = "0.2.0" 33 | chrono = "0.4.19" 34 | chrono-tz = "0.6.1" 35 | smartcalc = "1.0.8" 36 | 37 | [dependencies.log] 38 | version = "0.4.14" 39 | # disable logging so it doesn't interrupt tui 40 | features = ["max_level_off", "release_max_level_off"] 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Aaron Ross 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # smartcalc-tui 2 | 3 | Terminal UI for [erhanbaris/smartcalc](https://github.com/erhanbaris/smartcalc), 4 | a new way to do calculations on-the-fly. From the README: 5 | 6 | > Do your calculation on text based queries and see the result immediately. 7 | > Still it is under development but it is enough to use it on daily purpose. 8 | > Supports money conversion, percentage calculation and basis time calculation 9 | > but still not fully supported. For now, we support only in english language 10 | > but if any want to help to translate, we can easily integrate new language. 11 | 12 | A number of different operations are supported. To see the full list, see 13 | [here](https://github.com/erhanbaris/smartcalc). 14 | 15 | ![tui-screenshot](./assets/tui-1.0.1.png) 16 | 17 | ## Project Status 18 | 19 | This project is under active development. Some existing functionality may not 20 | work as expected. 21 | 22 | Use at your own risk :slightly_smiling_face: 23 | 24 | ## License 25 | 26 | The SmartCalc project is distributed under the GNU General Public License. This 27 | project is available under the MIT License, © 2022 Aaron Ross. All rights 28 | reserved. 29 | -------------------------------------------------------------------------------- /assets/tui-1.0.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superhawk610/smartcalc-tui/e22accf50f5d3eb92946522045482b866d0d2b24/assets/tui-1.0.1.png -------------------------------------------------------------------------------- /src/bin/main.rs: -------------------------------------------------------------------------------- 1 | use smartcalc_tui::spawn as spawn_tui; 2 | 3 | fn main() { 4 | if let Err(reason) = spawn_tui() { 5 | eprintln!("whoops! {:?}", reason); 6 | std::process::exit(1); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/calculate.rs: -------------------------------------------------------------------------------- 1 | use crate::syntax::SyntaxToken; 2 | use chrono::{Local, TimeZone}; 3 | use chrono_tz::{OffsetName, Tz}; 4 | use num_format::SystemLocale; 5 | use smartcalc::{Session, SmartCalc}; 6 | 7 | const LANG: &'static str = "en"; 8 | 9 | pub struct Calculate { 10 | app: SmartCalc, 11 | session: Session, 12 | } 13 | 14 | impl Default for Calculate { 15 | fn default() -> Self { 16 | let timezone = match localzone::get_local_zone() { 17 | Some(tz) => match tz.parse::() { 18 | Ok(tz) => { 19 | let dt = Local::today().naive_local(); 20 | tz.offset_from_utc_date(&dt).abbreviation().to_string() 21 | } 22 | Err(_) => "UTC".to_string(), 23 | }, 24 | None => "UTC".to_string(), 25 | }; 26 | 27 | let mut app = SmartCalc::default(); 28 | let locale = SystemLocale::default().unwrap(); 29 | app.set_decimal_seperator(locale.decimal().to_string()); 30 | app.set_thousand_separator(locale.separator().to_string()); 31 | app.set_timezone(timezone).unwrap(); 32 | 33 | let mut session = Session::new(); 34 | session.set_language(LANG.to_string()); 35 | 36 | Self { app, session } 37 | } 38 | } 39 | 40 | impl Calculate { 41 | pub fn execute(&mut self, input: &str) -> Option<(String, Vec)> { 42 | self.session.set_text(input.to_string()); 43 | let res = self.app.execute_session(&self.session); 44 | match &res.lines[0] { 45 | Some(line) => match &line.result { 46 | Ok(result) => { 47 | let output = result.output.clone(); 48 | let tokens = line.ui_tokens.iter().map(|token| token.into()).collect(); 49 | Some((output, tokens)) 50 | } 51 | _ => None, 52 | }, 53 | _ => None, 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | use colored::*; 2 | use const_format::formatcp; 3 | use crossterm::{ 4 | event::{read, Event, KeyCode, KeyModifiers}, 5 | queue, 6 | style::Print, 7 | }; 8 | use std::io::{stdout, Write}; 9 | use std::sync::Arc; 10 | 11 | // TODO: display smartcalc version as well as smartcalc-tui 12 | // (probably want built::util::parse_versions https://docs.rs/built/latest/built/) 13 | const VERSION: &'static str = env!("CARGO_PKG_VERSION"); 14 | 15 | const HEADER: &'static str = formatcp!( 16 | " 17 | ---- smartcalc {} ---- 18 | (ctrl+C / ctrl+D to quit) 19 | ", 20 | VERSION 21 | ); 22 | 23 | mod calculate; 24 | mod prompt; 25 | mod syntax; 26 | mod thread_loop; 27 | 28 | use calculate::Calculate; 29 | use prompt::Prompt; 30 | 31 | pub fn spawn() -> Result<(), Box> { 32 | println!("{}", HEADER); 33 | 34 | let prompt = Prompt::spawn(); 35 | 36 | { 37 | let ps = Arc::downgrade(&prompt.state()); 38 | std::thread::spawn(move || { 39 | let mut calc = Calculate::default(); 40 | 41 | loop { 42 | match ps.upgrade() { 43 | None => { 44 | break; 45 | } 46 | Some(ps) => { 47 | // TODO: memoize 48 | let mut ps = ps.lock(); 49 | // drop(ps) then relock after execution? 50 | if let Some((res, tokens)) = calc.execute(&ps.input) { 51 | ps.set_hint(&res); 52 | ps.set_syntax_tokens(tokens); 53 | } else { 54 | ps.clear_hint(); 55 | } 56 | } 57 | } 58 | 59 | std::thread::sleep(std::time::Duration::from_millis(250)); 60 | } 61 | }); 62 | } 63 | 64 | let ps = prompt.state(); 65 | 66 | while let Event::Key(key_event) = read()? { 67 | let modifier = key_event.modifiers; 68 | match key_event.code { 69 | KeyCode::Char('c') | KeyCode::Char('d') if modifier == KeyModifiers::CONTROL => { 70 | let mut ps = ps.lock(); 71 | 72 | // erase hint then flush 73 | ps.clear_hint(); 74 | let mut stdout = stdout(); 75 | ps.queue_print(&mut stdout)?; 76 | stdout.flush()?; 77 | break; 78 | } 79 | KeyCode::Enter => { 80 | let mut ps = ps.lock(); 81 | 82 | // erase hint then flush 83 | let hint = ps.hint.clone(); 84 | ps.clear_hint(); 85 | ps.cur_offset = 0; 86 | if !hint.is_empty() { 87 | let mut stdout = stdout(); 88 | ps.queue_print(&mut stdout)?; 89 | queue!(stdout, Print(" => ".dimmed()), Print(hint.green()))?; 90 | stdout.flush()?; 91 | } 92 | 93 | // move to next line 94 | ps.clear_input(); 95 | println!(); 96 | } 97 | KeyCode::Char(c) if c.is_ascii() => ps.lock().insert_input(c), 98 | KeyCode::Left => ps.lock().cursor_left(), 99 | KeyCode::Right => ps.lock().cursor_right(), 100 | KeyCode::Backspace => ps.lock().delete_backward(), 101 | KeyCode::Delete => ps.lock().delete_forward(), 102 | // TODO: implement command history 103 | // Key::Up => { } 104 | // Key::Down => { } 105 | _ => (), 106 | } 107 | } 108 | 109 | // cleanup 110 | prompt.stop(); 111 | 112 | Ok(()) 113 | } 114 | -------------------------------------------------------------------------------- /src/prompt.rs: -------------------------------------------------------------------------------- 1 | use crate::syntax::{syntax_highlight, SyntaxToken}; 2 | use crate::thread_loop::ThreadLoop; 3 | use colored::*; 4 | use crossterm::cursor::MoveRight; 5 | use crossterm::queue; 6 | use crossterm::style::Print; 7 | use crossterm::terminal::{disable_raw_mode, enable_raw_mode, Clear, ClearType}; 8 | use parking_lot::Mutex; 9 | use std::fmt::Write as _; 10 | use std::io::{stdout, Write}; 11 | use std::sync::Arc; 12 | 13 | const PROMPT: &'static str = "# "; 14 | 15 | pub struct Prompt { 16 | thread_loop: ThreadLoop, 17 | state: Arc>, 18 | } 19 | 20 | pub struct PromptState { 21 | dirty: bool, 22 | 23 | pub syntax_tokens: Option>, 24 | pub cur_offset: usize, 25 | pub input: String, 26 | pub hint: String, 27 | } 28 | 29 | impl Prompt { 30 | pub fn spawn() -> Self { 31 | let state = Arc::new(Mutex::new(PromptState::new())); 32 | 33 | let thread_loop = { 34 | enable_raw_mode().unwrap(); 35 | let state = Arc::clone(&state); 36 | ThreadLoop::spawn(50, move || { 37 | let mut state = state.lock(); 38 | if state.dirty { 39 | let mut stdout = stdout(); 40 | state.queue_print(&mut stdout).unwrap(); 41 | stdout.flush().unwrap(); 42 | state.mark_clean(); 43 | } 44 | }) 45 | }; 46 | 47 | Self { thread_loop, state } 48 | } 49 | 50 | pub fn state(&self) -> Arc> { 51 | Arc::clone(&self.state) 52 | } 53 | 54 | pub fn stop(self) { 55 | print!("\r\n"); 56 | self.thread_loop.stop(); 57 | disable_raw_mode().unwrap(); 58 | } 59 | } 60 | 61 | impl PromptState { 62 | pub fn new() -> Self { 63 | Self { 64 | dirty: false, 65 | syntax_tokens: None, 66 | cur_offset: 0, 67 | input: String::with_capacity(1024), 68 | hint: String::with_capacity(1024), 69 | } 70 | } 71 | 72 | pub fn queue_print(&self, stdout: &mut std::io::Stdout) -> std::io::Result<()> { 73 | queue!( 74 | stdout, 75 | Clear(ClearType::CurrentLine), 76 | Print(format!("\r{}", PROMPT.dimmed())), 77 | )?; 78 | 79 | if let Some(ref tokens) = self.syntax_tokens { 80 | for s in syntax_highlight(&self.input, tokens) { 81 | queue!(stdout, Print(s))?; 82 | } 83 | } else { 84 | // if no syntax tokens are available, just print the input 85 | queue!(stdout, Print(&self.input))?; 86 | } 87 | 88 | queue!( 89 | stdout, 90 | Print(format!(" {}\r", self.hint.dimmed())), 91 | MoveRight((PROMPT.len() + self.input.len() - self.cur_offset) as u16) 92 | ) 93 | } 94 | 95 | /// Mark the state as dirty after mutating one or more fields. 96 | pub fn mark_dirty(&mut self) { 97 | self.dirty = true; 98 | } 99 | 100 | fn mark_clean(&mut self) { 101 | self.dirty = false; 102 | } 103 | 104 | #[allow(dead_code)] 105 | pub fn append_input(&mut self, input: &str) { 106 | write!(self.input, "{}", input).unwrap(); 107 | self.mark_dirty(); 108 | } 109 | 110 | pub fn insert_input(&mut self, c: char) { 111 | let idx = self.input.len() - self.cur_offset; 112 | self.input.insert(idx, c); 113 | self.mark_dirty(); 114 | } 115 | 116 | /// Also clears any syntax tokens and resets cursor offset. 117 | pub fn clear_input(&mut self) { 118 | self.input.clear(); 119 | self.cur_offset = 0; 120 | self.clear_syntax_tokens(); 121 | self.mark_dirty(); 122 | } 123 | 124 | pub fn set_hint(&mut self, hint: &str) { 125 | self.hint.clear(); 126 | write!(self.hint, "{}", hint).unwrap(); 127 | self.mark_dirty(); 128 | } 129 | 130 | pub fn clear_hint(&mut self) { 131 | self.hint.clear(); 132 | self.mark_dirty(); 133 | } 134 | 135 | pub fn set_syntax_tokens(&mut self, tokens: Vec) { 136 | self.syntax_tokens = Some(tokens); 137 | self.mark_dirty(); 138 | } 139 | 140 | pub fn clear_syntax_tokens(&mut self) { 141 | self.syntax_tokens = None; 142 | self.mark_dirty(); 143 | } 144 | 145 | pub fn cursor_left(&mut self) { 146 | if self.cur_offset < self.input.len() { 147 | self.cur_offset += 1; 148 | self.mark_dirty(); 149 | } 150 | } 151 | 152 | pub fn cursor_right(&mut self) { 153 | if self.cur_offset > 0 { 154 | self.cur_offset -= 1; 155 | self.mark_dirty(); 156 | } 157 | } 158 | 159 | pub fn delete_backward(&mut self) { 160 | let cursor_idx = self.input.len() - self.cur_offset; 161 | if cursor_idx > 0 { 162 | self.input.remove(cursor_idx - 1); 163 | self.clear_syntax_tokens(); 164 | self.mark_dirty(); 165 | } 166 | } 167 | 168 | pub fn delete_forward(&mut self) { 169 | if self.cur_offset > 0 { 170 | self.input.remove(self.input.len() - self.cur_offset); 171 | self.cur_offset -= 1; 172 | self.clear_syntax_tokens(); 173 | self.mark_dirty(); 174 | } 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /src/syntax.rs: -------------------------------------------------------------------------------- 1 | use colored::{Color, ColoredString, Colorize}; 2 | 3 | pub struct SyntaxToken { 4 | pub start: usize, 5 | pub end: usize, 6 | pub color: Color, 7 | } 8 | 9 | impl From<&smartcalc::UiToken> for SyntaxToken { 10 | fn from(token: &smartcalc::UiToken) -> Self { 11 | Self { 12 | start: token.start, 13 | end: token.end, 14 | color: syntax_color(&token.ui_type), 15 | } 16 | } 17 | } 18 | 19 | fn syntax_color(tt: &smartcalc::UiTokenType) -> Color { 20 | use smartcalc::UiTokenType::*; 21 | match tt { 22 | Text => Color::White, 23 | VariableDefination => Color::White, 24 | VariableUse => Color::White, 25 | Comment => Color::White, 26 | Month => Color::White, 27 | DateTime => Color::White, 28 | Number => Color::Cyan, 29 | Symbol1 => Color::Red, 30 | Symbol2 => Color::Red, 31 | Operator => Color::Yellow, 32 | } 33 | } 34 | 35 | pub fn syntax_highlight(s: &str, tokens: &[SyntaxToken]) -> Vec { 36 | let mut index = 0; 37 | let mut strs = Vec::new(); 38 | 39 | for token in tokens.iter() { 40 | debug_assert!( 41 | index <= token.start, 42 | "expected tokens to be in order and not to overlap" 43 | ); 44 | 45 | // there's some input not part of a token 46 | if index < token.start { 47 | strs.push((&s[index..token.start]).into()); 48 | } 49 | 50 | strs.push((&s[token.start..token.end]).color(token.color)); 51 | index = token.end; 52 | } 53 | 54 | // check for trailing input that's not part of a token 55 | if index < s.len() { 56 | strs.push((&s[index..]).into()); 57 | } 58 | 59 | strs 60 | } 61 | 62 | #[cfg(test)] 63 | mod tests { 64 | use super::*; 65 | 66 | macro_rules! tkn { 67 | ($start:literal $end:literal $color:tt) => { 68 | SyntaxToken { 69 | start: $start, 70 | end: $end, 71 | color: Color::$color, 72 | } 73 | }; 74 | } 75 | 76 | macro_rules! check_syntax { 77 | ($input:literal with $tokens:ident => $expected:expr) => { 78 | let highlights = syntax_highlight($input, &$tokens); 79 | let mut output = String::with_capacity(128); 80 | for h in highlights { 81 | output.push_str(&format!("{}", h)); 82 | } 83 | assert_eq!(output, $expected); 84 | }; 85 | } 86 | 87 | #[test] 88 | fn test_syntax_highlight() { 89 | let mut tokens = Vec::new(); 90 | check_syntax!("" with tokens => ""); 91 | 92 | // skipping whitespace 93 | check_syntax!("foo bar" with tokens => "foo bar"); 94 | tokens.push(tkn![0 3 Cyan]); 95 | check_syntax!("foo bar" with tokens => format!("{} bar", "foo".cyan())); 96 | tokens.push(tkn![4 7 Red]); 97 | check_syntax!("foo bar" with tokens => format!("{} {}", "foo".cyan(), "bar".red())); 98 | 99 | // skipping text at the start 100 | let tokens = vec![tkn![4 7 Red]]; 101 | check_syntax!("foo bar" with tokens => format!("foo {}", "bar".red())); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/thread_loop.rs: -------------------------------------------------------------------------------- 1 | use crossbeam_channel::{unbounded, Sender}; 2 | 3 | pub struct ThreadLoop { 4 | handle: std::thread::JoinHandle<()>, 5 | done: Sender<()>, 6 | } 7 | 8 | impl ThreadLoop { 9 | pub fn spawn(tick_rate: u64, mut f: F) -> Self 10 | where 11 | F: FnMut() + Send + 'static, 12 | { 13 | let (tx, rx) = unbounded(); 14 | let handle = std::thread::spawn(move || loop { 15 | if let Ok(()) = rx.try_recv() { 16 | break; 17 | } 18 | 19 | f(); 20 | std::thread::sleep(std::time::Duration::from_millis(tick_rate)); 21 | }); 22 | 23 | Self { handle, done: tx } 24 | } 25 | 26 | pub fn stop(self) { 27 | self.done.send(()).unwrap(); 28 | self.handle.join().unwrap(); 29 | } 30 | } 31 | --------------------------------------------------------------------------------