~nicohman/signal-rs

09ca26e73a729229d3a464b7a2c03789361d033d — nicohman 9 months ago 5846622
Use sled to store scli data
6 files changed, 1070 insertions(+), 264 deletions(-)

M Cargo.lock
M Cargo.toml
M src/axolotl.rs
M src/main.rs
M src/scli.rs
M src/signal.rs
M Cargo.lock => Cargo.lock +772 -31
@@ 110,6 110,23 @@ dependencies = [
]

[[package]]
name = "atomicwrites"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a2baf2feb820299c53c7ad1cc4f5914a220a1cb76d7ce321d2522a94b54651f"
dependencies = [
 "nix",
 "tempdir",
 "winapi 0.3.9",
]

[[package]]
name = "autocfg"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"

[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 131,6 148,12 @@ dependencies = [

[[package]]
name = "base64"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"

[[package]]
name = "base64"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"


@@ 142,12 165,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"

[[package]]
name = "bincode"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f30d3a39baa26f9651f17b375061f3233dde33424a8b72b0dbe93a68a0bc896d"
dependencies = [
 "byteorder",
 "serde",
]

[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"

[[package]]
name = "bitpacking"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3744aff20a3437a99ebc0bb7733e9e60c7bf590478c9b897e95b38d57e5acb68"
dependencies = [
 "crunchy",
]

[[package]]
name = "blake2b_simd"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 192,6 234,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"

[[package]]
name = "bytes"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad1f8e949d755f9d79112b5bb46938e0ef9d3804a0b16dfab13aafcaa5f0fa72"

[[package]]
name = "cairo-rs"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 235,6 283,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66120af515773fb005778dc07c261bd201ec8ce50bd6e7144c927753fe013381"

[[package]]
name = "census"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5927edd8345aef08578bcbb4aea7314f340d80c7f4931f99fbeb40b99d8f5060"

[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 256,6 310,19 @@ dependencies = [
]

[[package]]
name = "chrono"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
dependencies = [
 "libc",
 "num-integer",
 "num-traits",
 "time",
 "winapi 0.3.9",
]

[[package]]
name = "cloudabi"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 280,6 347,16 @@ dependencies = [
]

[[package]]
name = "combine"
version = "4.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc4369b5e4c0cddf64ad8981c0111e7df4f7078f4d6ba98fb31f2e17c4c57b7e"
dependencies = [
 "bytes 1.0.0",
 "memchr",
]

[[package]]
name = "confy"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 291,6 368,12 @@ dependencies = [
]

[[package]]
name = "const_fn"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6"

[[package]]
name = "constant_time_eq"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 344,6 427,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"

[[package]]
name = "crc32fast"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
dependencies = [
 "cfg-if 1.0.0",
]

[[package]]
name = "crossbeam"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e"
dependencies = [
 "cfg-if 0.1.10",
 "crossbeam-channel 0.4.4",
 "crossbeam-deque 0.7.3",
 "crossbeam-epoch 0.8.2",
 "crossbeam-queue",
 "crossbeam-utils 0.7.2",
]

[[package]]
name = "crossbeam-channel"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 354,12 460,84 @@ dependencies = [
]

[[package]]
name = "crossbeam-channel"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
dependencies = [
 "cfg-if 1.0.0",
 "crossbeam-utils 0.8.1",
]

[[package]]
name = "crossbeam-deque"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
dependencies = [
 "crossbeam-epoch 0.8.2",
 "crossbeam-utils 0.7.2",
 "maybe-uninit",
]

[[package]]
name = "crossbeam-deque"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
dependencies = [
 "cfg-if 1.0.0",
 "crossbeam-epoch 0.9.1",
 "crossbeam-utils 0.8.1",
]

[[package]]
name = "crossbeam-epoch"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
dependencies = [
 "autocfg 1.0.1",
 "cfg-if 0.1.10",
 "crossbeam-utils 0.7.2",
 "lazy_static",
 "maybe-uninit",
 "memoffset 0.5.5",
 "scopeguard",
]

[[package]]
name = "crossbeam-epoch"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d"
dependencies = [
 "cfg-if 1.0.0",
 "const_fn",
 "crossbeam-utils 0.8.1",
 "lazy_static",
 "memoffset 0.6.1",
 "scopeguard",
]

[[package]]
name = "crossbeam-queue"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570"
dependencies = [
 "cfg-if 0.1.10",
 "crossbeam-utils 0.7.2",
 "maybe-uninit",
]

[[package]]
name = "crossbeam-utils"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
dependencies = [
 "autocfg",
 "autocfg 1.0.1",
 "cfg-if 0.1.10",
 "lazy_static",
]


@@ 370,12 548,18 @@ version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"
dependencies = [
 "autocfg",
 "autocfg 1.0.1",
 "cfg-if 1.0.0",
 "lazy_static",
]

[[package]]
name = "crunchy"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"

[[package]]
name = "dbus"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 495,6 679,51 @@ dependencies = [
]

[[package]]
name = "fail"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f63eec71a3013ee912a0ecb339ff0c5fa5ed9660df04bfefa10c250b885d018c"
dependencies = [
 "lazy_static",
 "log",
 "rand 0.6.5",
]

[[package]]
name = "failure"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86"
dependencies = [
 "backtrace",
 "failure_derive",
]

[[package]]
name = "failure_derive"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
dependencies = [
 "proc-macro2 1.0.20",
 "quote 1.0.7",
 "syn",
 "synstructure",
]

[[package]]
name = "filetime"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c122a393ea57648015bf06fbd3d372378992e86b9ff5a7a497b076a28c79efe"
dependencies = [
 "cfg-if 1.0.0",
 "libc",
 "redox_syscall",
 "winapi 0.3.9",
]

[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 516,6 745,50 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"

[[package]]
name = "fs2"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
dependencies = [
 "libc",
 "winapi 0.3.9",
]

[[package]]
name = "fsevent"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6"
dependencies = [
 "bitflags",
 "fsevent-sys",
]

[[package]]
name = "fsevent-sys"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0"
dependencies = [
 "libc",
]

[[package]]
name = "fst"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "927fb434ff9f0115b215dc0efd2e4fbdd7448522a92a1aa37c77d6a2f8f1ebd6"
dependencies = [
 "byteorder",
]

[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"

[[package]]
name = "fuchsia-zircon"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 571,6 844,7 @@ dependencies = [
 "futures-core",
 "futures-task",
 "futures-util",
 "num_cpus",
]

[[package]]


@@ 627,6 901,15 @@ dependencies = [
]

[[package]]
name = "fxhash"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
dependencies = [
 "byteorder",
]

[[package]]
name = "gdk"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 709,7 992,7 @@ checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
dependencies = [
 "cfg-if 0.1.10",
 "libc",
 "wasi",
 "wasi 0.9.0+wasi-snapshot-preview1",
]

[[package]]


@@ 790,7 1073,7 @@ checksum = "41486a26d1366a8032b160b59065a59fb528530a46a49f627e7048fb8c064039"
dependencies = [
 "anyhow",
 "heck",
 "itertools",
 "itertools 0.9.0",
 "proc-macro-crate",
 "proc-macro-error",
 "proc-macro2 1.0.20",


@@ 819,7 1102,7 @@ dependencies = [
 "gl_generator",
 "glutin",
 "lazy_static",
 "memoffset",
 "memoffset 0.5.5",
 "smallvec 1.4.2",
 "takeable-option",
]


@@ 959,7 1242,7 @@ version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535"
dependencies = [
 "bytes",
 "bytes 0.5.6",
 "fnv",
 "futures-core",
 "futures-sink",


@@ 1007,12 1290,18 @@ dependencies = [
]

[[package]]
name = "htmlescape"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9025058dae765dee5070ec375f591e2ba14638c63feff74f13805a72e523163"

[[package]]
name = "http"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9"
dependencies = [
 "bytes",
 "bytes 0.5.6",
 "fnv",
 "itoa",
]


@@ 1023,7 1312,7 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b"
dependencies = [
 "bytes",
 "bytes 0.5.6",
 "http",
]



@@ 1045,7 1334,7 @@ version = "0.13.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f3afcfae8af5ad0576a31e768415edb627824129e8e5a29b8bfccb2f234e835"
dependencies = [
 "bytes",
 "bytes 0.5.6",
 "futures-channel",
 "futures-core",
 "futures-util",


@@ 1069,7 1358,7 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d979acc56dcb5b8dddba3917601745e877576475aa046df3226eabdecef78eed"
dependencies = [
 "bytes",
 "bytes 0.5.6",
 "hyper",
 "native-tls",
 "tokio",


@@ 1093,17 1382,37 @@ version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2"
dependencies = [
 "autocfg",
 "autocfg 1.0.1",
 "hashbrown",
]

[[package]]
name = "inotify"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f"
dependencies = [
 "bitflags",
 "inotify-sys",
 "libc",
]

[[package]]
name = "inotify-sys"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4563555856585ab3180a5bf0b2f9f8d301a728462afffc8195b3f5394229c55"
dependencies = [
 "libc",
]

[[package]]
name = "input_buffer"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19a8a95243d5a0398cae618ec29477c6e3cb631152be5c19481f80bc71559754"
dependencies = [
 "bytes",
 "bytes 0.5.6",
]

[[package]]


@@ 1129,6 1438,15 @@ checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135"

[[package]]
name = "itertools"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484"
dependencies = [
 "either",
]

[[package]]
name = "itertools"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"


@@ 1186,10 1504,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"

[[package]]
name = "levenshtein_automata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73a004f877f468548d8d0ac4977456a249d8fabbdb8416c36db163dfc8f2e8ca"
dependencies = [
 "fst",
]

[[package]]
name = "libc"
version = "0.2.76"
version = "0.2.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "755456fae044e6fa1ebbbd1b3e902ae19e73097ed4ed87bb79934a867c007bc3"
checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929"

[[package]]
name = "libdbus-sys"


@@ 1334,7 1661,16 @@ version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c198b026e1bbf08a937e94c6c60f9ec4a2267f5b0d2eec9c1b21b061ce2be55f"
dependencies = [
 "autocfg",
 "autocfg 1.0.1",
]

[[package]]
name = "memoffset"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87"
dependencies = [
 "autocfg 1.0.1",
]

[[package]]


@@ 1360,7 1696,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c60c0dfe32c10b43a144bad8fc83538c52f58302c92300ea7ec7bf7b38d5a7b9"
dependencies = [
 "adler",
 "autocfg",
 "autocfg 1.0.1",
]

[[package]]


@@ 1454,6 1790,15 @@ dependencies = [
]

[[package]]
name = "murmurhash32"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d736ff882f0e85fe9689fb23db229616c4c00aee2b3ac282f666d8f20eb25d4a"
dependencies = [
 "byteorder",
]

[[package]]
name = "native-tls"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 1527,6 1872,24 @@ dependencies = [
]

[[package]]
name = "notify"
version = "4.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80ae4a7688d1fab81c5bf19c64fc8db920be8d519ce6336ed4e7efe024724dbd"
dependencies = [
 "bitflags",
 "filetime",
 "fsevent",
 "fsevent-sys",
 "inotify",
 "libc",
 "mio 0.6.22",
 "mio-extras",
 "walkdir",
 "winapi 0.3.9",
]

[[package]]
name = "ntapi"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 1536,12 1899,22 @@ dependencies = [
]

[[package]]
name = "num-integer"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
 "autocfg 1.0.1",
 "num-traits",
]

[[package]]
name = "num-traits"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
dependencies = [
 "autocfg",
 "autocfg 1.0.1",
]

[[package]]


@@ 1638,7 2011,7 @@ version = "0.9.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a842db4709b604f0fe5d1170ae3565899be2ad3d9cbc72dedc789ac0511f78de"
dependencies = [
 "autocfg",
 "autocfg 1.0.1",
 "cc",
 "libc",
 "pkg-config",


@@ 1664,6 2037,51 @@ dependencies = [
]

[[package]]
name = "owned-read"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b66d1e235abcebc845cf93550b89b74f468c051496fafb433ede4104b9f71ba1"
dependencies = [
 "stable_deref_trait",
]

[[package]]
name = "owning_ref"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ff55baddef9e4ad00f88b6c743a2a8062d4c6ade126c2a528644b8e444d52ce"
dependencies = [
 "stable_deref_trait",
]

[[package]]
name = "pallet"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dac317cde4216b159a9e7c450387cd8489107bf0d89f48211e468d244474cf48"
dependencies = [
 "bincode",
 "pallet-macros",
 "rayon",
 "serde",
 "sled",
 "tantivy",
 "tempfile",
 "thiserror",
]

[[package]]
name = "pallet-macros"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7090911079c230fbbaec3ebbd21b80e0c900e8fe82dd7a1c10dc811cc639b07"
dependencies = [
 "proc-macro2 1.0.20",
 "quote 1.0.7",
 "syn",
]

[[package]]
name = "pango"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 1915,15 2333,57 @@ dependencies = [

[[package]]
name = "rand"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
dependencies = [
 "fuchsia-cprng",
 "libc",
 "rand_core 0.3.1",
 "rdrand",
 "winapi 0.3.9",
]

[[package]]
name = "rand"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
dependencies = [
 "autocfg 0.1.7",
 "libc",
 "rand_chacha 0.1.1",
 "rand_core 0.4.2",
 "rand_hc 0.1.0",
 "rand_isaac",
 "rand_jitter",
 "rand_os",
 "rand_pcg",
 "rand_xorshift",
 "winapi 0.3.9",
]

[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
 "getrandom",
 "libc",
 "rand_chacha",
 "rand_core",
 "rand_hc",
 "rand_chacha 0.2.2",
 "rand_core 0.5.1",
 "rand_hc 0.2.0",
]

[[package]]
name = "rand_chacha"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
dependencies = [
 "autocfg 0.1.7",
 "rand_core 0.3.1",
]

[[package]]


@@ 1933,11 2393,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [
 "ppv-lite86",
 "rand_core",
 "rand_core 0.5.1",
]

[[package]]
name = "rand_core"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
dependencies = [
 "rand_core 0.4.2",
]

[[package]]
name = "rand_core"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"

[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"


@@ 1947,11 2422,73 @@ dependencies = [

[[package]]
name = "rand_hc"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
dependencies = [
 "rand_core 0.3.1",
]

[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
 "rand_core",
 "rand_core 0.5.1",
]

[[package]]
name = "rand_isaac"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
dependencies = [
 "rand_core 0.3.1",
]

[[package]]
name = "rand_jitter"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
dependencies = [
 "libc",
 "rand_core 0.4.2",
 "winapi 0.3.9",
]

[[package]]
name = "rand_os"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
dependencies = [
 "cloudabi",
 "fuchsia-cprng",
 "libc",
 "rand_core 0.4.2",
 "rdrand",
 "winapi 0.3.9",
]

[[package]]
name = "rand_pcg"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
dependencies = [
 "autocfg 0.1.7",
 "rand_core 0.4.2",
]

[[package]]
name = "rand_xorshift"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
dependencies = [
 "rand_core 0.3.1",
]

[[package]]


@@ 1964,6 2501,40 @@ dependencies = [
]

[[package]]
name = "rayon"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674"
dependencies = [
 "autocfg 1.0.1",
 "crossbeam-deque 0.8.0",
 "either",
 "rayon-core",
]

[[package]]
name = "rayon-core"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
dependencies = [
 "crossbeam-channel 0.5.0",
 "crossbeam-deque 0.8.0",
 "crossbeam-utils 0.8.1",
 "lazy_static",
 "num_cpus",
]

[[package]]
name = "rdrand"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
dependencies = [
 "rand_core 0.3.1",
]

[[package]]
name = "redox_syscall"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 1988,12 2559,18 @@ checksum = "8963b85b8ce3074fecffde43b4b0dded83ce2f367dc8d363afc56679f3ee820b"
dependencies = [
 "aho-corasick",
 "memchr",
 "regex-syntax",
 "regex-syntax 0.6.20",
 "thread_local",
]

[[package]]
name = "regex-syntax"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e"

[[package]]
name = "regex-syntax"
version = "0.6.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8cab7a364d15cde1e505267766a2d3c4e22a843e1a601f0fa7564c0f82ced11c"


@@ 2014,7 2591,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9eaa17ac5d7b838b7503d118fa16ad88f440498bf9ffe5424e621f93190d61e"
dependencies = [
 "base64 0.12.3",
 "bytes",
 "bytes 0.5.6",
 "encoding_rs",
 "futures-core",
 "futures-util",


@@ 2055,6 2632,16 @@ dependencies = [
]

[[package]]
name = "rust-stemmers"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e46a2036019fdb888131db7a4c847a1063a7493f971ed94ea82c67eada63ca54"
dependencies = [
 "serde",
 "serde_derive",
]

[[package]]
name = "rustc-demangle"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 2249,9 2836,10 @@ dependencies = [
name = "signal-rs"
version = "0.1.0"
dependencies = [
 "anyhow",
 "cairo-rs",
 "confy",
 "crossbeam-channel",
 "crossbeam-channel 0.4.4",
 "dbus",
 "dbus-tokio",
 "enum_variant_type",


@@ 2268,6 2856,7 @@ dependencies = [
 "libhandy",
 "mio 0.7.0",
 "once_cell 0.2.4",
 "pallet",
 "pango",
 "pangocairo",
 "regex",


@@ 2275,6 2864,7 @@ dependencies = [
 "serde",
 "serde_json",
 "serde_repr",
 "tempfile",
 "tokio",
 "tokio-tungstenite",
 "tungstenite",


@@ 2288,6 2878,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"

[[package]]
name = "sled"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fb6824dde66ad33bf20c6e8476f5b82b871bc8bc3c129a10ea2f7dae5060fa3"
dependencies = [
 "crc32fast",
 "crossbeam-epoch 0.8.2",
 "crossbeam-utils 0.7.2",
 "fs2",
 "fxhash",
 "libc",
 "log",
 "parking_lot 0.10.2",
]

[[package]]
name = "smallvec"
version = "0.6.13"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 2319,6 2925,12 @@ dependencies = [
]

[[package]]
name = "snap"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98d3306e84bf86710d6cd8b4c9c3b721d5454cc91a603180f8f8cd06cfd317b4"

[[package]]
name = "socket2"
version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 2331,6 2943,12 @@ dependencies = [
]

[[package]]
name = "stable_deref_trait"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"

[[package]]
name = "stb_truetype"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 2369,6 2987,18 @@ dependencies = [
]

[[package]]
name = "synstructure"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
dependencies = [
 "proc-macro2 1.0.20",
 "quote 1.0.7",
 "syn",
 "unicode-xid 0.2.1",
]

[[package]]
name = "system-deps"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 2390,6 3020,84 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36ae8932fcfea38b7d3883ae2ab357b0d57a02caaa18ebb4f5ece08beaec4aa0"

[[package]]
name = "tantivy"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02e1d2fbfa82ab829208e5f03f4d2c177b8a126252ab4f80ed232e1064770efb"
dependencies = [
 "atomicwrites",
 "base64 0.11.0",
 "bitpacking",
 "byteorder",
 "census",
 "chrono",
 "crc32fast",
 "crossbeam",
 "downcast-rs",
 "fail",
 "failure",
 "fnv",
 "fs2",
 "futures",
 "htmlescape",
 "itertools 0.8.2",
 "levenshtein_automata",
 "log",
 "memmap",
 "murmurhash32",
 "notify",
 "num_cpus",
 "once_cell 1.4.1",
 "owned-read",
 "owning_ref",
 "rayon",
 "regex",
 "rust-stemmers",
 "serde",
 "serde_derive",
 "serde_json",
 "smallvec 1.4.2",
 "snap",
 "stable_deref_trait",
 "tantivy-fst",
 "tantivy-query-grammar",
 "tempfile",
 "uuid",
 "winapi 0.3.9",
]

[[package]]
name = "tantivy-fst"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38878efb477cf2efb7d9112b12b230c27d32abdfec4bea5e66095733f2928610"
dependencies = [
 "byteorder",
 "levenshtein_automata",
 "regex-syntax 0.4.2",
 "utf8-ranges",
]

[[package]]
name = "tantivy-query-grammar"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "900f098da37d350b0e8f116791b9ee43e600704cb6b5cc83b7f826d1b119f21c"
dependencies = [
 "combine",
]

[[package]]
name = "tempdir"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
dependencies = [
 "rand 0.4.6",
 "remove_dir_all",
]

[[package]]
name = "tempfile"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 2397,7 3105,7 @@ checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
dependencies = [
 "cfg-if 0.1.10",
 "libc",
 "rand",
 "rand 0.7.3",
 "redox_syscall",
 "remove_dir_all",
 "winapi 0.3.9",


@@ 2433,6 3141,17 @@ dependencies = [
]

[[package]]
name = "time"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [
 "libc",
 "wasi 0.10.0+wasi-snapshot-preview1",
 "winapi 0.3.9",
]

[[package]]
name = "tinyvec"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 2444,7 3163,7 @@ version = "0.2.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd"
dependencies = [
 "bytes",
 "bytes 0.5.6",
 "fnv",
 "futures-core",
 "iovec",


@@ 2502,7 3221,7 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499"
dependencies = [
 "bytes",
 "bytes 0.5.6",
 "futures-core",
 "futures-sink",
 "log",


@@ 2570,13 3289,13 @@ checksum = "f0308d80d86700c5878b9ef6321f020f29b1bb9d5ff3cab25e75e23f3a492a23"
dependencies = [
 "base64 0.12.3",
 "byteorder",
 "bytes",
 "bytes 0.5.6",
 "http",
 "httparse",
 "input_buffer",
 "log",
 "native-tls",
 "rand",
 "rand 0.7.3",
 "sha-1",
 "url",
 "utf-8",


@@ 2651,6 3370,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7"

[[package]]
name = "utf8-ranges"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4ae116fef2b7fea257ed6440d3cfcff7f190865f170cdad00bb6465bf18ecba"

[[package]]
name = "uuid"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11"
dependencies = [
 "rand 0.7.3",
 "serde",
]

[[package]]
name = "vcpkg"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 2702,6 3437,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"

[[package]]
name = "wasi"
version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"

[[package]]
name = "wasm-bindgen"
version = "0.2.68"
source = "registry+https://github.com/rust-lang/crates.io-index"

M Cargo.toml => Cargo.toml +4 -1
@@ 35,4 35,7 @@ serde_repr = "0.1"
glib-macros = "0.10.0"
dbus-tokio = "0.6.0"
dbus = "0.9.0"
home = "0.5.3"
\ No newline at end of file
home = "0.5.3"	
pallet = "0.6.1"
anyhow  = "1.0"
tempfile = "3.1.0"
\ No newline at end of file

M src/axolotl.rs => src/axolotl.rs +14 -7
@@ 1,10 1,12 @@
use crate::*;

use crate::Message;
use anyhow::Context;
use anyhow::Result;
pub struct AxolotlSession {
    pub res_sender: glib::Sender<SignalResponse>,
    pub contacts: HashMap<String, Contact>,
    pub messages: HashMap<String, BTreeMap<i64, Message>>,
    pub messages: HashMap<String, BTreeMap<i64, SignalMessage>>,
}
impl AxolotlSession {
    pub async fn run(


@@ 38,8 40,7 @@ impl AxolotlSession {
        }
        let msg_p = self.messages.get_mut(&message.source).unwrap();
        if !msg_p.contains_key(&message.sent_at) {
            let msg = Message::new(message.clone());
            msg_p.insert(message.sent_at, msg);
            msg_p.insert(message.sent_at, message.clone());
            self.res_sender
                .send(SignalResponse::AddHist(
                    message.source.clone(),


@@ 68,11 69,17 @@ impl SignalBackend for AxolotlSession {
            messages: HashMap::new(),
        }
    }
    fn messages<'a>(&'a self) -> &'a HashMap<String, BTreeMap<i64, Message>> {
        &self.messages
        fn messages_tel<'a>(&'a self, tel: &str) -> Result<BTreeMap<i64, SignalMessage>> {
            Ok(self.messages.get(tel).context("none")?.clone())
        }
    fn message<'a>(&'a self, tel: &str, id: i64) -> Result<SignalMessage> {
        Ok(self.messages.get(tel).context("none")?.get(&id).context("none")?.clone())
    }
    fn contact<'a>(&'a self, tel: &str) -> Result<Contact> {
        Ok(self.contacts.get(tel).context("none")?.clone())
    }
    fn contacts<'a>(&'a self) -> &'a HashMap<String, Contact> {
        &self.contacts
    fn contacts<'a>(&'a self) -> HashMap<String, Contact> {
        self.contacts.clone()
    }
    fn process_response(&mut self, response: SignalResponse) {
        match response {

M src/main.rs => src/main.rs +32 -29
@@ 1,6 1,7 @@
#![feature(type_alias_impl_trait)]
extern crate confy;
extern crate crossbeam_channel;
extern crate dbus;
extern crate enum_variant_type;
extern crate futures_util;
extern crate gdk_pixbuf;


@@ 10,15 11,17 @@ extern crate gtk;
extern crate libhandy;
extern crate mio;
extern crate reqwest;
extern crate dbus;
extern crate serde;
#[macro_use]
extern crate pallet;
extern crate dbus_tokio;
extern crate home;
extern crate serde_json;
extern crate tempfile;
extern crate tokio;
extern crate tokio_tungstenite;
extern crate tungstenite;
extern crate url;
extern crate dbus_tokio;
extern crate home;
#[macro_use]
extern crate lazy_static;
use futures_util::StreamExt;


@@ 51,13 54,17 @@ use widgets::Settings;
use widgets::*;
mod axolotl;
use axolotl::*;
use std::result::Result;
mod scli;
const BASE_CSS: &'static str = include_str!("base.css");
const SIGNAL_CSS: &'static str = include_str!("signal.css");
const STYLE_CSS: &'static str = include_str!("style.css");
pub trait SignalBackend {
    fn messages<'a>(&'a self) -> &'a HashMap<String, BTreeMap<i64, Message>>;
    fn contacts<'a>(&'a self) -> &'a HashMap<String, Contact>;
    fn messages_tel<'a>(&'a self, tel: &str)
        -> Result<BTreeMap<i64, SignalMessage>, anyhow::Error>;
    fn message<'a>(&'a self, tel: &str, id: i64) -> Result<SignalMessage, anyhow::Error>;
    fn contact<'a>(&'a self, tel: &str) -> Result<Contact, anyhow::Error>;
    fn contacts<'a>(&'a self) -> HashMap<String, Contact>;
    fn process_response(&mut self, response: SignalResponse);
    fn new(res_sender: glib::Sender<SignalResponse>, config: Config) -> Self;
}


@@ 247,17 254,19 @@ where
    pub fn update_chats(&mut self) {
        self.chat_list.chats = HashMap::new();
        for (i, contact) in self.sbackend.contacts().values().enumerate() {
            if let Some(msgs) = self.sbackend.messages().get(&contact.tel) {
                let latest = msgs.values().max_by_key(|x| x.msg.sent_at).unwrap();
                self.chat_list.add_chat(Chat {
                    ID: i as i32,
                    name: contact.name.clone(),
                    tel: contact.tel.clone(),
                    is_group: false,
                    last: latest.msg.message.clone(),
                    timestamp: latest.msg.sent_at,
                    messages: vec![latest.msg.clone()],
                });
            if let Some(msgs) = self.sbackend.messages_tel(&contact.tel).ok() {
                if msgs.len() > 0 {
                    let latest = msgs.values().max_by_key(|x| x.sent_at).unwrap();
                    self.chat_list.add_chat(Chat {
                        ID: i as i32,
                        name: contact.name.clone(),
                        tel: contact.tel.clone(),
                        is_group: false,
                        last: latest.message.clone(),
                        timestamp: latest.sent_at,
                        messages: vec![latest.clone()],
                    });
                }
            }
        }
    }


@@ 289,9 298,9 @@ where
    pub fn show_chat(&mut self, tel: String) {
        self.hide_history();
        let mut history = ChatHistory::new(tel.clone());
        if let Some(map) = self.sbackend.messages().get(&tel) {
        if let Some(map) = self.sbackend.messages_tel(&tel).ok() {
            for m in map.values() {
                history.insert_bottom(Element::Message(m.clone()));
                history.insert_bottom(Element::Message(Message::new(m.clone())));
            }
        }
        self.current_chat.replace(Some(tel.clone()));


@@ 327,19 336,13 @@ where
                }
            },
            SignalResponse::AddHist(tel, id, new) => {
                let msg = self
                    .sbackend
                    .messages()
                    .get(&tel)
                    .unwrap()
                    .get(&id)
                    .unwrap();
                let msg = self.sbackend.message(&tel, id).unwrap();
                if let Some(hist) = self.history.as_mut() {
                    if hist.tel == msg.msg.source {
                    if hist.tel == msg.source {
                        if new {
                            hist.insert_bottom(Element::Message(msg.clone()));
                            hist.insert_bottom(Element::Message(Message::new(msg.clone())));
                        } else {
                            hist.insert_top(Element::Message(msg.clone()));
                            hist.insert_top(Element::Message(Message::new(msg.clone())));
                        }
                        self.last_id.replace(hist.get_last_id());
                    }


@@ 384,7 387,7 @@ impl Message {
    }
}
#[tokio::main]
async fn main() -> Result<()> {
async fn main() -> Result<(), std::boxed::Box<dyn std::error::Error>> {
    let config: Config = confy::load("signal-rs").expect("Couldn't handle config file");
    let _total: Vec<SignalResponse> = vec![];
    let application = Application::new(Some("com.nicohman"), Default::default()).unwrap();

M src/scli.rs => src/scli.rs +237 -192
@@ 1,18 1,23 @@
use crate::Message;
use crate::*;
use anyhow::{Context, Result};
use config::*;
use dbus::message::MatchRule;
use dbus::nonblock;
use dbus_tokio::connection;
use futures_util::StreamExt;
use pallet::Document;
use pallet::Store;
use serde::{Deserialize, Deserializer, Serialize};
use signal::*;
use signal::*;
use std::fs;
use std::io::BufRead;
use std::fs::File;
use std::io::{BufRead, BufWriter, Write};
use std::path::*;
use std::process::Stdio;
use std::time::Duration;
use tempfile::TempDir;
lazy_static! {
    static ref SCLI_ATTACHMENT_DIRECTORY: String = home::home_dir()
        .unwrap()


@@ 22,21 27,12 @@ lazy_static! {
        .unwrap();
}
pub struct SCLISession {
    pub contacts: HashMap<String, Contact>,
    pub messages: HashMap<String, BTreeMap<i64, Message>>,
    pub msg_store: Store<SignalMessage>,
    pub contact_store: Store<Contact>,
    pub config: SignalCLIConfig,
    pub res_sender: glib::Sender<SignalResponse>,
}
impl SCLISession {
    pub fn save(&self) {
        let datafile = DataFile::from_data(self.contacts.clone(), self.messages.clone());
        fs::rename(Path::new(&self.config.data_dir).join("data.json"), Path::new(&self.config.data_dir).join("old.data.json")).expect("Couldn't move current data file to backup");
        fs::write(
            Path::new(&self.config.data_dir).join("data.json"),
            serde_json::to_string(&datafile).unwrap().as_bytes(),
        )
        .expect("Couldn't write data");
    }
    pub fn fetch_contacts_scli(username: &str) -> Vec<Contact> {
        let output = Command::new("signal-cli")
            .arg("--username")


@@ 88,120 84,121 @@ impl SCLISession {
        let cmd_handle = tokio::spawn(async { child.await });
        loop {
            tokio::select! {
                /*msg  = inc.1.next() => {
                    let (timestamp, source , group_id, message, attachments) : (i64, String, Vec<u8>, String, Vec<String>) = msg.unwrap().read5().unwrap();
                    let con_msg = SignalMessage {
                        message,
                            /*msg  = inc.1.next() => {
                                let (timestamp, source , group_id, message, attachments) : (i64, String, Vec<u8>, String, Vec<String>) = msg.unwrap().read5().unwrap();
                                let con_msg = SignalMessage {
                                    message,

                        attachment: None,
                        ID: 0,
                        outgoing: false,
                        source,
                        sent_at: timestamp,
                    };
                    res_sender.send(SignalResponse::IDLessMessage(con_msg)).expect("COuldn't send IDLessMessage");
                },
                msg = inc_sync.1.next() => {
                    let (timestamp, mut source, dest, group_id, message, attachments) : (i64,String,String,Vec<u8>,String,Vec<String>) = msg.unwrap().read_all().unwrap();
                    let mut outgoing = false;
                    if source == config.username {
                        source = dest;
                        outgoing = true;
                    }
                    let con_msg = SignalMessage {
                        message,
                        attachment: None,
                        ID: 0,
                        outgoing,
                        source,
                        sent_at: timestamp,
                    };
                    res_sender.send(SignalResponse::IDLessMessage(con_msg)).expect("COuldn't send IDLessMessage");
                }*/
                msg_line = reader.next_line() => {
                    println!("Incoming!");
                    let parsed : SignalCLIContainer= serde_json::from_str(&msg_line.unwrap().unwrap()).unwrap();
                    if let Some(ref data_msg) = parsed.envelope.data_message {
                                let mut attachment = vec![];
                                if let Some(ats) = &data_msg.attachments {
                                    attachment = parse_attachments(ats);
                                }
                        let con_msg = SignalMessage {
                            message: data_msg.message.clone().unwrap_or_default(),
                            ID: 0,
                            outgoing: false,
                            attachment: Some(attachment),
                            source: parsed.envelope.source.clone(),
                            sent_at: parsed.envelope.timestamp,
                        };
                        res_sender.send(SignalResponse::IDLessMessage(con_msg)).expect("Couldn't send IDLessMessage");
                    } else if let Some(ref sync_msg) = parsed.envelope.sync_message {
                        if let Some(sm) = &sync_msg.sent_message {
                                    attachment: None,
                                    ID: 0,
                                    outgoing: false,
                                    source
            ,                        sent_at: timestamp,
                                };
                                res_sender.send(SignalResponse::IDLessMessage(con_msg)).expect("COuldn't send IDLessMessage");
                            },
                            msg = inc_sync.1.next() => {
                                let (timestamp, mut source, dest, group_id, message, attachments) : (i64,String,String,Vec<u8>,String,Vec<String>) = msg.unwrap().read_all().unwrap();
                                let mut outgoing = false;
                                let mut source = parsed.envelope.source.clone();
                                if parsed.envelope.source == config.username {
                                if source == config.username {
                                    source = dest;
                                    outgoing = true;
                                    source = sm.destination.clone();
                                }
                                let mut attachment = vec![];
                                if let Some(ats) = &sm.attachments {
                                    attachment = parse_attachments(ats);
                                }
                                let con_msg = SignalMessage {
                                    message: sm.message.clone().unwrap_or_default(),
                                    message,
                                    attachment: None,
                                    ID: 0,
                                    outgoing,
                                    attachment: Some(attachment),
                                    source,
                                    sent_at: parsed.envelope.timestamp,
                                    sent_at: timestamp,
                                };
                                res_sender.send(SignalResponse::IDLessMessage(con_msg)).expect("Couldn't send IDLessMessage");
                                res_sender.send(SignalResponse::IDLessMessage(con_msg)).expect("COuldn't send IDLessMessage");
                            }*/
                            msg_line = reader.next_line() => {
                                println!("Incoming!");
                                let parsed : SignalCLIContainer= serde_json::from_str(&msg_line.unwrap().unwrap()).unwrap();
                                if let Some(ref data_msg) = parsed.envelope.data_message {
                                            let mut attachment = vec![];
                                            if let Some(ats) = &data_msg.attachments {
                                                attachment = parse_attachments(ats);
                                            }
                                    let con_msg = SignalMessage {
                                        message: data_msg.message.clone().unwrap_or_default(),
                                        ID: 0,
                                        outgoing: false,
                                        attachment: Some(attachment),
                                        source: parsed.envelope.source.clone(),
                                        sent_at: parsed.envelope.timestamp,
                                    };
                                    res_sender.send(SignalResponse::IDLessMessage(con_msg)).expect("Couldn't send IDLessMessage");
                                } else if let Some(ref sync_msg) = parsed.envelope.sync_message {
                                    if let Some(sm) = &sync_msg.sent_message {
                                            let mut outgoing = false;
                                            let mut source = parsed.envelope.source.clone();
                                            if parsed.envelope.source == config.username {
                                                outgoing = true;
                                                source = sm.destination.clone();
                                            }
                                            let mut attachment = vec![];
                                            if let Some(ats) = &sm.attachments {
                                                attachment = parse_attachments(ats);
                                            }
                                            let con_msg = SignalMessage {
                                                message: sm.message.clone().unwrap_or_default(),
                                                ID: 0,
                                                outgoing,
                                                attachment: Some(attachment),
                                                source,
                                                sent_at: parsed.envelope.timestamp,
                                            };
                                            res_sender.send(SignalResponse::IDLessMessage(con_msg)).expect("Couldn't send IDLessMessage");

                        }
                    }
                }
                inc = req_receiver.recv() => {
                    if let Some(v) = inc {
                        match v {
                            SignalRequest::GetContacts => {
                                println!("Getting contacts");
                                //let contacts = Self::fetch_contacts_scli(config.username.as_str());
                                //res_sender.send(SignalResponse::ContactList(contacts)).expect("Can't send ContactList");
                            }
                            SignalRequest::SendMessage { to, message } => {
                                let (timestamp,) : (i64,) = proxy.method_call("org.asamk.Signal", "sendMessage", (&message,Vec::<String>::new(), vec![&to] )).await.unwrap();
                                res_sender.send(SignalResponse::IDLessMessage(SignalMessage {
                                    message: message,
                                    source: to,
                                    outgoing: true,
                                    attachment: None,
                                    sent_at: timestamp,
                                    ID: 0,
                                })).expect("Couldnt send IDLessMessage");
                                    }
                                }
                            }
                            SignalRequest::AddContact{ name, phone} => {
                                res_sender.send(SignalResponse::ContactList(vec![Contact {name, tel: phone}])).expect("Couldn't send ContactList");
                            },
                            _ => {
                            inc = req_receiver.recv() => {
                                if let Some(v) = inc {
                                    match v {
                                        SignalRequest::GetContacts => {
                                            println!("Getting contacts");
                                            //let contacts = Self::fetch_contacts_scli(config.username.as_str());
                                            //res_sender.send(SignalResponse::ContactList(contacts)).expect("Can't send ContactList");
                                        }
                                        SignalRequest::SendMessage { to, message } => {
                                            let (timestamp,) : (i64,) = proxy.method_call("org.asamk.Signal", "sendMessage", (&message,Vec::<String>::new(), vec![&to] )).await.unwrap();
                                            res_sender.send(SignalResponse::IDLessMessage(SignalMessage {
                                                message: message,
                                                source: to,
                                                outgoing: true,
                                                attachment: None,
                                                sent_at: timestamp,
                                                ID: 0,
                                            })).expect("Couldnt send IDLessMessage");
                                        }
                                        SignalRequest::AddContact{ name, phone} => {
                                            res_sender.send(SignalResponse::ContactList(vec![Contact {name, tel: phone}])).expect("Couldn't send ContactList");
                                        },
                                        SignalRequest::EditContact{ name, phone, id} => {
                                            res_sender.send(SignalResponse::RmContact(id)).expect("Couldn't send RmContact");
                                            res_sender.send(SignalResponse::ContactList(vec![Contact {name, tel: phone}])).expect("Couldn't send ContactList");
                                        },
                                        _ => {

                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        unreachable!();
        conn.remove_match(inc.0.token()).await.unwrap();
    }
    pub fn add_message(&mut self, message: SignalMessage, new: bool) {
        if !self.messages.contains_key(&message.source) {
            self.messages
                .insert(message.source.clone(), BTreeMap::new());
        }
        let msg_p = self.messages.get_mut(&message.source).unwrap();
        if !msg_p.contains_key(&message.sent_at) {
            let msg = Message::new(message.clone());
            msg_p.insert(message.sent_at, msg);
        if self.message(&message.source, message.sent_at).is_err() {
            println!("creating");
            self.msg_store
                .create(&message)
                .expect("Couldn't add message to store");
            self.res_sender
                .send(SignalResponse::AddHist(
                    message.source.clone(),


@@ 210,31 207,33 @@ impl SCLISession {
                ))
                .expect("Couldn't send AddHist");
        }
        self.save();
    }

    pub fn process_scli_msg(&mut self, msg: SignalCLIMessage) {
        /*if !self.contacts.contains_key(&msg.source) {
            self.req_sender.send(SignalRequest::GetContacts).expect("Couldn't send GetContacts");
        }*/
    pub fn process_scli_msg(&mut self, mut msg: SignalCLIMessage) {
        let message: Option<String>;
        let mut outgoing = false;
        if let Some(m) = msg.message {
            println!("text");
            message = Some(m);
        } else if let Some(data) = msg.data_message {
            message = data.message;
            if let Some(dest) = data.destination {
                if msg.source == self.config.username {
                    outgoing = true;
                    msg.source = dest;
                }
            }
        } else {
            println!("Return early");
            return;
        }
        // TODO: Fix outgoing
        if let Some(v) = self.messages.get(&msg.source) {
            let last_id = v.values().map(|msg| msg.msg.ID).max().unwrap();
        if let Some(v) = self.messages_tel(&msg.source).ok() {
            let last_id = v.values().map(|msg| msg.ID).max().unwrap();
            let made_msg = SignalMessage {
                ID: last_id + 1,
                source: msg.source,
                message: message.unwrap(),
                outgoing: false,
                outgoing,
                sent_at: msg.timestamp,
                attachment: None,
            };


@@ 244,67 243,126 @@ impl SCLISession {
                ID: 0,
                source: msg.source,
                message: message.unwrap(),
                outgoing: false,
                outgoing,
                sent_at: msg.timestamp,
                attachment: None,
            };
            self.add_message(made_msg, true);
        }
    }
    fn message_doc<'a>(
        &'a self,
        tel: &str,
        sent_at: i64,
    ) -> Result<Document<SignalMessage>, anyhow::Error> {
        Ok(self
            .msg_store
            .search(format!("source:{} AND sent_at:{}", tel, sent_at).as_str())?
            .hits
            .into_iter()
            .next()
            .context("none")?
            .doc
            .clone())
    }
    fn contact_doc<'a>(&'a self, tel: &str) -> Result<Document<Contact>, anyhow::Error> {
        Ok(self
            .contact_store
            .search(format!("tel:{}", tel).as_str())?
            .hits
            .into_iter()
            .next()
            .context("none")?
            .doc
            .clone())
    }
}
impl SignalBackend for SCLISession {
    fn new(res_sender: glib::Sender<SignalResponse>, config: Config) -> SCLISession {
        let scli_config = config.scli.expect("No configured SCLI settings");
        let mut messages = HashMap::new();
        let mut contacts = HashMap::new();
        let mut to_save = false;
        if fs::metadata(&scli_config.data_dir).is_err() {
            fs::create_dir_all(&scli_config.data_dir).expect("Couldn't create data directory");
            let base_contacts = Self::fetch_contacts_scli(&scli_config.username);
            for contact in base_contacts {
                contacts.insert(contact.tel.clone(), contact);
            }
            to_save = true;
        } else {
            let data = DataFile::load_data(
                Path::new(&scli_config.data_dir)
                    .join("data.json")
                    .to_str()
                    .unwrap(),
            )
            .expect("Couldn't load data file");
            for contact in data.contacts.values() {
                contacts.insert(contact.tel.clone(), contact.clone());
            }
            messages = data
                .messages
                .into_iter()
                .map(|(k, x)| {
                    (
                        k,
                        x.into_iter()
                            .map(|(k, msg)| (k, Message::new(msg)))
                            .collect(),
                    )
                })
                .collect();
        }
        let m_db = pallet::ext::sled::open(
            Path::new(&scli_config.data_dir)
                .join("messages")
                .to_str()
                .unwrap(),
        )
        .unwrap();
        let c_db = pallet::ext::sled::open(
            Path::new(&scli_config.data_dir)
                .join("contacts")
                .to_str()
                .unwrap(),
        )
        .unwrap();
        fs::create_dir("/tmp/sclim");
        fs::create_dir("/tmp/sclic");
        let msg_store = pallet::Store::builder()
            .with_db(m_db)
            .with_index_dir("/tmp/sclim")
            .finish()
            .unwrap();
        let contact_store = pallet::Store::builder()
            .with_db(c_db)
            .with_index_dir("/tmp/sclic")
            .finish()
            .unwrap();
        let session = SCLISession {
            res_sender,
            config: scli_config,
            messages,
            contacts,
            msg_store,
            contact_store,
        };
        if to_save {
            session.save();
        }
        session
    }
    fn messages<'a>(&'a self) -> &'a HashMap<String, BTreeMap<i64, Message>> {
        &self.messages
    fn messages_tel<'a>(&'a self, tel: &str) -> Result<BTreeMap<i64, SignalMessage>> {
        let messages = self
            .msg_store
            .search(format!("source:{}", tel).as_str())?
            .hits;
        Ok(messages
            .into_iter()
            .map(|m| {
                let m = m.doc.inner;
                (m.sent_at, m)
            })
            .collect())
    }
    fn contacts<'a>(&'a self) -> &'a HashMap<String, Contact> {
        &self.contacts
    fn message<'a>(&'a self, tel: &str, sent_at: i64) -> Result<SignalMessage> {
        Ok(self
            .msg_store
            .search(format!("source:{} AND sent_at:{}", tel, sent_at).as_str())?
            .hits
            .into_iter()
            .next()
            .context("none")?
            .doc
            .inner
            .clone())
    }
    fn contact<'a>(&'a self, tel: &str) -> Result<Contact> {
        Ok(self
            .contact_store
            .search(format!("phone:{}", tel).as_str())?
            .hits
            .into_iter()
            .next()
            .context("none")?
            .doc
            .inner
            .clone())
    }
    fn contacts<'a>(&'a self) -> HashMap<String, Contact> {
        let map = self
            .contact_store
            .all()
            .unwrap()
            .into_iter()
            .map(|x| {
                let x = x.inner;
                (x.tel.clone(), x)
            })
            .collect();
        map
    }
    fn process_response(&mut self, response: SignalResponse) {
        match response {


@@ 314,52 372,39 @@ impl SignalBackend for SCLISession {
            }
            SignalResponse::IDLessMessage(mut msg) => {
                let mut id = 0;
                if let Some(v) = self.messages.get(&msg.source) {
                    id = v.values().map(|msg| msg.msg.ID).max().unwrap() + 1;
                if let Some(v) = self.messages_tel(&msg.source).ok() {
                    if (v.len() > 0) {
                        id = v.values().map(|msg| msg.ID).max().unwrap() + 1;
                    }
                }
                msg.ID = id;
                self.add_message(msg, true);
            }
            SignalResponse::RmContact(tel) => {
                if let Some(contact) = self.contact_doc(&tel).ok() {
                    self.contact_store
                        .delete(contact.id)
                        .expect("Couldn't delete contact");
                }
            }
            SignalResponse::ContactList(contacts) => {
                for contact in contacts.into_iter() {
                    if let Some(contact_p) = self.contacts.get_mut(&contact.tel) {
                        *contact_p = contact;
                    if let Some(mut contact_p) = self.contact_doc(&contact.tel).ok() {
                        contact_p.inner = contact;
                        self.contact_store
                            .update(&contact_p)
                            .expect("Couldn't update contact");
                    } else {
                        self.contacts.insert(contact.tel.clone(), contact.clone());
                        self.contact_store
                            .create(&contact)
                            .expect("Couldn't create contact");
                    }
                }
                self.save();
            }
            _ => {}
        }
    }
}
/// The file containing the stored signal messages/contacts
#[derive(Serialize, Deserialize)]
pub struct DataFile {
    pub contacts: HashMap<String, Contact>,
    pub messages: HashMap<String, BTreeMap<i64, SignalMessage>>,
}
impl DataFile {
    pub fn from_data(
        contacts: HashMap<String, Contact>,
        messages: HashMap<String, BTreeMap<i64, Message>>,
    ) -> DataFile {
        DataFile {
            contacts,
            messages: messages
                .into_iter()
                .map(|(k, b)| (k, b.into_iter().map(|(k, v)| (k, v.msg)).collect()))
                .collect(),
        }
    }
    pub fn load_data(
        path: &str,
    ) -> std::result::Result<DataFile, std::boxed::Box<dyn std::error::Error>> {
        let stri = fs::read_to_string(&path)?;
        Ok(serde_json::from_str(&stri)?)
    }
}
/// Turns a vec of SignalCLIAttachments into their Attachment counterparts
pub fn parse_attachments(catt: &Vec<SignalCLIAttachment>) -> Vec<Attachment> {
    catt.into_iter()

M src/signal.rs => src/signal.rs +11 -4
@@ 5,6 5,7 @@ use futures_util::stream::*;
use futures_util::{future, StreamExt};
use gio::subclass::BoxedType;
use glib_macros::*;
use pallet::DocumentLike;
use regex::Regex;
use serde::{Deserialize, Deserializer, Serialize};
use serde_repr::*;


@@ 92,6 93,7 @@ pub enum SignalResponse {
    #[serde(skip)]
    ShowTheme(crate::config::Theme),
    IDLessMessage(SignalMessage),
    RmContact(String),
}

#[derive(Serialize, Deserialize, Clone, Debug)]


@@ 147,7 149,7 @@ pub struct SignalCLIMessage {
    pub is_read: Option<bool>,
    pub is_delivery: Option<bool>,
    pub data_message: Option<DataMessage>,
    pub sync_message: Option<SyncMessage>
    pub sync_message: Option<SyncMessage>,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct SignalCLIContactInfo {


@@ 177,7 179,7 @@ pub struct SentMessage {
    pub message: Option<String>,
    pub expires_in_seconds: u64,
    pub attachments: Option<Vec<SignalCLIAttachment>>,
    //pub group_info: 
    //pub group_info:
    pub destination: String,
}
#[serde(rename_all = "camelCase")]


@@ 198,10 200,12 @@ pub struct SignalCLIAttachment {
    pub id: String,
    pub size: u64,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
#[derive(Serialize, Deserialize, Clone, Debug, DocumentLike)]
#[serde(rename_all = "PascalCase")]
#[pallet(tree_name = "messages")]
pub struct SignalMessage {
    #[serde(rename = "ID")]
    #[pallet(skip_indexing)]
    pub ID: i32,
    /*#[serde(rename = "SID")]
    pub SID: i32,*/


@@ 209,8 213,10 @@ pub struct SignalMessage {
    pub chat_id: String,*/
    pub source: String,
    pub message: String,
    #[pallet(skip_indexing)]
    pub outgoing: bool,
    pub sent_at: i64,
    #[pallet(skip_indexing)]
    #[serde(deserialize_with = "parse_attachment")]
    pub attachment: Option<Vec<Attachment>>,
    //pub received_at: i64,


@@ 270,7 276,8 @@ impl PartialEq for SignalMessage {
trait SignalResponseTrait {}
impl SignalResponseTrait for SignalResponse {}
#[serde(rename_all = "PascalCase")]
#[derive(Serialize, Deserialize, Clone, Debug)]
#[pallet(tree_name = "contacts")]
#[derive(Serialize, Deserialize, Clone, Debug, DocumentLike)]
pub struct Contact {
    pub tel: String,
    //pub uuid: String,