diff --git a/Cargo.lock b/Cargo.lock index 896e7ce..c592174 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,19 +1,28 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. [[package]] -name = "adler32" -version = "1.0.4" +name = "ab_glyph_rasterizer" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" +checksum = "2692800d602527d2b8fea50036119c37df74ab565b10e285706a3dcec0ec3e16" [[package]] -name = "approx" -version = "0.3.2" +name = "adler" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" -dependencies = [ - "num-traits", -] +checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" + +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + +[[package]] +name = "arc-swap" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034" [[package]] name = "arrayref" @@ -23,15 +32,15 @@ checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" [[package]] name = "autocfg" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "base64" -version = "0.11.0" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" [[package]] name = "bitflags" @@ -41,36 +50,18 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "block-buffer" -version = "0.7.3" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding", - "byte-tools", - "byteorder", "generic-array", ] -[[package]] -name = "block-padding" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" -dependencies = [ - "byte-tools", -] - -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" - [[package]] name = "bytemuck" -version = "1.2.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37fa13df2292ecb479ec23aa06f4507928bef07839be9ef15281411076629431" +checksum = "41aa2ec95ca3b5c54cf73c91acf06d24f4495d5f1b1c12506ae3483d646177ac" [[package]] name = "byteorder" @@ -80,15 +71,15 @@ checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" [[package]] name = "bytes" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1" +checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" [[package]] name = "cc" -version = "1.0.54" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bbb73db36c1246e9034e307d0fba23f9a2e251faa47ade70c1bd252220c8311" +checksum = "ef611cc68ff783f18535d77ddd080185275713d852c4f5cbb6122c462a7a825c" [[package]] name = "cfg-if" @@ -98,9 +89,9 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "chrono" -version = "0.4.11" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2" +checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b" dependencies = [ "num-integer", "num-traits", @@ -109,14 +100,23 @@ dependencies = [ [[package]] name = "chrono-tz" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0e430fad0384e4defc3dc6b1223d1b886087a8bf9b7080e5ae027f73851ea15" +checksum = "2554a3155fec064362507487171dcc4edc3df60cb10f3a1fb10ed8094822b120" dependencies = [ "chrono", "parse-zoneinfo", ] +[[package]] +name = "cloudabi" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467" +dependencies = [ + "bitflags", +] + [[package]] name = "color_quant" version = "1.0.1" @@ -148,6 +148,12 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" +[[package]] +name = "cpuid-bool" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" + [[package]] name = "crc32fast" version = "1.2.0" @@ -157,6 +163,16 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-channel" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" +dependencies = [ + "crossbeam-utils", + "maybe-uninit", +] + [[package]] name = "crossbeam-deque" version = "0.7.3" @@ -183,16 +199,6 @@ dependencies = [ "scopeguard", ] -[[package]] -name = "crossbeam-queue" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - [[package]] name = "crossbeam-utils" version = "0.7.2" @@ -212,9 +218,9 @@ checksum = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9" [[package]] name = "deflate" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7e5d2a2273fed52a7f947ee55b092c4057025d7a3e04e5ecdbd25d6c3fb1bd7" +checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" dependencies = [ "adler32", "byteorder", @@ -222,33 +228,45 @@ dependencies = [ [[package]] name = "digest" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ "generic-array", ] [[package]] -name = "either" -version = "1.5.3" +name = "dtoa" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" +checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b" + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "euclid" -version = "0.20.11" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "667703ececa1ac04d1d40ae0c0fd6401b91d8caccfda3a65458ca8ee5dfedf1c" +checksum = "5337024b8293bdce5265dc9570ef6e608a34bfacbbc87fe1a5dcb5f1dac2f4e2" dependencies = [ "num-traits", ] [[package]] -name = "fake-simd" -version = "0.1.2" +name = "flate2" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" +checksum = "766d0e77a2c1502169d4a93ff3b8c15a71fd946cd0126309752104e5f3c46d94" +dependencies = [ + "cfg-if", + "crc32fast", + "libc", + "miniz_oxide 0.4.2", +] [[package]] name = "fnv" @@ -273,22 +291,23 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "generic-array" -version = "0.12.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" dependencies = [ "typenum", + "version_check", ] [[package]] name = "getrandom" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" +checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.9.0+wasi-snapshot-preview1", ] [[package]] @@ -311,8 +330,11 @@ dependencies = [ "euclid", "image", "imageproc", + "log", + "log4rs", "rppal", "rusttype", + "serde", "serde_json", "text_io", "tungstenite", @@ -322,9 +344,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.13" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91780f809e750b0a89f5544be56617ff6b1227ee485bcb06ebe10cdf89bd3b71" +checksum = "4c30f6d0bc6b00693347368a67d41b58f2fb851215ff1da49e90fe2c5c667151" dependencies = [ "libc", ] @@ -346,6 +368,15 @@ version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" +[[package]] +name = "humantime" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" +dependencies = [ + "quick-error", +] + [[package]] name = "idna" version = "0.2.0" @@ -359,9 +390,9 @@ dependencies = [ [[package]] name = "image" -version = "0.23.4" +version = "0.23.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f4167a8f21fa2bb3f17a652a760acd7572645281c98e3b612a26242c96ee" +checksum = "974e194911d1f7efe3cd8a8f9db3b767e43536327e899e8bc9a12ef5711b74d2" dependencies = [ "bytemuck", "byteorder", @@ -377,14 +408,14 @@ dependencies = [ [[package]] name = "imageproc" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4552f3c2cbcf66e0451863120805b480fc421a7a8cf45f19eee5fc4a6fc3a3d3" +checksum = "7b0fbd0ced24e3bc65052406fa6466203fe9c8d1990a3327567433e47109ed1a" dependencies = [ "conv", "image", "itertools", - "num 0.2.1", + "num 0.3.0", "rand", "rand_distr", "rayon", @@ -392,15 +423,6 @@ dependencies = [ "rusttype", ] -[[package]] -name = "inflate" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff" -dependencies = [ - "adler32", -] - [[package]] name = "input_buffer" version = "0.3.1" @@ -411,25 +433,34 @@ dependencies = [ ] [[package]] -name = "itertools" -version = "0.8.2" +name = "instant" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" +checksum = "63312a18f7ea8760cdd0a7c5aac1a619752a246b833545e3e36d1f81f7cd9e66" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "itertools" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" dependencies = [ "either", ] [[package]] name = "itoa" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" +checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" [[package]] name = "jpeg-decoder" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b47b4c4e017b01abdc5bcc126d2d1002e5a75bbe3ce73f9f4f311a916363704" +checksum = "cc797adac5f083b8ff0ca6f6294a999393d76e197c36488e2ef732c4715f6fa3" dependencies = [ "byteorder", "rayon", @@ -443,17 +474,64 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.70" +version = "0.2.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3baa92041a6fec78c687fa0cc2b3fae8884f743d672cf551bed1d6dac6988d0f" +checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235" + +[[package]] +name = "linked-hash-map" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a" + +[[package]] +name = "lock_api" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28247cc5a5be2f05fbcd76dd0cf2c7d3b5400cb978a28042abcd4fa0b3f8261c" +dependencies = [ + "scopeguard", +] [[package]] name = "log" -version = "0.4.8" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" dependencies = [ "cfg-if", + "serde", +] + +[[package]] +name = "log-mdc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a94d21414c1f4a51209ad204c1776a3d0765002c76c6abcb602a6f09f1e881c7" + +[[package]] +name = "log4rs" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e1ad45e4584824d760c35d71868dd7e6e5acd8f5195a9573743b369fc86cd6" +dependencies = [ + "arc-swap", + "chrono", + "flate2", + "fnv", + "humantime", + "libc", + "log", + "log-mdc", + "parking_lot", + "serde", + "serde-value", + "serde_derive", + "serde_json", + "serde_yaml", + "thread-id", + "typemap", + "winapi", ] [[package]] @@ -485,22 +563,32 @@ checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" [[package]] name = "memoffset" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8" +checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" dependencies = [ "autocfg", ] [[package]] name = "miniz_oxide" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa679ff6578b1cddee93d7e82e263b94a575e0bfced07284eb0c037c1d2416a5" +checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" dependencies = [ "adler32", ] +[[package]] +name = "miniz_oxide" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c60c0dfe32c10b43a144bad8fc83538c52f58302c92300ea7ec7bf7b38d5a7b9" +dependencies = [ + "adler", + "autocfg", +] + [[package]] name = "native-tls" version = "0.2.4" @@ -532,9 +620,9 @@ dependencies = [ [[package]] name = "num" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8536030f9fea7127f841b45bb6243b27255787fb4eb83958aa1ef9d2fdc0c36" +checksum = "ab3e176191bc4faad357e3122c4747aa098ac880e88b168f106386128736cf4a" dependencies = [ "num-bigint", "num-complex", @@ -546,9 +634,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.2.6" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +checksum = "b7f3fc75e3697059fb1bc465e3d8cca6cf92f56854f201158b3f9c77d5a3cfa0" dependencies = [ "autocfg", "num-integer", @@ -557,19 +645,18 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.2.4" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" +checksum = "b05ad05bd8977050b171b3f6b48175fea6e0565b7981059b486075e1026a9fb5" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-integer" -version = "0.1.42" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" +checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" dependencies = [ "autocfg", "num-traits", @@ -577,9 +664,9 @@ dependencies = [ [[package]] name = "num-iter" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfb0800a0291891dd9f4fe7bd9c19384f98f7fbe0cd0f39a2c6b88b9868bbc00" +checksum = "7a6e6b7c748f995c4c29c5f5ae0248536e04a5739927c74ec0fa564805094b9f" dependencies = [ "autocfg", "num-integer", @@ -588,9 +675,9 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.2.4" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +checksum = "a5b4d7360f362cfb50dde8143501e6940b22f644be75a4cc90b2d81968908138" dependencies = [ "autocfg", "num-bigint", @@ -600,9 +687,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" +checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" dependencies = [ "autocfg", ] @@ -619,15 +706,15 @@ dependencies = [ [[package]] name = "opaque-debug" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.29" +version = "0.10.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee6d85f4cb4c4f59a6a85d5b68a233d280c82e29e822913b9c8b129fbf20bdd" +checksum = "8d575eff3665419f9b83678ff2815858ad9d11567e082f5ac1814baba4e2bcb4" dependencies = [ "bitflags", "cfg-if", @@ -645,9 +732,9 @@ checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" [[package]] name = "openssl-sys" -version = "0.9.57" +version = "0.9.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7410fef80af8ac071d4f63755c0ab89ac3df0fd1ea91f1d1f37cf5cec4395990" +checksum = "a842db4709b604f0fe5d1170ae3565899be2ad3d9cbc72dedc789ac0511f78de" dependencies = [ "autocfg", "cc", @@ -658,18 +745,53 @@ dependencies = [ [[package]] name = "ordered-float" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518" +checksum = "3741934be594d77de1c8461ebcbbe866f585ea616a9753aa78f2bdc69f0e4579" dependencies = [ "num-traits", ] [[package]] -name = "parse-zoneinfo" -version = "0.2.1" +name = "owned_ttf_parser" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feece9d0113b400182a7d00adcff81ccf29158c49c5abd11e2eed8589bf6ff07" +checksum = "9f923fb806c46266c02ab4a5b239735c144bdeda724a50ed058e5226f594cde3" +dependencies = [ + "ttf-parser", +] + +[[package]] +name = "parking_lot" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b" +dependencies = [ + "cfg-if", + "cloudabi", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi", +] + +[[package]] +name = "parse-zoneinfo" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41" dependencies = [ "regex", ] @@ -682,27 +804,51 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pkg-config" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" +checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33" [[package]] name = "png" -version = "0.16.3" +version = "0.16.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c68a431ed29933a4eb5709aca9800989758c97759345860fa5db3cfced0b65d" +checksum = "dfe7f9f1c730833200b134370e1d5098964231af8450bce9b78ee3ab5278b970" dependencies = [ "bitflags", "crc32fast", "deflate", - "inflate", + "miniz_oxide 0.3.7", ] [[package]] name = "ppv-lite86" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea" +checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20" + +[[package]] +name = "proc-macro2" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quote" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +dependencies = [ + "proc-macro2", +] [[package]] name = "rand" @@ -762,10 +908,11 @@ checksum = "ebac11a9d2e11f2af219b8b8d833b76b1ea0e054aa0e8d8e9e4cbde353bdf019" [[package]] name = "rayon" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098" +checksum = "cfd016f0c045ad38b5251be2c9c0ab806917f82da4d36b2a327e5166adad9270" dependencies = [ + "autocfg", "crossbeam-deque", "either", "rayon-core", @@ -773,12 +920,12 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9" +checksum = "e8c4fec834fb6e6d2dd5eece3c7b432a52f0ba887cf40e595190c4107edc08bf" dependencies = [ + "crossbeam-channel", "crossbeam-deque", - "crossbeam-queue", "crossbeam-utils", "lazy_static", "num_cpus", @@ -786,9 +933,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.1.56" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "regex" @@ -807,9 +954,9 @@ checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" [[package]] name = "remove_dir_all" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" dependencies = [ "winapi", ] @@ -836,13 +983,12 @@ dependencies = [ [[package]] name = "rusttype" -version = "0.8.3" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f61411055101f7b60ecf1041d87fb74205fb20b0c7a723f07ef39174cf6b4c0" +checksum = "dc7c727aded0be18c5b80c1640eae0ac8e396abf6fa8477d96cb37d18ee5ec59" dependencies = [ - "approx", - "ordered-float", - "stb_truetype", + "ab_glyph_rasterizer", + "owned_ttf_parser", ] [[package]] @@ -898,15 +1044,39 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.111" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9124df5b40cbd380080b2cc6ab894c040a3070d995f5c9dc77e18c34a8ae37d" +checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-value" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a65a7291a8a568adcae4c10a677ebcedbc6c9cec91c054dee2ce40b0e3290eb" +dependencies = [ + "ordered-float", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.116" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "serde_json" -version = "1.0.53" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "993948e75b189211a9b31a7528f950c6adc21f9720b6438ff80a7fa2f864cea2" +checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c" dependencies = [ "itoa", "ryu", @@ -914,30 +1084,45 @@ dependencies = [ ] [[package]] -name = "sha-1" -version = "0.8.2" +name = "serde_yaml" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" +checksum = "ae3e2dd40a7cdc18ca80db804b7f461a39bb721160a85c9a1fa30134bf3c02a5" +dependencies = [ + "dtoa", + "linked-hash-map", + "serde", + "yaml-rust", +] + +[[package]] +name = "sha-1" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "170a36ea86c864a3f16dd2687712dd6646f7019f301e57537c7f4dc9f5916770" dependencies = [ "block-buffer", + "cfg-if", + "cpuid-bool", "digest", - "fake-simd", "opaque-debug", ] [[package]] name = "smallvec" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4" +checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252" [[package]] -name = "stb_truetype" -version = "0.3.1" +name = "syn" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f77b6b07e862c66a9f3e62a07588fee67cd90a9135a2b942409f195507b4fb51" +checksum = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b" dependencies = [ - "byteorder", + "proc-macro2", + "quote", + "unicode-xid", ] [[package]] @@ -961,31 +1146,61 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6cb170b4f47dc48835fbc56259c12d8963e542b05a24be2e3a1f5a6c320fd2d4" [[package]] -name = "tiff" -version = "0.4.0" +name = "thread-id" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "002351e428db1eb1d8656d4ca61947c3519ac3191e1c804d4600cd32093b77ad" -dependencies = [ - "byteorder", - "lzw", - "miniz_oxide", -] - -[[package]] -name = "time" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +checksum = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" dependencies = [ "libc", + "redox_syscall", "winapi", ] [[package]] -name = "tungstenite" -version = "0.10.1" +name = "tiff" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfea31758bf674f990918962e8e5f07071a3161bd7c4138ed23e416e1ac4264e" +checksum = "3f3b8a87c4da944c3f27e5943289171ac71a6150a79ff6bacfff06d159dfff2f" +dependencies = [ + "byteorder", + "lzw", + "miniz_oxide 0.3.7", +] + +[[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", +] + +[[package]] +name = "tinyvec" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "238ce071d267c5710f9d31451efec16c5ee22de34df17cc05e56cbc92e967117" + +[[package]] +name = "traitobject" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" + +[[package]] +name = "ttf-parser" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e5d7cd7ab3e47dda6e56542f4bbf3824c15234958c6e1bd6aaa347e93499fdc" + +[[package]] +name = "tungstenite" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0308d80d86700c5878b9ef6321f020f29b1bb9d5ff3cab25e75e23f3a492a23" dependencies = [ "base64", "byteorder", @@ -1001,6 +1216,15 @@ dependencies = [ "utf-8", ] +[[package]] +name = "typemap" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "653be63c80a3296da5551e1bfd2cca35227e13cdd08c6668903ae2f4f77aa1f6" +dependencies = [ + "unsafe-any", +] + [[package]] name = "typenum" version = "1.12.0" @@ -1018,11 +1242,26 @@ dependencies = [ [[package]] name = "unicode-normalization" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4" +checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977" dependencies = [ - "smallvec", + "tinyvec", +] + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + +[[package]] +name = "unsafe-any" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30360d7979f5e9c6e6cea48af192ea8fab4afb3cf72597154b8f08935bc9c7f" +dependencies = [ + "traitobject", ] [[package]] @@ -1044,9 +1283,15 @@ checksum = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7" [[package]] name = "vcpkg" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55d1e41d56121e07f1e223db0a4def204e45c85425f6a16d462fd07c8d10d74c" +checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c" + +[[package]] +name = "version_check" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" [[package]] name = "wasi" @@ -1055,10 +1300,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] -name = "winapi" -version = "0.3.8" +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", @@ -1081,3 +1332,12 @@ name = "xml-rs" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b07db065a5cf61a7e4ba64f29e67db906fb1787316516c4e6e5ff0fea1efcd8a" + +[[package]] +name = "yaml-rust" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39f0c922f1a334134dc2f7a8b67dc5d25f0735263feec974345ff706bcf20b0d" +dependencies = [ + "linked-hash-map", +] diff --git a/Cargo.toml b/Cargo.toml index b627c5d..cc7e78a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,9 +14,12 @@ arrayref = "*" chrono = "*" chrono-tz = "*" euclid = "*" +log = "*" +log4rs = { version = "*", features = ["file", "yaml_format", "console_appender"] } xml-rs = "0.8" text_io = "0.1.8" +serde = { version = "*", features = ["derive"] } serde_json = "*" -rusttype = "0.8.3" +rusttype = "0.9.2" tungstenite = "*" url = "*" diff --git a/README.md b/README.md index 61fae1f..02c881f 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ The idea is to find a cheap, small, GPIO connected monitor and have it display u * Very cheap cockpit display software for Openplotter on the Raspberry PI. * Bought on eBay, for size, and use of less GPIO pins. Thus ended up buying an ili9488 based 3.5 inch TFT LCD. I would love to get something transflective in the future. It turned out the ili9488 is very poorly supported in the linux fb world; I've ordered a 2.8 inch ili9341 based display to try that one out too. * Reference platform is the Raspberry PI 3 Model B; reasons being: - * It seems to be powerful enough, it's a 1.2 GHz 64 bit qtad-core ARM Cortex-A53 processor and 1 GiB of memory. Furthermore is has 4 USB ports, making it less likely that I'll need a USB hub; also, it has WiFi should I want to play around with that. Newer, more powerful models are very neat, but they also have a significantly higher power consumption, model B idles at about 230 mA (1.2 W) where the B+, for example, idles at 350 mA (1.7 W) + * It seems to be powerful enough, it's a 1.2 GHz 64 bit quad-core ARM Cortex-A53 processor and 1 GiB of memory. Furthermore is has 4 USB ports, making it less likely that I'll need a USB hub; also, it has WiFi should I want to play around with that. Newer, more powerful models are very neat, but they also have a significantly higher power consumption, model B idles at about 230 mA (1.2 W) where the B+, for example, idles at 350 mA (1.7 W) # Software considerations diff --git a/log4rs.yml b/log4rs.yml new file mode 100644 index 0000000..29132ff --- /dev/null +++ b/log4rs.yml @@ -0,0 +1,8 @@ +refresh_rate: 30 seconds +appenders: + stdout: + kind: console +root: + level: info + appenders: + - stdout diff --git a/src/forms.rs b/src/forms.rs index f5c4060..006d7ec 100644 --- a/src/forms.rs +++ b/src/forms.rs @@ -11,6 +11,7 @@ use std::error::Error; use std::fs::File; use std::io::BufReader; use std::io::Read; +use std::rc::Rc; use std::fs; use xml::reader::{EventReader, XmlEvent}; use euclid::Point2D; @@ -72,20 +73,13 @@ impl Loader { pub fn load_font (&mut self, path: &str) -> Option { - let mut file = match self.make_file(path) { - Some(f) => f, - None => return None, + let fullpath = match self.make_path(path) { + Some(p) => p, + None => return None, }; - let mut data = Vec::new(); - if file.read_to_end(&mut data).is_err() { - return None; - } - - let font = match Font::from_bytes(data) { - Ok(data) => data, - Err(_) => return None, - }; - Some(font) + let data = fs::read(fullpath).expect("File read error"); + let font = move || Font::try_from_bytes(&data).unwrap(); + Some(font()) } pub fn load_form(&mut self, path: &str) -> Option
{ @@ -155,7 +149,7 @@ impl Screen { pub fn render (&mut self, form: &Form, angle: f32, x: u16, y: u16) { - let transform : Transform2D = Transform2D::create_rotation(Angle::radians(angle)).post_translate(Vector2D::new(500.0, 500.0)); + let transform : Transform2D = Transform2D::rotation(Angle::radians(angle)).then_translate(Vector2D::new(500.0, 500.0)); let tx_points = form.points.iter().map(|p| transform.transform_point(*p)).collect::>(); let screen_points = tx_points.iter().map(|p| self.model_scale.transform_point(*p)).collect::>(); for (indices, weight, (r, g, b)) in &form.lines { diff --git a/src/main.rs b/src/main.rs index da7a0dc..44282bd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,11 @@ use std::time::Duration; use std::f32::consts::PI; use chrono::{DateTime, Utc}; use chrono_tz::Tz; +use rusttype::Font; +#[macro_use] +extern crate log; +use log4rs; use image::{ Rgb, @@ -18,12 +22,134 @@ use imageproc::drawing::draw_filled_rect_mut; mod ilidisplay; mod forms; mod signalk; +mod vesseldata; +use vesseldata::VesselDataEventSource; + +pub struct HelmsDisplay { + font: Box>, + boat: forms::Form, + compassrose: forms::Form, + cog: forms::Form, + wind: forms::Form, + gps_screen: forms::Screen, + time_screen: forms::Screen, + course_screen: forms::Screen, +} + +impl HelmsDisplay { + + pub fn new() -> HelmsDisplay { + // in the future, this method should probably take some sort of + // configuration object. + let mut loader = forms::Loader::new("/root/helms-display".to_string()); + let boat = loader.load_form("boat.svg").unwrap(); + let compassrose = loader.load_form("compass-rose.svg").unwrap(); + let cog = loader.load_form("cog.svg").unwrap(); + let wind = loader.load_form("wind.svg").unwrap(); + let f = loader.load_font("font.ttf").unwrap(); + let font = Box::new(f); + + HelmsDisplay { + font: font, + boat: boat, + compassrose: compassrose, + cog: cog, + wind: wind, + gps_screen: forms::Screen::new(400, 40), + time_screen: forms::Screen::new(200, 60), + course_screen: forms::Screen::new(200, 200), + } + } + + pub fn render_gps (&mut self, loc: Option) { + self.gps_screen.clear(); + match loc { + None => self.gps_screen.text_c(&self.font, " --\u{00B0}--\u{2032}--\u{2033} --\u{00B0}--\u{2032}--\u{2033}", 32.0, 200, 5), + Some(vesseldata::VesselDataEvent::Location(lat,lon)) => { + + // format with unicodes for degrees, minutes and seconds. + let (latitude, lat_ew) = { + if lat < 0.0 { + (-lat, 'W') + } else if lat > 0.0 { + (lat, 'E') + } else { + (0.0, '-') + } + }; + + let (longitude, long_ns) = { + if lon < 0.0 { + (-lon, 'S') + } else if lon > 0.0 { + (lon, 'N') + } else { + (0.0, '-') + } + }; + + let long_d: u8 = longitude.trunc() as u8; + let longitude = longitude.fract() * 60.0; + let long_m: u8 = longitude.trunc() as u8; + let longitude = longitude.fract() * 60.0; + let long_s: u8 = longitude.round() as u8; + + let lat_d: u8 = latitude.trunc() as u8; + let latitude = latitude.fract() * 60.0; + let lat_m: u8 = latitude.trunc() as u8; + let latitude = latitude.fract() * 60.0; + let lat_s: u8 = latitude.round() as u8; + self.gps_screen.text_c(&self.font, + format!("{}{:02}\u{00B0}{:02}\u{2032}{:02}\u{2033} {}{:02}\u{00B0}{:02}\u{2032}{:02}\u{2033}", + long_ns, long_d, long_m, long_s, lat_ew, lat_d, lat_m, lat_s).as_str(), 32.0, 200, 5); + }, + _ => (), + } + } + + pub fn render_time (&mut self) { + let tz: Tz = "Europe/Copenhagen".parse().unwrap(); + let now = Utc::now().with_timezone(&tz); + self.time_screen.text_c(&self.font, now.format("%H:%M:%S %Z").to_string().as_str(), 24.0, 100, 1); + self.time_screen.text_c(&self.font, "Europe/Copenhagen", 16.0, 100, 25); + self.time_screen.text_c(&self.font, now.format("%Y-%m-%d").to_string().as_str(), 16.0, 100, 43); + } + + pub fn render_course (&mut self, cog: Option, magnetic: Option, wind: Option) { + let rad = (6 as f32) * 2.0*PI / 100.0; + self.course_screen.clear(); + + // render course over ground if present + match cog { + Some(vesseldata::VesselDataEvent::CourseOverGround(c)) => { + self.course_screen.render(&self.cog, c, 500, 500); + }, + _ => (), + }; + + // render wind if present + match wind { + Some(vesseldata::VesselDataEvent::WindOrigin(o)) => { + self.course_screen.render(&self.wind, o, 500, 500); + }, + _ => (), + }; + + // render compass rose + + self.course_screen.render(&self.compassrose, rad, 500, 500); + self.course_screen.render(&self.boat, 0.0, 500, 500); + } + +} fn main() -> Result<(), Box> { + // init log library + log4rs::init_file("log4rs.yml", Default::default()).unwrap(); + let mut course_screen = forms::Screen::new(200, 200); let mut sog_screen = forms::Screen::new(160,60); - let mut gps_screen = forms::Screen::new(400, 40); let mut time_screen = forms::Screen::new(200, 60); let mut loader = forms::Loader::new("/root/helms-display".to_string()); @@ -32,8 +158,10 @@ fn main() -> Result<(), Box> { let b = loader.load_form("boat.svg").unwrap(); let cog = loader.load_form("cog.svg").unwrap(); let wind = loader.load_form("wind.svg").unwrap(); - let font = loader.load_font("font.ttf").unwrap(); + //let font = loader.load_font("font.ttf").unwrap(); + let f2 = loader.load_font("font.ttf").unwrap(); + let mut helms = HelmsDisplay::new(); /* let mut img = RgbImage::new(480, 320); let thickness = 10; @@ -54,8 +182,9 @@ fn main() -> Result<(), Box> { course_screen.render(&wind, rad*2.0, 500, 500); course_screen.render(&c, rad, 500, 500); course_screen.render(&b, 0.0, 500, 500); - e.put_image(&(course_screen.image), (160, (160-100))); + e.put_image(&(course_screen.image), (140, (160-110))); +/* sog_screen.clear(); sog_screen.text(&font, "SOG", 32.0, 5, 5); sog_screen.text(&font, "speed over ground", 12.0, 5, 38); @@ -63,41 +192,21 @@ fn main() -> Result<(), Box> { let speed_over_ground = speed_over_ground * 1.9438612860586; // now in nautic miles per hour sog_screen.text_rj(&font, format!("{:.1}", speed_over_ground).as_str(), 32.0, 138, 5); sog_screen.fraction(&font, "nm", "h", 14.0, 140, 6); - e.put_image(&(sog_screen.image), (0, 0)); + e.put_image(&(sog_screen.image), (0, 50)); +*/ - gps_screen.clear(); - // format with unicodes for degrees, minutes and seconds. - let longitude: f32 = 55.658863; - let latitude: f32 = 12.480960; + helms.render_gps(None); + e.put_image(&(helms.gps_screen.image), (40,0)); - let long_d: u8 = longitude.trunc() as u8; - let longitude = longitude.fract() * 60.0; - let long_m: u8 = longitude.trunc() as u8; - let longitude = longitude.fract() * 60.0; - let long_s: u8 = longitude.round() as u8; - let long_ns: char = 'N'; - - let lat_d: u8 = latitude.trunc() as u8; - let latitude = latitude.fract() * 60.0; - let lat_m: u8 = latitude.trunc() as u8; - let latitude = latitude.fract() * 60.0; - let lat_s: u8 = latitude.round() as u8; - let lat_ew: char = 'E'; - gps_screen.text_c(&font, format!("{}{:02}\u{00B0}{:02}\u{2032}{:02}\u{2033} {}{:02}\u{00B0}{:02}\u{2032}{:02}\u{2033}", long_ns, long_d, long_m, long_s, lat_ew, lat_d, lat_m, lat_s).as_str(), 32.0, 200, 5); - e.put_image(&(gps_screen.image), (240,370)); - - time_screen.clear(); - let tz: Tz = "Europe/Copenhagen".parse().unwrap(); - let now = Utc::now().with_timezone(&tz); - time_screen.text_c(&font, now.format("%H:%M:%S %Z").to_string().as_str(), 24.0, 100, 1); - time_screen.text_c(&font, "Europe/Copenhagen", 16.0, 100, 25); - time_screen.text_c(&font, now.format("%Y-%m-%d").to_string().as_str(), 16.0, 100, 43); - time_screen.save(); + helms.render_time(); + e.put_image(&(helms.time_screen.image), (140,260)); println!("Display has been rendered now, sleeping for 5s"); - signalk::SignalKData::connect(); - thread::sleep(Duration::from_millis(5000)); + let vd = signalk::SignalK::connect(); + + thread::sleep(Duration::from_millis(15000)); e.turn_off(); Ok(()) + } diff --git a/src/signalk.rs b/src/signalk.rs index fea1c1f..ca2fd4d 100644 --- a/src/signalk.rs +++ b/src/signalk.rs @@ -1,32 +1,65 @@ use std::thread; +use std::io::{BufReader, Read}; use tungstenite::connect; use url::Url; -use serde_json::{Result, Value}; +use serde::Deserialize; +use serde_json::Value as JValue; +use std::sync::mpsc::{Sender, Receiver}; +use std::sync::mpsc; +use crate::vesseldata::{VesselDataEvent, VesselDataEventSource}; -// Model the data sent over SignalK Websocket -// that I'm interested in -pub enum SignalKEvent { - SpeedOverGround(f32), - SpeedThroughWater(f32), - Location(f32, f32), - CourseOverGround(f32), - TrueCompassCourse(f32), - AISVessel(String, f32, f32, f32), // Name, lat, long, speed - BatteryLevel(u8, u8), // Bank#, percentage - FuelLevel(u8), // percentage + +#[derive(Debug, Deserialize)] +#[serde()] +struct Source { + sentence: String, + talker: String, + #[serde(rename = "type")] + k_type: String, + label: String, } - -pub struct SignalKData { - latitude: f32, - longitude: f32, - position_timestamp: u64, +#[derive(Debug, Deserialize)] +#[serde()] +struct Value { + path: String, + value: JValue, } -impl SignalKData { +#[derive(Debug, Deserialize)] +#[serde()] +struct Update { + #[serde(rename = "$source")] + dsource: String, + timestamp: String, + values: Vec, +} - pub fn parseJson (json: String) -> Vec { - let res = Vec::::new(); +#[derive(Debug, Deserialize)] +#[serde()] +struct SignalKEventData { + context: String, + updates: Vec, +} + +#[derive(Debug, Deserialize)] +#[serde()] +struct SignalKHeader { + name: String, + version: String, + #[serde(rename="self")] + k_self: String, + roles: Vec, + timestamp: String, +} + +pub struct SignalK { +} + +impl SignalK { + + fn parse_json (json: String) -> Vec { + let res = Vec::::new(); let v: Value = match serde_json::from_str(&json) { Ok(value) => value, Err(_) => return res, @@ -37,22 +70,43 @@ impl SignalKData { res } - pub fn connect() -> SignalKData { - let mut data = SignalKData { - latitude: f32::NAN, - longitude: f32::NAN, - position_timestamp: 0, - }; - let handle = thread::spawn(|| { + fn value_to_vesseldata (val: Value) -> Option { + match val.path.as_str() { + "navigation.position" => return Some(VesselDataEvent::Location(val.value["latitude"].as_f64().unwrap() as f32, val.value["longitude"].as_f64().unwrap() as f32)), + "navigation.headingMagnetic" => return Some(VesselDataEvent::TrueCompassCourse(val.value.as_f64().unwrap() as f32)), + "navigation.courseOverGroundTrue" => return Some(VesselDataEvent::CourseOverGround(val.value.as_f64().unwrap() as f32)), + "navigation.speedOverGround" => return Some(VesselDataEvent::SpeedOverGround(val.value.as_f64().unwrap() as f32)), + _ => return None, + } + } +} + +impl VesselDataEventSource for SignalK { + + fn connect() -> Receiver { + let (tx, rx): (Sender, Receiver) = mpsc::channel(); + let handle = thread::spawn(move || { let (mut socket, response) = connect(Url::parse("ws://localhost:3000/signalk/v1/stream?subscribe=self").unwrap()).expect("Can't connect"); + let header: SignalKHeader = serde_json::from_str(socket.read_message().unwrap().to_text().unwrap()).unwrap(); + if header.version != "1.33.0" { + warn!("SignalK parser has only been tested with Signal K Server version 1.33.0"); + } loop { - let msg = socket.read_message().expect("Error reading message"); - if msg.is_text() { - println!("{}", msg.into_text().unwrap()); + let message = socket.read_message().unwrap(); + if message.is_text() { + let data: SignalKEventData = serde_json::from_str(message.to_text().unwrap()).unwrap(); + for u in data.updates { + for v in u.values { + match SignalK::value_to_vesseldata(v) { + Some(vd) => tx.send(vd).unwrap(), + _ => (), + } + } + } } } }); - data + rx } } diff --git a/src/vesseldata.rs b/src/vesseldata.rs new file mode 100644 index 0000000..e577e57 --- /dev/null +++ b/src/vesseldata.rs @@ -0,0 +1,83 @@ +use std::fmt; +use std::thread; +use tungstenite::connect; +use url::Url; +use serde_json::{Result, Value}; +use std::sync::mpsc::Receiver; + +// Model the data sent over SignalK Websocket +// that I'm interested in +pub enum VesselDataEvent { + SpeedOverGround(f32), + SpeedThroughWater(f32), + Location(f32, f32), + CourseOverGround(f32), + WindOrigin(f32), + TrueCompassCourse(f32), + AISVessel(String, f32, f32, f32), // Name, lat, long, speed + BatteryLevel(u8, u8), // Bank#, percentage + FuelLevel(u8), // percentage +} + +pub trait VesselDataEventSource { + + fn connect() -> Receiver; +} + +impl fmt::Debug for VesselDataEvent { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + VesselDataEvent::SpeedOverGround(s) => f.debug_tuple("SpeedOverGround").field(s).finish(), + VesselDataEvent::SpeedThroughWater(s) => f.debug_tuple("SpeedThroughWater").field(s).finish(), + VesselDataEvent::Location(lat, lon) => f.debug_tuple("Location").field(lat).field(lon).finish(), + VesselDataEvent::CourseOverGround(c) => f.debug_tuple("CourseOverGround").field(c).finish(), + VesselDataEvent::TrueCompassCourse(c) => f.debug_tuple("TrueCompassCourse").field(c).finish(), + VesselDataEvent::AISVessel(name, lat, lon, speed) => f.debug_tuple("AISVessel").field(name).field(lat).field(lon).field(speed).finish(), + VesselDataEvent::BatteryLevel(bank, level) => f.debug_tuple("BatteryLevel").field(bank).field(level).finish(), + VesselDataEvent::FuelLevel(level) => f.debug_tuple("FuelLevel").field(level).finish(), + VesselDataEvent::WindOrigin(c) => f.debug_tuple("WindOrigin").field(c).finish(), + } + } +} + + + +pub struct VesselDataState { + source: Receiver, + pub latitude: f32, + pub longitude: f32, + pub speed_over_ground: f32, + pub speed_through_water: f32, + pub true_compass_course: f32, + pub course_over_ground: f32, + pub position_timestamp: u64, +} + +impl VesselDataState { + pub fn init (source: Receiver) -> VesselDataState { + VesselDataState { + source: source, + latitude: 0.0, + longitude: 0.0, + speed_over_ground: 0.0, + speed_through_water: 0.0, + true_compass_course: 0.0, + course_over_ground: 0.0, + position_timestamp: 0, + } + } + + pub fn read_events(&mut self) -> () { + for vde in self.source.try_iter() { + match vde { + VesselDataEvent::SpeedOverGround(s) => self.speed_over_ground = s, + VesselDataEvent::SpeedThroughWater(s) => self.speed_through_water = s, + VesselDataEvent::Location(lat, lon) => { self.latitude = lat; self.longitude = lon; }, + VesselDataEvent::CourseOverGround(c) => self.course_over_ground = c, + VesselDataEvent::TrueCompassCourse(c) => self.true_compass_course = c, + _ => (), + } + } + } +} +