From d1c09f2561f75a911f044245c96ad2e862444c6c Mon Sep 17 00:00:00 2001 From: "Dustin J. Mitchell" Date: Fri, 9 Nov 2018 19:34:55 -0500 Subject: [PATCH] parse a TDB2 file --- .gitignore | 2 + Cargo.lock | 468 +++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 9 + src/main.rs | 103 +++++++++++ src/nibbler.rs | 292 ++++++++++++++++++++++++++++++ 5 files changed, 874 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/main.rs create mode 100644 src/nibbler.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..53eaa2196 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +**/*.rs.bk diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 000000000..81866a154 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,468 @@ +[[package]] +name = "aho-corasick" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "atty" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bitflags" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cfg-if" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "clap" +version = "2.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "clicolors-control" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "console" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "clicolors-control 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "indicatif" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "console 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "lazy_static" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lazy_static" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.43" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lock_api" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "memchr" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "owning_ref" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rask" +version = "0.1.0" +dependencies = [ + "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "console 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "indicatif 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "redox_syscall" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "redox_termios" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ucd-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ucd-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "scopeguard" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "smallvec" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "stable_deref_trait" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "strsim" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "termion" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "termios" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "textwrap" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thread_local" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ucd-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-width" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "utf8-ranges" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "vec_map" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "version_check" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e" +"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" +"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" +"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" +"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" +"checksum clicolors-control 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f84dec9bc083ce2503908cd305af98bd363da6f54bf8d4bf0ac14ee749ad5d1" +"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum console 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ecd48adf136733979b49e15bc3b4c43cc0d3c85ece7bd08e6daa414c6fcb13e6" +"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +"checksum indicatif 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a29b2fa6f00010c268bface64c18bb0310aaa70d46a195d5382d288c477fb016" +"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" +"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" +"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" +"checksum lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775751a3e69bde4df9b38dd00a1b5d6ac13791e4223d4a0506577f0dd27cfb7a" +"checksum memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0a3eb002f0535929f1199681417029ebea04aadc0c7a4224b46be99c7f5d6a16" +"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" +"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" +"checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" +"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" +"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372" +"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db" +"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" +"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" +"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" +"checksum regex 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ee84f70c8c08744ea9641a731c7fadb475bf2ecc52d7f627feb833e0b3990467" +"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" +"checksum regex-syntax 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fbc557aac2b708fe84121caf261346cc2eed71978024337e42eb46b8a252ac6e" +"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" +"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d" +"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" +"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" +"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" +"checksum termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625" +"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" +"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" +"checksum ucd-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d0f8bfa9ff0cadcd210129ad9d2c5f145c13e9ced3d3e5d948a6213487d52444" +"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" +"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" +"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" +"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" +"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" +"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 000000000..39089eff2 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "rask" +version = "0.1.0" +authors = ["Dustin J. Mitchell "] + +[dependencies] +clap = "2.32" +console = "0.6.2" +indicatif = "0.9.0" diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 000000000..169c99a71 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,103 @@ +mod nibbler; + +use std::str; + +use std::io::{stdin, BufRead, Result, Error, ErrorKind}; +use nibbler::Nibbler; + +/// Decode the given byte slice into a string using Taskwarrior JSON's escaping The slice is +/// assumed to be ASCII; unicode escapes within it will be expanded. +// TODO: return Cow +fn json_decode(value: &[u8]) -> String { + let length = value.len(); + let mut rv = String::with_capacity(length); + + let mut pos = 0; + while pos < length { + let v = value[pos]; + if v == b'\\' { + pos += 1; + if pos == length { + rv.push(v as char); + break; + } + let v = value[pos]; + match v { + b'"' | b'\\' | b'/' => rv.push(v as char), + b'b' => rv.push(8 as char), + b'f' => rv.push(12 as char), + b'n' => rv.push('\n' as char), + b'r' => rv.push('\r' as char), + b't' => rv.push('\t' as char), + b'u' => panic!("omg please no"), + _ => { + rv.push(b'\\' as char); + rv.push(v as char); + } + } + } else { + rv.push(v as char) + } + pos += 1; + } + + rv +} + +fn decode(value: String) -> String { + if let Some(_) = value.find('&') { + return value.replace("&open;", "[").replace("&close;", "]"); + } + value +} + +fn parse_ff4(line: &str) -> Result<()> { + let mut nib = Nibbler::new(line.as_bytes()); + println!("{}", line); + + if !nib.skip(b'[') { + return Err(Error::new(ErrorKind::Other, "bad line")); + } + if let Some(line) = nib.get_until(b']') { + let mut nib = Nibbler::new(line); + while !nib.depleted() { + if let Some(name) = nib.get_until(b':') { + if !nib.skip(b':') { + return Err(Error::new(ErrorKind::Other, "bad line")); + } + if let Some(value) = nib.get_quoted(b'"') { + let value = json_decode(value); + let value = decode(value); + println!("{}={}", str::from_utf8(name).unwrap(), value); + } else { + return Err(Error::new(ErrorKind::Other, "bad line")); + } + nib.skip(b' '); + } else { + return Err(Error::new(ErrorKind::Other, "bad line")); + } + } + } else { + return Err(Error::new(ErrorKind::Other, "bad line")); + } + if !nib.skip(b']') { + return Err(Error::new(ErrorKind::Other, "bad line")); + } + if !nib.depleted() { + return Err(Error::new(ErrorKind::Other, "bad line")); + } + Ok(()) +} + +fn parse_tdb2() -> Result<()> { + let input = stdin(); + for line in input.lock().lines() { + parse_ff4(&line?)?; + } + Ok(()) +} + +fn main() { + parse_tdb2().unwrap(); + println!("Done"); +} diff --git a/src/nibbler.rs b/src/nibbler.rs new file mode 100644 index 000000000..dbc3df920 --- /dev/null +++ b/src/nibbler.rs @@ -0,0 +1,292 @@ +pub struct Nibbler<'a> { + input: &'a [u8], + cursor: usize, +} + +impl<'a> Nibbler<'a> { + pub fn new(input: &'a [u8]) -> Self { + Nibbler { + input: input, + cursor: 0, + } + } + + pub fn get_until(&mut self, c: u8) -> Option<&'a [u8]> { + if self.cursor >= self.input.len() { + return None; + } + + let mut i = self.cursor; + while i < self.input.len() { + if self.input[i] == c { + let rv = &self.input[self.cursor..i]; + self.cursor = i; + return Some(rv); + } + i += 1; + } + let rv = &self.input[self.cursor..]; + self.cursor = self.input.len(); + Some(rv) + } + + // TODO: get_until_str + // TODO: get_until_one_of + // TODO: get_until_ws + + pub fn get_until_eos(&mut self) -> Option<&'a [u8]> { + if self.cursor >= self.input.len() { + return None; + } + let rv = &self.input[self.cursor..]; + self.cursor = self.input.len(); + return Some(rv); + } + + // TODO: get_n + + pub fn get_quoted(&mut self, c: u8) -> Option<&'a [u8]> { + let length = self.input.len(); + if self.cursor >= length || self.input[self.cursor] != c { + return None; + } + + let start = self.cursor + 1; + let mut i = start; + + while i < length { + while i < length && self.input[i] != c { + i += 1 + } + if i == length { + // unclosed quote + return None; + } + if i == start { + return Some(&self.input[i..i]); + } + + if self.input[i - 1] == b'\\' { + // work backward looking for escaped backslashes + let mut j = i - 2; + let mut quote = true; + while j >= start && self.input[j] == b'\\' { + quote = !quote; + j -= 1; + } + + if quote { + i += 1; + continue; + } + } + + // none of the above matched, so we are at the end + self.cursor = i + 1; + return Some(&self.input[start..i]); + } + + unreachable!(); + } + + // TODO: (missing funcs) + + pub fn skip_n(&mut self, n: usize) -> bool { + let length = self.input.len(); + if self.cursor < length && self.cursor + n <= length { + self.cursor += n; + return true; + } + + return false; + } + + pub fn skip(&mut self, c: u8) -> bool { + if self.cursor < self.input.len() && self.input[self.cursor] == c { + self.cursor += 1; + return true; + } + false + } + + // TODO: skip_all_one_of + // TODO: skip_ws + + pub fn next(&mut self) -> Option { + if self.cursor >= self.input.len() { + return None; + } + let rv = self.input[self.cursor]; + self.cursor += 1; + return Some(rv); + } + + // TODO: next_n + // TODO: cursor + // TODO: save + // TODO: restore + + pub fn depleted(&self) -> bool { + self.cursor >= self.input.len() + } +} + +#[cfg(test)] +mod test { + use super::Nibbler; + + #[test] + fn test_get_until() { + let s = b"abc:123"; + let mut nib = Nibbler::new(s); + assert_eq!(nib.get_until(b':'), Some(&s[..3])); + } + + #[test] + fn test_get_until_empty() { + let s = b"abc:123"; + let mut nib = Nibbler::new(s); + assert_eq!(nib.get_until(b'a'), Some(&s[..0])); + } + + #[test] + fn test_get_until_not_found() { + let s = b"abc:123"; + let mut nib = Nibbler::new(s); + assert_eq!(nib.get_until(b'/'), Some(&s[..])); + } + + #[test] + fn test_get_until_eos() { + let s = b"abc:123"; + let mut nib = Nibbler::new(s); + assert_eq!(nib.get_until_eos(), Some(&s[..])); + } + + #[test] + fn test_get_quoted() { + let s = b"'abcd'efg"; + let mut nib = Nibbler::new(s); + assert_eq!(nib.get_quoted(b'\''), Some(&s[1..5])); + assert_eq!(nib.next(), Some(b'e')); + } + + #[test] + fn test_get_quoted_unopened() { + let s = b"abcd'efg"; + let mut nib = Nibbler::new(s); + assert_eq!(nib.get_quoted(b'\''), None); + assert_eq!(nib.next(), Some(b'a')); // nothing consumed + } + + #[test] + fn test_get_quoted_unclosed() { + let s = b"'abcdefg"; + let mut nib = Nibbler::new(s); + assert_eq!(nib.get_quoted(b'\''), None); + assert_eq!(nib.next(), Some(b'\'')); // nothing consumed + } + + #[test] + fn test_get_quoted_escaped() { + let s = b"'abc\\'de'fg"; + let mut nib = Nibbler::new(s); + assert_eq!(nib.get_quoted(b'\''), Some(&s[1..8])); + assert_eq!(nib.next(), Some(b'f')); + } + + #[test] + fn test_get_quoted_double_escaped() { + let s = b"'abc\\\\'de'fg"; + let mut nib = Nibbler::new(s); + assert_eq!(nib.get_quoted(b'\''), Some(&s[1..6])); + assert_eq!(nib.next(), Some(b'd')); + } + + #[test] + fn test_get_quoted_triple_escaped() { + let s = b"'abc\\\\\\'de'fg"; + let mut nib = Nibbler::new(s); + assert_eq!(nib.get_quoted(b'\''), Some(&s[1..10])); + assert_eq!(nib.next(), Some(b'f')); + } + + #[test] + fn test_get_quoted_all_escapes() { + let s = b"'\\\\\\'\\\\'fg"; + let mut nib = Nibbler::new(s); + assert_eq!(nib.get_quoted(b'\''), Some(&s[1..7])); + assert_eq!(nib.next(), Some(b'f')); + } + + #[test] + fn test_skip_n() { + let s = b"abc:123"; + let mut nib = Nibbler::new(s); + assert!(nib.skip_n(3)); + assert_eq!(nib.get_until_eos(), Some(&s[3..])); + } + + #[test] + fn test_skip_n_too_long() { + let s = b"abc:123"; + let mut nib = Nibbler::new(s); + assert!(!nib.skip_n(33)); + // nothing is consumed + assert_eq!(nib.get_until_eos(), Some(&s[..])); + } + + #[test] + fn test_skip_n_exact_eos() { + let s = b"abc:123"; + let mut nib = Nibbler::new(s); + assert!(nib.skip_n(7)); + assert_eq!(nib.get_until_eos(), None); + } + + #[test] + fn test_skip_match() { + let s = b"foo"; + let mut nib = Nibbler::new(s); + assert!(nib.skip(b'f')); + assert_eq!(nib.get_until_eos(), Some(&s[1..])); + } + + #[test] + fn test_skip_no_match() { + let s = b"foo"; + let mut nib = Nibbler::new(s); + assert!(!nib.skip(b'x')); + assert_eq!(nib.get_until_eos(), Some(&s[..])); + } + + #[test] + fn test_skip_eos() { + let s = b"foo"; + let mut nib = Nibbler::new(s); + assert!(nib.skip_n(3)); + assert!(!nib.skip(b'x')); + } + + #[test] + fn test_next() { + let s = b"foo"; + let mut nib = Nibbler::new(s); + assert_eq!(nib.next(), Some(b'f')); + assert_eq!(nib.next(), Some(b'o')); + assert_eq!(nib.next(), Some(b'o')); + assert_eq!(nib.next(), None); + assert_eq!(nib.next(), None); + } + + #[test] + fn test_depleted() { + let s = b"xy"; + let mut nib = Nibbler::new(s); + assert!(!nib.depleted()); + assert_eq!(nib.next(), Some(b'x')); + assert!(!nib.depleted()); + assert_eq!(nib.next(), Some(b'y')); + assert!(nib.depleted()); + } +}